如何比较 yaml 文件而不考虑顺序差异?

Joh*_*ane 5 python yaml kubernetes

我需要比较从两个不同进程生成的、顺序不同的 yaml 文件,并检测它们在 python 中在逻辑上是否相同。

yaml 文件 1:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
Run Code Online (Sandbox Code Playgroud)

yaml 文件 2:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        ports:
        - containerPort: 80
        image: nginx:1.14.2
Run Code Online (Sandbox Code Playgroud)

在逻辑级别与文字文本级别生成 yaml 的有用差异的最佳方法是什么?在上面的玩具示例中,这些 yaml 文件应被视为等效。

Joh*_*ane 5

我能够达到的最佳解决方案是下面的脚本。

"""
python path_to_dir/compare_yaml.py path_to_dir/file1.yaml path_to_dir/file2.yaml
"""
import argparse
import yaml
import dictdiffer

parser = argparse.ArgumentParser(description='Convert two yaml files to dict and compare equality. Allows comparison of differently ordered keys.')
parser.add_argument('file_paths', type=str, nargs=2,
                    help='Full paths to yaml documents')
args = parser.parse_args()

print(f"File Path 1: {args.file_paths[0]}")
print(f"File Path 2: {args.file_paths[1]}")

with open(args.file_paths[0],'r') as rdr:
    data1=rdr.read()

with open(args.file_paths[1],'r') as rdr:
    data2=rdr.read()

data1_dict = yaml.load(data1,Loader=yaml.FullLoader)
data2_dict = yaml.load(data2,Loader=yaml.FullLoader)

if data1_dict == data2_dict:
    print("No difference detected")
else:
    print("Differences detected:")
    for diff in list(dictdiffer.diff(data1_dict, data2_dict)):
        print(diff)
Run Code Online (Sandbox Code Playgroud)

如果针对有问题的示例运行,如下所示:

python .../compare_yaml.py .../yaml1.yaml .../yaml2.yaml
File Path 1: .../yaml1.yaml
File Path 2: .../yaml2.yaml
No difference detected
Run Code Online (Sandbox Code Playgroud)

如果更改密钥,则得到如下输出:

python .../compare_yaml.py .../yaml1.yaml .../yaml2.yaml
File Path 1: .../yaml1.yaml
File Path 2: .../yaml2.yaml
Differences detected:
('change', ['spec', 'template', 'spec', 'containers', 0, 'name'], ('nginx', 'ngin'))
Run Code Online (Sandbox Code Playgroud)