2017-07-27 103 views
-1

我試圖使用pkuczynski's Gist讀取yaml文件以獲取key:value作爲變量。使用Makefile讀取Yaml

以下是我需要做的一件(多件)嘗試;我沒有得到任何錯誤,但只是一個空$(DEVURL)

config.yaml:

baseurl: 
    dev: "https://some-dev-url/" 
    stage: "https://a-staging-url/" 
    prod: "https://production-url" 

的Makefile:

BASEDIR  =$(CURDIR) 
CONFDIR  =$(BASEDIR) 
OUTPUTDIR =$/../build 

DEVDIR  =$(OUTPUTDIR)/dev 
PRODDIR  =$(OUTPUTDIR)/prod 
STAGEDIR =$(OUTPUTDIR)/stage 

DEVCONF  =$(CONFDIR)/config.dev.yml 
PRODCONF =$(CONFDIR)/config.prod.yml 
STAGECONF =$(CONFDIR)/config.stage.yml 
USRCONFIG =$/../usr/config.yml 

dev: 
    . $(BASEDIR)/parse_yaml.sh     # include parse_yaml function 
    $(info $(parse_yaml $(USRCONFIG) 'config_')) # read yaml file 
    $(parse-yaml DEVURL is $(config_baseurl_dev)) # Get the baseurl:dev KEY 
    @echo ${DEVURL}        # Print the DEVURL from KEY 
    sleep 1 
    rm -rfv $(DEVDIR)        # Delete the DEVDIR b4 build 
    sleep 1 
    $(BUILDER) --config=$(DEVCONF) -b=$(DEVURL) # Inset the baseurl:dev KEY 

parse_yaml.sh:

#!/bin/sh 
parse_yaml() { 
    local prefix=$2 
    local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034') 
    sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ 
     -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 | 
    awk -F$fs '{ 
     indent = length($1)/2; 
     vname[indent] = $2; 
     for (i in vname) {if (i > indent) {delete vname[i]}} 
     if (length($3) > 0) { 
     vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")} 
     printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3); 
     } 
    }' 
} 

回答

0
  1. 您似乎認爲make配方的連續行是作爲一個單獨的shell執行的。這不是它的工作方式:每行都在單獨的shell調用中執行。所以,當你執行

    . $(BASEDIR)/parse_yaml.sh 
    

    它對你的食譜的其他部分沒有影響。如果要在單個shell調用的上下文中執行完整配方,請將所有內容都放在一行中,並使用;,&&||鏈接命令。您可以使用續行(一個\作爲行結束前的最後一個字符)爲更好的可讀性:

    command1 && \ 
    command2 ; \ 
    command3 || \ 
    command4 
    
  2. 當食譜是由化妝擴大,各$被視爲一個參考做變量或功能。因此,擴大

    $(parse-yaml DEVURL is $(config_baseurl_dev)) 
    

    化妝時會試圖執行不存在(它是一個shell功能,不是簡單的修修補補功能)$(parse-yaml...化妝功能。這個陳述將因此完全被忽略。如果你想保護一些從擴大這些$跡象,加倍他們:

    $$(parse-yaml DEVURL is $$(config_baseurl_dev)) 
    

    後化妝擴張將被傳遞到外殼爲:

    $(parse-yaml DEVURL is $(config_baseurl_dev)) 
    

    這可能是你要哪個更接近。

  3. 你的一些變量定義是怪異:

    OUTPUTDIR =$/../build 
    

    您從領先$/期待什麼?有一個名爲$/沒有自動make變量,但要無論如何都將展開,並因爲它是不確定的,其結果將是一樣的:

    OUTPUTDIR =../build 
    

    即使是你想要的東西,這是一個有點怪,你不覺得嗎?除非有很好的理由這麼做,否則請與Makefiles的可靠維護人員友好相處,並避免它。

0

生成文件

all: 
    $(foreach var,$(shell . $(CURDIR)/parse_yaml.sh; parse_yaml config.yaml 'config_'),$(eval $(var))) 
    $(info config_baseurl__dev is $(config_baseurl__dev)) 
    $(info config_baseurl__stage is $(config_baseurl__stage)) 
    $(info config_baseurl__prod is $(config_baseurl__prod)) 

結果如下。

make 
config_baseurl__dev is "https://some-dev-url/" 
config_baseurl__stage is "https://a-staging-url/" 
config_baseurl__prod is "https://production-url"