2016-03-17 74 views
1

我將使用代表性示例解釋我的問題。使用其他文件的內容預處理(填充,生成)文件

比方說,我有這2個配置文件:

# product-conf.file 
seo_title: general_title 
seo_description: seo_description 
seo_canonical: seo_canonical 

product_id: general_id 
title: general_title 
intro: general_intro 

# service-conf.file 
seo_title: general_title 
seo_description: seo_description 
seo_canonical: seo_canonical 

service_id: general_id 
title: general_title 
products: list_products 

正如您所看到的,3個第一行(配置字段)完全相同。我實際上使用YAML來處理這些文件。我想在可維護的文件中包含代碼片段並將它們包含在調用中。我需要這些預處理器。例如:

# snippet-seo.file 
seo_title: general_title 
seo_description: seo_description 
seo_canonical: seo_canonical 

# product-conf-master.file 

@include snippet-seo 

product_id: general_id 
title: general_title 
intro: general_intro 

# service-conf-master.file 

@include snippet-seo 

service_id: general_id 
title: general_title 
products: list_products 

預處理程序將讀取/masters/*所有的主文件,參加所有的通話和/snippets/代他們合適的片段,並保存結果在/

我做的調用與@但我可以選擇其他適合於所選預處理器的格式。我用這種方式,因爲它非常類似於SASS指令@extend@include

我可以實現這一目標的最佳和最簡單的方法是什麼?節點包將是我的第一選擇。

+0

你有沒有想過使用合併密鑰工具將文件組合成一個組合YAML文件來定義公共部分,並直接使用它(區分在頂層名稱上使用什麼)或從這個組合中寫出不同的YAML文件? – Anthon

+0

是的,這可能有幫助。隨着你的輸入,我現在已經能夠找到更多關於這方面的信息(http://yaml.org/type/merge.html) 但是,我仍然不知道用什麼來預處理(合併)這些文件。這些文件的使用者需要處理的文件。與瀏覽器需要CSS相同的方式,不是SASS。 –

+0

對於預處理,您需要使用一些通用模板。但是,如果您使用合併密鑰和單個源YAML,則可以使用幾行Python代碼輕鬆分割該源。 – Anthon

回答

0

如果你不一定需要預處理文件,你可以用一個小的YAML處理程序來解決這個問題(你可以使用一些基於節點的編程來完成)。

import ruamel.yaml 

data = ruamel.yaml.round_trip_load(open('master.file')) 

common = data['common'] 
for file_name in data: 
    if file_name == 'common': 
     continue 
    data_out = ruamel.yaml.comments.CommentedMap() 
    # you can leave out the following two lines of code if you do a safe_load() 
    # but you will lose the ordering in your output file 
    for k, v in common.items(): 
     data_out[k] = v 
    for k, v in data[file_name].items(): 
     data_out[k] = v 
    with open(file_name, 'w') as fp: 
     ruamel.yaml.round_trip_dump(data_out, stream=fp) 

考慮下面的輸入文件master.file

# YAML master file 
common: &COMMON 
    seo_title: general_title 
    seo_description: seo_description 
    seo_canonical: seo_canonical 

product-conf.file: 
    <<: *COMMON 
    product_id: general_id 
    title: general_title 
    intro: general_intro 

service-conf.file: 
    <<: *COMMON 
    service_id: general_id 
    title: general_title 
    products: list_products 

運行程序爲您提供了兩個文件,product-conf.file ::

seo_title: general_title 
seo_description: seo_description 
seo_canonical: seo_canonical 
product_id: general_id 
title: general_title 
intro: general_intro 

service-conf.file

seo_title: general_title 
seo_description: seo_description 
seo_canonical: seo_canonical 
service_id: general_id 
title: general_title 
products: list_products 

也可以將三個部分放在單獨的輸入文件中,而不是組合文件中的值。


或者,如果不打算你的真實輸入文件,包括任何以特殊的方式通過cpp處理,你可以這樣做:

cpp -P -include master.in -o service-conf.file service-conf.in 

master.in

seo_title: general_title 
seo_description: seo_description 
seo_canonical: seo_canonical 

service-conf.in

service_id: general_id 
title: general_title 
products: list_products 

這給出了與前面的例子相同的service-conf.outproduct-conf.in當然會以相同的方式工作。

-P選項cpp抑制調試輸出的意見和-include包括彷彿輸入文件的第一行具有預處理指令的說法:

#include "master.in" 

,您還可以顯式並離開了命令行選項。

+0

謝謝@anthon! 當我實施解決方案時,我會在這裏回答自己。 (因爲我沒有足夠的聲望,所以無法贊成) –

相關問題