Come si crea un generatore che modifica un file.Modificare un file con un generatore di rotaie
Sto cercando di farlo in modo che trovi uno schema in un file e aggiunge il contenuto alla linea sottostante. generatore di scaffold
Come si crea un generatore che modifica un file.Modificare un file con un generatore di rotaie
Sto cercando di farlo in modo che trovi uno schema in un file e aggiunge il contenuto alla linea sottostante. generatore di scaffold
Rails' fa questo quando si aggiunge un percorso per config/routes.rb
Lo fa chiamando un metodo molto semplice:
def gsub_file(relative_destination, regexp, *args, &block)
path = destination_path(relative_destination)
content = File.read(path).gsub(regexp, *args, &block)
File.open(path, 'wb') { |file| file.write(content) }
end
quello che sta facendo sta prendendo un percorso/file come primo argomento, seguito da un pattern regexp, argomenti gsub e il blocco. Questo è un metodo protetto che dovrai ricreare per poterlo utilizzare. Non sono sicuro che l'destination_path
sia qualcosa a cui avrai accesso, quindi probabilmente vorrai passare il percorso esatto e saltare qualsiasi conversione.
Per utilizzare gsub_file
, supponiamo di voler aggiungere tag al modello utente. Ecco come si dovrebbe fare:
line = "class User < ActiveRecord::Base"
gsub_file 'app/models/user.rb', /(#{Regexp.escape(line)})/mi do |match|
"#{match}\n has_many :tags\n"
end
si sta trovando la linea specifica nel file, la gara di apertura della classe, e aggiungendo la linea has_many
proprio sotto.
Attenzione però, perché questo è il modo più fragile per aggiungere contenuto, motivo per cui il routing è uno dei pochi luoghi che lo utilizza. L'esempio sopra sarebbe normalmente gestito con un mix-in.
Mi piace la risposta di Jaime. Ma, quando ho iniziato a utilizzarlo, ho capito che avevo bisogno di apportare alcune modifiche. Ecco il codice di esempio che sto usando:
private
def destination_path(path)
File.join(destination_root, path)
end
def sub_file(relative_file, search_text, replace_text)
path = destination_path(relative_file)
file_content = File.read(path)
unless file_content.include? replace_text
content = file_content.sub(/(#{Regexp.escape(search_text)})/mi, replace_text)
File.open(path, 'wb') { |file| file.write(content) }
end
end
In primo luogo, gsub
sostituirà tutte le istanze del testo di ricerca; Ne ho solo bisogno. Quindi ho usato invece sub
.
Successivamente, avevo bisogno di controllare se la stringa di sostituzione era già a posto. Altrimenti, ripeterei l'inserimento se il mio generatore di binari fosse stato eseguito più volte. Così ho avvolto il codice in un blocco unless
.
Infine, ho aggiunto il def destination_path()
per voi.
Ora, come utilizzeresti un generatore di rotaie? Ecco un esempio di come mi assicuro simplecov è installata per RSpec e cetriolo:
def configure_simplecov
code = "#Simple Coverage\nrequire 'simplecov'\nSimpleCov.start"
sub_file 'spec/spec_helper.rb', search = "ENV[\"RAILS_ENV\"] ||= 'test'", "#{search}\n\n#{code}\n"
sub_file 'features/support/env.rb', search = "require 'cucumber/rails'", "#{search}\n\n#{code}\n"
end
C'è probabilmente un modo più elegante e DRY-er per fare questo. Mi è davvero piaciuto come puoi aggiungere un blocco di testo all'esempio di Jamie. Spero che il mio esempio aggiunga un po 'più di funzionalità e controllo degli errori.