2017-02-07 7 views
1

Ich mag wäre in der Lage sein, in Python wie mit der PyYAML Bibliothek eine YAML jinja Konfigurationsdatei zu lesen, aber ich bin Empfangsfehler:yaml und jinja2 Leser

{% set name = "abawaca" %} 
{% set version = "1.00" %} 

package: 
    name: {{ name }} 
    version: {{ version }} 

source: 
    fn: {{ name }}-{{ version }}.tar.gz 
    url: https://github.com/CK7/abawaca/archive/v{{ version }}.tar.gz 
    sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529 

build: 
    number: 0 

requirements: 
    build: 
     - gcc # [not osx] 
     - llvm # [osx] 
+1

Ich habe meine Antwort mit einem vollständigen Arbeitsbeispiel aktualisiert. Tut mir leid, es hat so lange gedauert, bis ich darauf zurückkam. – Anthon

Antwort

1

Ihre Eingabe ist nicht gültig YAML, wie Sie kann leicht überprüfen, z here Sie sollten zuerst die Konstrukte erweitern und dann die YAML verarbeiten, oder Sie sollten Ihre Datei in gültige YAML machen.

Dies ist eine Folge der Auswahl von jinja2, für die die Makrosequenzen {% ... %} mit einem Zeichen ({) beginnen, das in YAML eine besondere Bedeutung hat.

Wenn Sie die YAML ändern und erneut schreiben müssen, können Sie eigene Begrenzer definieren und sie so auswählen, dass sie in YAML keine besondere Bedeutung haben.

Die {% %} Sie sollten einen YAML-Kommentarblock einfügen, da auf der obersten Ebene Sie eine Zuordnung haben und nur Schlüssel-Wert-Paare haben sollten. Eine Möglichkeit, dies zu erreichen, besteht darin, den Start als #% %# neu zu definieren (Sie müssen nicht unbedingt das Ende ändern, aber ich bevorzuge die Symmetrie).

Dann nach der Aktualisierung, führen Sie die richtige YAML durch ein kleines Skript, das die Datei verarbeitet und ersetzt die Trennzeichen zu denen, die jinja2 versteht, oder zwicken die Umgebung, um die tatsächlichen Definitionen von jinja2 zu ändern.

korrigiert data.yaml:

import jinja2 
from ruamel import yaml 

yaml_file = 'data.yaml' 
tmp_file = 'tmp.yaml' 

data = yaml.round_trip_load(open(yaml_file)) 
data['package']['version'] = '<{ version }>' 
with open(tmp_file, 'w') as fp: 
    yaml.round_trip_dump(data, fp) 

environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(searchpath='.'), 
    trim_blocks=True, 
    block_start_string='#%', block_end_string='%#', 
    variable_start_string='<{', variable_end_string='}>') 

    print(environment.get_template(tmp_file).render()) 

geben:

#% set name = "abawaca" %# 
#% set version = "1.00" %# 

package: 
    name: <{ name }> 
    version: 42 

source: 
    fn: <{ name }>-<{ version }>.tar.gz 
    url: https://github.com/CK7/abawaca/archive/v<{ version }>.tar.gz 
    sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529 

build: 
    number: 0 

requirements: 
    build: 
     - gcc # [not osx] 
     - llvm # [osx] 

Dies kann durch verarbeitet werden

package: 
    name: abawaca 
    version: 1.00 

source: 
    fn: abawaca-1.00.tar.gz 
    url: https://github.com/CK7/abawaca/archive/v1.00.tar.gz 
    sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529 

build: 
    number: 0 

requirements: 
    build: 
    - gcc  # [not osx] 
    - llvm  # [osx] 

Bitte beachten Sie, dass Sie `ruamel.yaml (Haftungsausschluss verwenden : Ich bin der Autor dieses Pakets), Sie können dies nicht so einfach mit PyYAML tun, da es die Kommunikation wegwirft beim Lesen der YAML-Datei. Da alle jinja2 in Kommentaren am Anfang der Datei vorkommen, können Sie dies mit diesem speziellen Beispiel umgehen, aber das wird im Allgemeinen nicht der Fall sein.

+0

Dank @anthon aber wissen Sie, wie programmatisch erweitern Sie die Yaml und lesen Sie das Ergebnis mit Yaml. – ypriverol

+0

Sie können die Konstrukte erweitern, indem Sie sie über jinja2 lesen. Sie erhalten eine Datei und lesen diese Datei mit Ihrem Parser. – Anthon

+0

hast du ein Beispiel (Code-Schnipsel) Ich habe es vorher versucht und nicht funktioniert. – ypriverol