从Python脚本读取YAML文件中的值

时间:2019-04-06 07:56:35

标签: python bash shell gitlab yaml

我有一个名为app.py的Python脚本,它具有项目ID的值

project_id = "p007-999"

我将其硬编码在下面提供的.gitlab-ci.yml文件中

# list of enabled stages, the default should be built, test, publish
stages:
  - build
  - publish

before_script:
  - export WE_PROJECT_ID="p007-999"
  - docker login -u "$WELANCE_REGISTRY_USER" -p "$WELANCE_REGISTRY_TOKEN" registry.welance.com

build:
  stage: build
  services:
    - docker:dind
  variables:
    DOCKER_HOST: docker:2375
  script:
    - echo $WE_PROJECT_ID
    - cd templates && pwd && yarn install && yarn prod && cd ..
    - docker build -t registry.welance.com/$WE_PROJECT_ID:$CI_COMMIT_REF_SLUG.$CI_COMMIT_SHA -f ./build/ci/Dockerfile .

我想使它自动化。我认为要采取的步骤是

  

a。将Python脚本中的project_id值写入外壳   脚本variables.sh
  b。在YML文件的before_script:中,   执行variables.sh并从那里读取值。

如何正确实现?

2 个答案:

答案 0 :(得分:2)

您可以使用ruamel.yaml进行此操作,# list of enabled stages, the default should be built, test, publish stages: - build - publish before_script: - PID_TO_REPLACE - docker login -u "$WELANCE_REGISTRY_USER" -p "$WELANCE_REGISTRY_TOKEN" registry.welance.com build: stage: build services: - docker:dind variables: DOCKER_HOST: docker:2375 script: - echo $WE_PROJECT_ID - cd templates && pwd && yarn install && yarn prod && cd .. - docker build -t registry.welance.com/$WE_PROJECT_ID:$CI_COMMIT_REF_SLUG.$CI_COMMIT_SHA -f ./build/ci/Dockerfile . 是专门为执行这些操作而开发的 一种双向更新(免责声明:我是该软件包的作者)。

假设您输入的是:

import sys
from pathlib import Path
import ruamel.yaml


def update_project_id(path, pid):
   yaml = ruamel.yaml.YAML()
   yaml.indent(sequence=4, offset=2) # non-standard indent of 4 for sequences
   yaml.preserve_quotes = True
   data = yaml.load(path)

   data['before_script'][0] = 'export WE_PROJECT_ID="' + pid + '"'
   yaml.dump(data, path)

file_name = Path('.gitlab-ci.yml')
project_id = "p007-999"

update_project_id(file_name, project_id)

您的代码如下:

# list of enabled stages, the default should be built, test, publish
stages:
  - build
  - publish

before_script:
  - export WE_PROJECT_ID="p007-999"
  - docker login -u "$WELANCE_REGISTRY_USER" -p "$WELANCE_REGISTRY_TOKEN" registry.welance.com

build:
  stage: build
  services:
    - docker:dind
  variables:
    DOCKER_HOST: docker:2375
  script:
    - echo $WE_PROJECT_ID
    - cd templates && pwd && yarn install && yarn prod && cd ..
    - docker build -t registry.welance.com/$WE_PROJECT_ID:$CI_COMMIT_REF_SLUG.$CI_COMMIT_SHA -f ./build/ci/Dockerfile .

给出输出:

s = []
l = ['a', 'b', 'c', 'a', 'b']
for i in range(len(l)):
    j, k = 0, i+1
    while k <= len(l):
        sub_list = l[j:k]
        if sub_list not in s:
            s.append(sub_list)
        j += 1
        k += 1
print(s)
[['a'], ['b'], ['c'], ['a', 'b'], ['b', 'c'], ['c', 'a'], ['a', 'b', 'c'], ['b', 'c', 'a'], ['c', 'a', 'b'], ['a', 'b', 'c', 'a'], ['b', 'c', 'a', 'b'], ['a', 'b', 'c', 'a', 'b']]

(包括注释,您在大多数其他YAML加载程序/转储程序使用该注释时会丢失)

答案 1 :(得分:1)

这几乎绝对是不合适的,但是我真的束手无策。

警告:这是破坏性的,将覆盖.gitlab-ci.yml

awk '
  NR==FNR && $1=="project_id" {pid=$NF}
  /WE_PROJECT_ID=/ {sub(/\".*\"/, pid)}
  NR!=FNR {print > FILENAME}
' app.py .gitlab-ci.yml
  1. 仅在第一个文件中,仅当第一列恰好是“ project_id”时,才将最后一列分配给pid

  2. 在任何文件中分配变量WE_PROJECT_ID的任何行上,将第一个带引号的字符串替换为pid

  3. 在第一个文件以外的任何文件中,将所有记录打印到当前文件。由于awk的漂亮缓冲区,这是可能的。如果必须告诉您进行备份,请不要运行它。