2012-07-31 19 views
10

Según http://yaml.org/spec/current.html#id2509980 los comentarios en archivos YAML son un detalle de presentación y no deben estar en el gráfico de serialización/representación (http://yaml.org/spec/current.html#representation/). Parece que Psych está analizando según las especificaciones y pierde los comentarios, lo que significa que no es posible analizar un archivo YAML y volver a serializarlo exactamente de la misma manera cuando el archivo contiene comentarios. Que en mi opinión es muy extraño porque los comentarios importan en dicho archivo (por ejemplo, configs).Analizando Psych YAML incluyendo comentarios

¿Alguien sabe si es posible analizar comentarios con una biblioteca existente o es la única forma de hacerlo solo?

+1

Es un tramo, pero se puede clonar en un archivo temporal antes de cargarlo en y luego fusionar los dos archivos después de serialización (usando diferencia?) ... siempre y cuando la estructura general fue la misma .. ¿o ... es esa una especie de idea loca ...? –

+0

[Esta publicación de blog] (https://kev.inburke.com/kevin/more-comment-preserving-configuration-parsers/) sugiere que el único analizador de YAML que preserva los comentarios es ruamel, que es para Python. –

Respuesta

0

Puede iterar sobre los nodos en un nivel inferior manteniendo los comentarios al emitir. Además, podría ver si el motor de sincronización le da el resultado que está buscando.

+0

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

+0

Relacionados http://stackoverflow.com/questions/14149570/can-rubys-yaml-module-be-used-to-embed-comments –

0

Me gustó @ josh-voigts crazy idea. Aquí hay una implementación loca. Los comentarios se pueden intercalar casi en cualquier parte y ¡funciona!

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 

que se puede utilizar en algo así como:

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

Podemos hacer algo como esto también, que cambiaría el valor de la clave y también mantener los comentarios.

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