2012-07-31 13 views
10

In base a http://yaml.org/spec/current.html#id2509980 i commenti nei file YAML sono un dettaglio di presentazione e non devono essere nel grafico di serializzazione/rappresentazione (http://yaml.org/spec/current.html#representation/). Sembra che Psych stia analizzando in base alle specifiche e perde i commenti, il che significa che non è possibile analizzare un file YAML e serializzarlo di nuovo esattamente allo stesso modo quando il file contiene commenti. Quale a mio parere è molto strano perché i commenti sono importanti in tale file (ad esempio configs).Parsing YAML psicologico con commenti

Qualcuno sa se è possibile analizzare i commenti con una libreria esistente o è l'unico modo per andare a fare tutto da solo?

+1

E 'un tratto, ma si potrebbe clonare in un file temporaneo prima di caricarla nel e quindi unire i due file dopo la serializzazione (utilizzando diff?) ... fino a quando la struttura complessiva era lo stesso .. o ... è una specie di pazza idea ...? –

+0

[Questo post del blog] (https://kev.inburke.com/kevin/more-comment-preserving-configuration-parsers/) suggerisce l'unico commento: il parser YAML è ruamel, che è per Python. –

risposta

0

È possibile scorrere i nodi su un livello inferiore mantenendo i commenti durante l'emissione. Inoltre, puoi vedere se il motore di ricerca ti dà il risultato che stai cercando.

+0

correlati http://stackoverflow.com/questions/16390330/how-do-i-update-rails-locale-yaml-file-without-loosing-comments-and-variables –

+0

correlati http://stackoverflow.com/questions/14149570/can-rubys-yaml-modulo-essere-usato-per-incorporare-comments –

0

Mi è piaciuta l'idea pazzesca di josh-voigts. Ecco un'implementazione pazzesca. I commenti possono essere sparpagliati quasi ovunque e funziona!

def yaml_conf_edit(fn, &block) 
    conf = File.open(fn) {|f| YAML.load(f.read)} 

    before = Tempfile.new('before') 
    before.write(conf.to_yaml) 
    before.close 

    yield conf 

    after = Tempfile.new('after') 
    after.write(conf.to_yaml) 
    after.close 

    `merge #{fn} #{before.path} #{after.path}` 
    before.unlink; after.unlink 

    conf 
end 

che è possibile utilizzare in qualcosa di simile:

yaml_conf_edit('conf/database.yml') do |conf| 
    conf['development']['database'] = db_timestamped 
end 
1

Possiamo fare qualche cosa di simile anche, che avrebbe cambiato il valore della chiave e anche mantenere i commenti.

require 'yaml' 
thing = YAML.load_file('/opt/database.yml') 
hostname = thing["common"]["host_name"] 
appname = thing["common"]["app_name"] 
motdobj = IO.readlines('/opt/database.yml') 
motdobj = motdobj.map {|s| s.gsub(hostname, "mrigesh")} 
motdobj = motdobj.map {|s| s.gsub(appname, "abc")} 

File.open('/opt/database.yml', "w") do | file1 | 
    file1.puts motdobj 
    file1.close 
end