简体   繁体   English

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

[英]Read the value in the YAML file from the Python script

I have a Python script named app.py that has the value of the project ID, 我有一个名为app.py的Python脚本,它具有项目ID的值,

project_id = "p007-999"

I hard code it inside the .gitlab-ci.yml file provided below, 我将其硬编码在下面提供的.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 .

I would like to automate this. 我想使它自动化。 I think the steps for that will be, 我认为要采取的步骤是,

a. 一种。 write the project_id value from the Python script to a shell script variables.sh . 将Python脚本中的project_id值写入shell脚本variables.sh
b. In the before_script: of the YML file, execute the variables.sh and read the value from there. 在YML文件的before_script:中,执行variables.sh并从那里读取值。

How do I achieve it correctly? 如何正确实现?

You can do this with ruamel.yaml , which was specfically developed to do these kind of round-trip updates (disclaimer: I am the author of that package). 您可以使用ruamel.yaml进行此ruamel.yaml ,该文件专门开发用于进行此类往返更新(免责声明:我是该软件包的作者)。

Assuming your input is: 假设您输入的是:

# 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 .

And your code something like: 和您的代码类似:

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)

which gives as output: 作为输出:

# 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 .

(including the comment, which you lose when using by most other YAML loader/dumpers) (包括注释,您在大多数其他YAML加载程序/转储程序使用该注释时会丢失)

This is almost definitely inappropriate, but I really can't help myself. 这几乎绝对是不合适的,但我实在无能为力。

WARNING: This is destructive, and will overwrite .gitlab-ci.yml . 警告:这是破坏性的,将覆盖.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. In the first file only, assign the last column to pid only if the first column is exactly "project_id". 仅在第一个文件中,仅当第一列恰好是“ project_id”时,才将最后一列分配给pid

  2. On any line in any file that assigns the variable WE_PROJECT_ID , replace the first quoted string with pid . 在任何文件中分配变量WE_PROJECT_ID任何行上,将第一个带引号的字符串替换为pid

  3. In any files other than the first, print all records to the current file. 在除第一个文件以外的任何文件中,将所有记录打印到当前文件。 This is possible due to awk 's nifty buffers. 由于awk的漂亮缓冲区,这是可能的。 If you have to be told to make a back-up, don't run this. 如果必须告诉您进行备份,请不要运行此备份。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM