2017-07-27 232 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"