2013-04-19 5 views
10

Ich schreibe eine Gradle-Build-Datei, die eine grundlegende Entwicklungsdomäne für unser Produkt installieren wird. Im Wesentlichen wird der gesamte echte Code in benutzerdefinierten Plugins und benutzerdefinierten Tasks enthalten sein. Einige der Schritte sind ziemlich repetitiv (mehrere sudo-Aufrufe, mehrere Benutzer hinzufügen) und ich möchte die gemeinsamen Sachen in eine Aufgabe kapseln.Was ist die am besten geeignete Methode, die Exec-Task in Großbuchstaben für allgemeine Befehlszeilenoperationen wiederzuverwenden?

Zum Beispiel:

task('addDBUser', type:AddUser) { 
    username = joeUser 
} 

task('startService', type:SudoExec) { 
    workingDir = "not/too/relevant" 
    commandLine = "/etc/init.d/coolService start" 
} 

Ich mag würde die verschiedenen Funktionen wieder zu verwenden, die Exec mir bekommt (stdin, stdout, etc.) als tidily wie möglich, während die vorformulierten Versorgung ("sudo ... ") automatisch. Ich bin mir ziemlich sicher, dass ich Exec anstelle von DefaultTask erweitern kann, aber ich kenne keine Standardmethode, um eine tatsächliche Aktion auszulösen. Es scheint einfach zu sein, die Eigenschaft commandLine mit dem zu modifizieren, was ich brauche, aber es gibt kein generisches "run()" oder ähnliches, das ich verwenden kann, wenn ich möchte, dass Exec tatsächlich läuft.

Ich öffne Exec, um festzustellen, welche Methode es ist Arbeitsmethode und dann direkt aufrufen? Oder gibt es einen allgemeineren Weg, um mein Ziel zu erreichen?

+1

Irgendwelche Gründe für den Downvote? Ich kann keine besseren Fragen schreiben, wenn ich nicht weiß, was los ist. –

+0

Ich stimme Josh zu. Ich hasse es auch, wenn jemand ohne Grund einen Countdown gibt. Ich denke, dass das Beste sein wird, wenn ein Kommentar für den Downvote benötigt wird. – pepuch

Antwort

10

Um zu sehen, welche Methode für eine Aufgabe ausgeführt wird, können Sie die Quellen von Exec überprüfen und nach einer Methode suchen, die mit @TaskAction markiert ist. Es stellt sich heraus, dass es die exec()-Methode ist, aber im Allgemeinen möchten Sie Task-Aktionen nicht manuell aufrufen, aber Gradle tut es für Sie. Die beste Idee ist meiner Meinung nach, Methoden/Setter Ihren benutzerdefinierten Aufgaben hinzuzufügen. Es könnte so aussehen:

task addUser(type: AddUser) { 
    username = 'fromGradle' 
} 


class SudoExec extends Exec { 

    void sudoCommand(Object... arguments) { 
     executable 'sudo' 
     args = arguments.toList() 
    } 
} 

class AddUser extends SudoExec { 

    void setUsername(String username) { 
     sudoCommand('useradd', username) 
    } 
} 
+0

Ah, und ich brauche nicht zu wissen, welche Methode der Exec-Befehl verwendet, weil diese Methode und ihre Annotation @TaskAction beide geerbt werden. Solange ich die erwarteten Werte modifiziere, wird Gradle die Punkte für mich verbinden. Als ich diese Frage schrieb, hatte ich das Gefühl, dass es etwas relativ Einfaches an OO sein würde, dass ich einfach nicht klicken konnte. (Es war eine lange Woche hier im Großraum Boston.) Danke, dass Sie geduldig sind! –

+0

Sie haben recht damit, dass Sie nicht die Interna von 'Exec' und Gradle kennen müssen, die die Punkte für Sie verbinden. Kein Problem und viel Glück! – erdi

+0

Dies ist eine schlechte Lösung, weil es Ihre Einkapselung bricht. Im Allgemeinen möchten Sie Ihre Benutzer nicht wissen lassen, dass diese Aufgabe nur eine grundlegende Exec-Aufgabe ist und noch mehr - Sie möchten nicht, dass sie sich mit ihren Parametern wie ausführbaren Dateien oder Argumenten herumschlagen, die mit Vererbung verfügbar gemacht werden. – dant3

1

Dieser Code der Lage ist, mehrere Parameter zu handhaben, da es nicht in Etter aller spezifischen Parameter nicht Haken, verwendet aber faul GString Auswertung.

task vagrantfile (type:Vagrantfile) { 
    account 'vagrant' 
    password 'vagrant' 
} 

class Vagrantfile extends Copy { 
    String account 
    String password 

    def Vagrantfile() { 
     from 'templates/' 
     into 'build/' 
     include 'Vagrantfile.ubuntu.tpl' 
     rename {'Vagrantfile'} 
     expand (account:"${->account}", password:"${->password}") 
    } 
} 
Verwandte Themen