Uruchamianie polecenia w zadaniu Grunt

94

W moim projekcie używam Grunt (narzędzie do tworzenia wiersza poleceń oparte na zadaniach dla projektów JavaScript). Utworzyłem niestandardowy tag i zastanawiam się, czy można uruchomić na nim polecenie.

Aby wyjaśnić, próbuję użyć szablonów zamknięcia i „zadanie” powinno wywołać plik jar, aby wstępnie skompilować plik Soy do pliku javascript.

Uruchamiam ten jar z wiersza poleceń, ale chcę ustawić go jako zadanie.

JuanO
źródło

Odpowiedzi:

105

Alternatywnie możesz załadować wtyczki gruntowe, aby pomóc:

przykład powłoki gruntowej:

shell: {
  make_directory: {
    command: 'mkdir test'
  }
}

lub przykład grunt-exec :

exec: {
  remove_logs: {
    command: 'rm -f *.log'
  },
  list_files: {
    command: 'ls -l **',
    stdout: true
  },
  echo_grunt_version: {
    command: function(grunt) { return 'echo ' + grunt.version; },
    stdout: true
  }
}
papercowboy
źródło
9
Czy ktoś wie, czy którykolwiek z tych dwóch jest użyteczny w systemie Windows?
Capaj
Nie mogłem od razu zabrać się grunt-shelldo pracy z Windows + Cygwin, ale miałem więcej szczęścia grunt-exec.
Nathan,
3
Czy istnieje sposób synchronicznego używania grunt-exec? Fajnie byłoby połączyć polecenia w łańcuch
funseiki
1
@funseiki po prostu umieść polecenia w pakiecie lub powłoce, która wywołuje polecenia w preferowanej kolejności. Lub definiujesz zadanie np. Mycmds i piszesz "exec:cmd1", "exec:cmd2"wtedy też masz synchroniczne zamówienie.
Sebastian,
35

Sprawdź grunt.util.spawn:

grunt.util.spawn({
  cmd: 'rm',
  args: ['-rf', '/tmp'],
}, function done() {
  grunt.log.ok('/tmp deleted');
});
Nick Heiner
źródło
5
z opts: {stdio: 'inherit'},można zobaczyć wynik polecenia
JuanPablo
2
Uwaga: parametr cmd powinien być łańcuchem, a nie tablicą.
RKI
1
To teraz wymaga grunt-legacy-utilwtyczki. Zaleca użycie require('child_process').spawn()zamiast tego.
JD,
19

Znalazłem rozwiązanie, więc chcę się z Tobą podzielić.

Używam grunt pod węzłem, więc aby wywołać polecenia terminala, musisz wymagać modułu „child_process”.

Na przykład,

var myTerminal = require("child_process").exec,
    commandToBeExecuted = "sh myCommand.sh";

myTerminal(commandToBeExecuted, function(error, stdout, stderr) {
    if (!error) {
         //do something
    }
});
JuanO
źródło
12
Lepszym podejściem jest użycie wtyczki (lub napisanie własnej), aby zachować konfigurację gruntową jako konfigurację, a nie kod. grunt-shell i grunt-exec to dwa przykłady.
papercowboy,
Jak używasz shwcześniej, sh mayCommand.sh nie jestem pewien, czy będzie działać w
systemie
To nie zadziała, ponieważ jest to skrypty bash. Pracuję pod systemem Unix
JuanO,
18

Jeśli używasz najnowszej wersji gruntowej (0.4.0rc7 w chwili pisania tego tekstu), zarówno grunt-exec, jak i grunt-shell zawodzą (nie wydaje się, aby zostały zaktualizowane, aby obsługiwać najnowszy grunt). Z drugiej strony, exec child_process jest async, co jest kłopotliwe.

Skończyło się na tym , że użyłem rozwiązania Jake'a Trenta i dodałem shelljs jako zależność deweloperską do mojego projektu, więc mogłem po prostu łatwo i synchronicznie wykonywać testy:

var shell = require('shelljs');

...

grunt.registerTask('jquery', "download jquery bundle", function() {
  shell.exec('wget http://jqueryui.com/download/jquery-ui-1.7.3.custom.zip');
});
kikito
źródło
1
fyi grunt-shelldziała dobrze grunt v0.4.5pod Windows
fiat
Myślę, że używanie shelljs jest świetnym rozwiązaniem, ponieważ umożliwia aplikacji node dostęp do powłoki i daje lepszą kontrolę nad nią niż same dodatki gruntowe.
Nick Steele
14

Faceci wskazują child_process, ale spróbuj użyć execSync, aby zobaczyć wyjście.

grunt.registerTask('test', '', function () {
        var exec = require('child_process').execSync;
        var result = exec("phpunit -c phpunit.xml", { encoding: 'utf8' });
        grunt.log.writeln(result);
});
Artjom Kurapov
źródło
Świetne rozwiązanie bez żadnych dodatkowych wtyczek.
valentinvieriu
Próbowałem uruchomić uruchomione zadania przez jeden dzień i wreszcie proste rozwiązanie, które działa!
johnny 5