Questo articolo finale esamina FileList, Pathmap, CLEAN, CLOBBER e passa gli argomenti. Questi non sono molto importanti per i principianti fin da subito, ma sicuramente torneranno molto utili in un secondo momento, davvero inestimabile.
Hai due opzioni per passare argomenti in attività Rake. Puoi farlo usando le variabili di Bash o facendo uso della sintassi di Rake stessa.
Se non hai mai giocato con Bash prima o Bash suona come se ti piacesse, prendiamone cinque e iniziamo dall'inizio.
Bash nella tua shell offre due tipi di variabili: variabili globali (aka ambiente) e locali. Entrambi sono scritti in maiuscolo. Le variabili di ambiente sono globali, il che significa che sono disponibili in tutte le shell e non svaniscono quando si chiudono le variabili one Bash diverse, che sono disponibili solo nella shell corrente.
Le variabili di ambiente possono contenere dati che possono essere utilizzati da più applicazioni e sono spesso usati come un modo pratico per condividere le impostazioni di configurazione. Al contrario, le variabili Bash locali sono proprio questo, locale.
Nel nostro contesto dell'uso di Rake, hai la possibilità di accedere sia tramite Ruby che in effetti passa le variabili dalla riga di comando.
Un po 'da parte, se digiti ENV
o ENV
nella tua shell, avrai accesso a tutta una serie di variabili d'ambiente. Ho redatto l'elenco, ma per una migliore comprensione di quali variabili d'ambiente sono e di cosa includono, ti incoraggio a eseguirlo per te.
ENV
TERM_PROGRAM = TERMINOLOGIA Apple_Terminal = SHELL schermo-256 SHELL = / bin / bash TMUX = / private / var / folders / 4z / 3np9k5ks62b1xpbn_w_lmrgh0000gr / T / tmux-504 / default, 4146,0 EDITOR = vim LANG = it_US.UTF-8 TMUX_PANE = % 1 is_vim = echo "# pane_current_command" | grep -iqE "(^ | \ /) g? (view | n? vim? x?) (diff)? $" ...
Se si desidera visualizzare un elenco di variabili Bash locali, è possibile eseguire impostato
.
(imposta -o posix; imposta) | Di meno
Il impostato
il comando ti dà molto più output, ma il precedente mostra i bit rilevanti subito.
Ruby offre un modo per usare l'ambiente e le variabili Bash locali allo stesso modo tramite un accettore tipo hash. Per le nostre esigenze, quando passiamo una variabile a un'attività Rake, sarà una variabile Bash locale, che puoi trovare nell'elenco di variabili in esecuzione impostato
o una variazione di esso. Ruby può leggerlo usando ENV [ 'VARIABILE']
.
rake prepare_book BOOKTITLE = "Confessioni di un unicorno"
Quello che voglio chiarire, però, è che questa variabile non verrà aggiunta alla lista ENV utilizzata dal tuo sistema, quella che hai visto chiamare ENV
dalla shell. Per aggiungerlo a quell'elenco, è necessario "esportarlo". Questa è un'altra storia, ma ho pensato di chiarirlo.
task: prepare_book do book_title = ENV ['BOOKTITLE'] || 'Working Title' mette "Fai qualcosa con il # book_title" fine
In questa definizione di attività, è possibile vedere come siamo disposti ad accettare o incorporare la variabile passata al richiamo dell'attività. ruby ENV [BASHVARIABLE]
fa tutto il sollevamento pesante. Se TITOLO DEL LIBRO
era stata una variabile di ambiente globale, tuttavia, avremmo potuto accedervi anche all'interno di questa definizione di compito con questa sintassi.
Il secondo approccio utilizza la sintassi Rake pura. È sufficiente passare le variabili in parentesi quadre. Questo approccio è migliore e puoi mantenere le cose più isolate. Perché coinvolgere Bash se Rake è perfettamente in grado di gestirlo? Inoltre non hai nessuna variabile Bash che fluttua in quel modo. Se vuoi passare più argomenti in un'attività, è anche molto più elegante.
rake "create_mi6_agent [James, Bond, 007]"
compito: create_mi6_agent, [: first_name,: last_name,: number] do | t, args | puts "Numero # args.number è il comandante # args.first_name # args.last_name." fine
Quando passi più argomenti di quelli che hai definito nel tuo compito, puoi semplicemente accedervi tramite args
. args.extras
visualizza una matrice di tutti i parametri aggiuntivi passati. args.to_a
mostra tutti i parametri, ovviamente anche in un array.
Negli esempi precedenti, abbiamo raccolto manualmente elenchi di file che necessitano di una certa trasformazione. È noioso, giusto? FileList
è una di quelle sottigliezze che rendono Rake uno strumento potente. È fin troppo facile definire un modello glob per i file necessari e averlo automaticamente aggiornato quando si aggiungono o eliminano file da quella destinazione. Con quello a nostra disposizione, le liste di filtraggio possono essere semplici o sofisticate di cui abbiamo bisogno. Le espressioni regolari sono solo la punta dell'iceberg, anche se molto utile, ovviamente.
La necessità di elenchi di file da elaborare è molto comune per gli strumenti di compilazione e rendere più facile gestirli è uno dei punti di forza di Rake. FileList rende Rakefile più piccolo, più intelligente e in grado di gestire un numero arbitrario di file che non è necessario gestire. Puoi lasciare Rake in carica.
Allora, cos'è una FileList esattamente? Pensala come una serie di file che corrispondono al modello dato. È una Ruby Array specializzata che si concentra sull'elaborazione di elenchi di file, memorizzandoli come stringhe. Una volta raccolti, sono pronti per l'iterazione e per applicare le trasformazioni.
image_list = FileList ['images / *. png'] => ["images / jim-weirich.png", "images / zen-rake.png"]
Gestire questi file a mano è un modo sicuro per costruire sulla sabbia. E, naturalmente, Rake controlla i timestamp di questo elenco e ricostruisce solo i file che non sono aggiornati. Un FileList è anche pigro. Non prende i file finché non sono necessari. Se hai un sacco di elenchi di file, si comportano molto bene e in modo intelligente per questo. Gli elenchi che non vengono utilizzati attivamente si stanno prendendo facilmente senza colpire il file system. È più efficiente in questo modo.
Come puoi vedere di seguito, puoi anche fornire più modelli glob per l'elenco.
image_list = FileList ['images / *. png', 'images / *. jpg'] => ["images / happy-jim.jpg", "images / jim-weirich.png", "images / zen-rake. png "]
Con un ampio set di file, le esclusioni diventano molto utili, ad esempio, se vogliamo filtrare i file temporanei, eseguire il backup di file da editor, file Git o determinate directory non necessarie. In breve, le regole di esclusione sono per i file che non vuoi nella tua build.
articles = Rake :: FileList.new ('_ posts / ** / *. markdown, md') do | file | files.exclude ('/ _ post / bozze / *. markdown, md') end => ["_posts / published / 2016 / 2016-02-02-some-article.md", "_posts / published / 2015 / 2015/12/12-another-article.markdown "]
Possiamo passare i file di FileList attraverso il suo inizializzatore, che accetta un elenco di maschere di file. Elaborate eventuali esclusioni all'interno del blocco. Abbiamo semplificato l'elenco delle estensioni di file desiderate tramite markdown, md
per mantenere le cose ASCIUTTE. Inoltre, è possibile collegare queste esclusioni quanto necessario. Qui potremmo anche controllare se i file inclusi nella FileList sono vuoti (zero?
) ed escludono questi dalla matrice in questo modo.
articles = Rake :: FileList.new ('_ posts / ** / *. md') do | files | files.exclude ('/ _ post / bozze / *. markdown, md') files.exclude ('_ posts / ~ *') files.exclude do | file | File.zero?(file) end end
Fondamentalmente stiamo fornendo più modelli glob per raccogliere solo i file necessari in FileList. Per qualsiasi motivo, puoi anche andare nella direzione opposta e includere file in una FileList.
FL = FileList ['images / *. Png'] FL.include ('images / private / *. Jpg)
È l'arma segreta di Rake e mostra il suo vero potere consentendoti di manipolare i percorsi dei file. Può essere richiamato su un elenco di file tramite FileList o anche su singoli file. Non dimenticare che funziona su stringhe, però. Fa parte di un'estensione di Ruby Stringa
classe.
Giochiamo con un semplice file e cambia una semplice estensione. Potremmo farlo con il pratico ext
metodo, ovviamente.
"/mi6/q/secret_gadgets.xml".ext("html") # => '/mi6/q/secret_gadgets.html'
Il ext
metodo ci consente di sostituire un'estensione di file piuttosto facilmente. Vediamo cosa possiamo fare con questo file quando giochiamo pathmap
, anche se. Penso che sia il modo migliore per mostrarti cosa ha in serbo per te. Possiamo ottenere la stessa cosa come questa.
"/mi6/q/secret_gadgets.xml".pathmap('%X.html ') # =>' /mi6/q/secret_gadgets.html '
Come puoi vedere, questo è un po 'più elegante. Noi forniamo pathmap
con una specifica di ciò che ci serve da quella stringa tramite %
.
%X
Usando questo, otteniamo tutto tranne l'estensione del file. Quindi aggiungiamo semplicemente l'estensione di cui abbiamo bisogno. Questo è solo grattando la superficie, però. pathmap
ha molti indicatori utili che ti consentono di essere più creativo. Le manipolazioni del percorso file non potrebbero essere più semplici con questo.
% p
Se hai bisogno del percorso completo.
"/mi6/q/secret_gadgets.xml".pathmap('%p ') # =>" mi6 / q / secret_gadgets.xml "
% f
Se hai solo bisogno del nome di un determinato percorso. Nessuna directory ma con l'estensione del file.
"/mi6/q/secret_gadgets.xml".pathmap('%f ') # =>" secret_gadgets.xml "
% n
Se è necessario il nome del file di un determinato percorso senza la sua estensione di file.
"/mi6/q/secret_gadgets.xml".pathmap('%n ') # =>" secret_gadgets "
% d
Se hai bisogno solo dell'elenco di directory di un determinato percorso.
"/mi6/q/secret_gadgets.xml".pathmap('%d ') # =>" mi6 / q "
%X
Estrae solo l'estensione del file.
"/mi6/q/secret_gadgets.xml".pathmap('%x ') # =>" .xml "
%S
Mostra solo il separatore di file.
"/mi6/q/secret_gadgets.xml".pathmap('%s ') # =>" / "
ND%
Se si desidera specificare un numero specifico di directory che è necessario. Comodo per strutture di file profondamente annidate.
"/mi6/q/secret_gadgets.xml".pathmap('%1d ') # =>" mi6 "
"/mi6/q/secret_gadgets.xml".pathmap('%2d ') # =>" mi6 / q "
Puoi anche affrontarlo nell'ordine inverso usando un segno meno.
"/mi6/q/secret_gadgets.xml".pathmap('%-2d ') # =>" mi6 / q "
"/mi6/q/secret_gadgets.xml".pathmap('%-1d ') # =>" q "
Come puoi vedere, questo piccolo metodo affronta tutte le varie esigenze che puoi avere con la mappatura di un elenco di file in un diverso elenco di file. Collegalo a una FileList e la magia si innesca. È davvero uno strumento potente per i nomi di file munging.
images = FileList ['images / *. png'] thumbs = images.pathmap ('thumbs /% n-thumbs% x')
Qui, ad esempio, stiamo prendendo un elenco di immagini e mappandole a nuovi nomi di file estraendo i nomi dei file e aggiungendo un -pollici
suffisso più l'estensione del file estratto mentre li inserisci in a pollici
directory. Sono sicuro che troverai un ottimo uso per pathmap
.
Vogliamo essere in grado di restituire un progetto a uno stato incontaminato. Del resto, un FileList non è utile solo per preparare i file che devono essere trasformati, ma semplifica anche la raccolta dei file che si desidera vengano puliti dopo aver terminato le attività. CLEAN e CLOBBER sono in realtà anche FileList: hanno solo due compiti molto specifici da gestire: la cancellazione.
richiede 'rake / clean' CLEAN.include ('*. intermediate_files') CLOBBER.include ('*. intermediate_files', 'built_files / *')
Questi due compiti sono stupidi, ovviamente, e devi dar loro da mangiare elenchi di file tramite il nostro comodo includere
. Quando corri pulire bene
o rastrellare il clobber
, questi file raccolti spariranno. Poiché questo è un modulo opzionale, è necessario richiederlo prima nel tuo Rakefile. La cosa bella di CLEAN e CLOBBER è che ti danno un posto centrale per gestire la pulizia dei tuoi file di costruzione. Certo, potresti scrivere manualmente le attività di Rake per gestirlo, ma sia CLEAN che CLOBBER lo risolvono senza reinventare la ruota.
Non stiamo mettendo tutto in un compito pulito perché è comodo che tu possa distinguere tra file intermedi e file di costruzione. Supponiamo di dover creare file HTML per creare versioni PDF definitive dei nostri file Markdown. Includeremmo i file HTML nel nostro PULITO
elenco. Sia il .html
e il finale .PDF
i file andrebbero in clobber
. Concettualmente, la lista CLOBBER dovrebbe rimuovere tutto in entrambi gli elenchi.
Perché ci preoccupiamo di questi file di costruzione? A volte vuoi ricostruire tutto e cancellare vecchi file per ottenere una nuova build. Pertanto è necessario un modo per eliminare tutti i file che sono stati generati mantenendo i file di origine necessari per la compilazione, più spesso i file sottoposti a controllo di versione. È facile che queste liste non siano aggiornate quando si risolve manualmente. Pertanto, gestirli come il nostro buon vecchio amico FileList rende questo processo molto più efficace.
Rake, nella sua essenza, è per la gestione delle attività, ovviamente. Scomponali fino ai loro componenti più utili e costruiscili per creare compiti più grandi. Pensa OOP! Lo stesso vale per i tuoi file. Rails rende questo molto facile per te via compiti / lib
. In altri progetti, è possibile creare una directory chiamata rakelib
e costruisci i tuoi componenti Rake lì. Rake carica il Rakefile e rakelib / *. rastrello
file automaticamente.
rake --dry-run
Se è necessario eseguire un'attività potenzialmente distruttiva in un certo senso e si preferisce controllare prima quale operazione svolgerebbe, è possibile eseguire l'ordinamento in modalità sandbox. Vedrai il registro di ciò che sta facendo senza le operazioni sui file.
Keep it simple! Rake è intelligente nel fare la minima quantità possibile. Quindi dovresti essere. La cosa bella di Rake è che fornisce un ottimo DSL senza darti molta corda per farti del male reinventando la ruota inutilmente.
I namespace sono economici e ti impediscono di imbattersi in nomi di attività in conflitto. Questo è particolarmente importante se si dispone di Rakefiles provenienti da fonti diverse e da più sviluppatori.
compito: fight_bad_dude do ... end namespace: bond do task: fight_bad_dude ... end end
Utilizza FileUtils e mantieniti lontano dalle manipolazioni dei file shell all'interno delle tue attività. È un po 'sporco quando Rake li rende già disponibili per te.
Puoi eseguire i file Ruby nei file Rake. Questo potrebbe tornare utile ogni tanto.
compito: some_task do ruby 'ruby_program.rb' fine
Usa le regole se hai molti file invece di attività generate dinamicamente. Perché? Correre rastrello -P
e otterrai una lista di tutti loro. Questo può sfuggire di mano molto, molto velocemente. Oltre a questo, non usare le regole spesso manca semplicemente di eleganza. Potresti non aver ridotto il modello al suo nucleo ancora. Soprattutto, ciò renderà più facile il riutilizzo pur essendo ASCIUTTO, ovviamente.
Invece di definire autonomamente le raccolte per i file, e anche l'aggiornamento di questa lista, lasciamo che sia Rake a occuparsene. Come abbiamo visto, la raccolta di file per le tue attività non è affatto complicata in Rake.
Usa i metodi di Ruby per cose più complesse. Estrai i metodi per il riutilizzo ovunque tu sia possibile. Solo perché stiamo scrivendo il codice nei file Rake, non dovrebbe impedirci di incapsulare correttamente e OOP.
rake -T secret_service_agent
Questo, ad esempio, cercherà le attività rake con "secret_service_agent" al loro interno. Corrisponde al nome dell'attività ma non alla descrizione.
rake -W create_mi6_agent
Questo ci mostra dove è il compito create_mi6_agent
è definito.
Rake è un potente motore di gestione e esecuzione delle attività. Software open source al suo meglio, se me lo chiedi. All'inizio, sono stato davvero sorpreso di sapere quanti download ha accumulato negli ultimi due anni. Che questo piccolo strumento di costruzione sia la gemma più popolare fino ad oggi e che abbia oltre 100 milioni di download sembra pazzesco.
Ma quando guardi più a fondo ciò che ha da offrire, diventa subito chiaro in un batter d'occhio che cosa fosse veramente un produttore di software Jim Weirich: un vero eroe di Ruby che tutti dovremmo ammirare per il suo lavoro, il suo retaggio e la sua passione. Ti lascio con una bella video intervista in cui Jim parla di Rake. Ci sono tantissimi altri video dei suoi discorsi disponibili online. Vai a guardarli tutti!