Skip to content

Commit a56e1d2

Browse files
committed
initial commit
1 parent 90ff8e0 commit a56e1d2

14 files changed

+250
-1
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
**/__pycache__
2+
/dist/
3+
/*.egg-info
4+
/*.egg
5+
build
6+
tmp
7+
README.rst

.travis.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
language: python
2+
python:
3+
- "3.3"
4+
- "3.4"
5+
- "3.5"
6+
- "3.5-dev"
7+
before_install:
8+
- bundle install
9+
install: "pip install pyaml flake8 pylint"
10+
script: "rake test"

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM alpine:3.3
2+
MAINTAINER think@hotmail.de
3+
4+
RUN \
5+
apk add --no-cache python3 && \
6+
apk add --no-cache --virtual=build-dependencies wget ca-certificates && \
7+
wget "https://bootstrap.pypa.io/get-pip.py" -O /dev/stdout | python3 && \
8+
apk del build-dependencies
9+
10+
RUN pip install --no-cache-dir pyaml
11+
12+
COPY bin /bin
13+
COPY compose_diff /usr/lib/python3.5/site-packages/compose_diff
14+
15+
RUN chmod +x /bin/compose_diff
16+
17+
ENTRYPOINT ["python3", "/bin/compose_diff"]

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source 'https://rubygems.org'
2+
gem 'rubocop', '~> 0.41.0'
3+
gem 'rake'
4+
gem 'aruba'

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include README.rst
2+
include features/*.feature

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
1+
[![Build Status](https://travis-ci.org/funkwerk/compose_diff.svg)](https://travis-ci.org/funkwerk/compose_diff)
2+
[![](https://badge.imagelayers.io/funkwerk/compose_diff.svg)](https://imagelayers.io/?images=funkwerk/compose_diff:latest 'funkwerk/compose_diff')
3+
[![PyPi downloads](https://img.shields.io/pypi/dm/compose_diff.svg)](https://pypi.python.org/pypi/compose_diff/)
4+
[![PyPi version](https://img.shields.io/pypi/v/compose_diff.svg)](https://pypi.python.org/pypi/compose_diff/)
5+
[![Docker pulls](https://img.shields.io/docker/pulls/funkwerk/compose_diff.svg)](https://hub.docker.com/r/funkwerk/compose_diff/)
16
# compose_diff
2-
Diff Docker Compose Files
7+
8+
Diff docker-compose files.
9+
10+
## Usage
11+
12+
### Via Python
13+
14+
Install it via:
15+
`pip3 install compose_diff`
16+
17+
After that use it like
18+
19+
`compose_diff --images old.yml new.yml`
20+
this will print the the differences in the used images between the two versions.
21+
22+
## Features
23+
- Support for Version 2 and Version 1.
24+
- Diffs Images

Rakefile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
task default: :test
2+
3+
task test: :audit
4+
task :test do
5+
sh "PYTHONPATH=#{File.expand_path '.'}:$PYTHONPATH cucumber"
6+
end
7+
8+
desc 'Publishes the PyPi'
9+
task push: :generate
10+
task :push do
11+
sh 'python3 setup.py sdist upload'
12+
end
13+
14+
desc 'Checks style'
15+
task audit: :rubocop
16+
task :audit do
17+
ignores = %w(D100 D101 D102 D103 D104 E501 I201)
18+
19+
FILES = FileList[%w(bin/compose_diff compose_diff/*.py setup.py)]
20+
sh "flake8 --ignore='#{ignores * ','}' #{FILES}"
21+
sh "pylint -E #{FILES}"
22+
end
23+
24+
desc 'Checks ruby style'
25+
task :rubocop do
26+
sh 'rubocop'
27+
end
28+
29+
task :generate do
30+
sh 'pandoc --from=markdown --to=rst --output=README.rst README.md'
31+
end
32+
33+
task :docker do
34+
sh 'docker build --tag=funkwerk/compose_diff .'
35+
end

__init__.py

Whitespace-only changes.

bin/compose_diff

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python3
2+
from compose_diff import ComposeDiff
3+
4+
5+
if __name__ == '__main__':
6+
7+
import argparse
8+
import sys
9+
10+
parser = argparse.ArgumentParser()
11+
parser.add_argument(
12+
'--images', action='store_const', const=True,
13+
help='diffs the images', default=False)
14+
parser.add_argument('files', nargs=argparse.REMAINDER)
15+
args = parser.parse_args()
16+
17+
if args.images:
18+
if len(args.files) != 2:
19+
print('please diff exactly two files. You provided {0} files.'.format(len(args.files)))
20+
sys.exit(1)
21+
22+
old, new = args.files[0], args.files[1]
23+
24+
ComposeDiff().diff_images(old, new)
25+
else:
26+
parser.print_help()

compose_diff/__init__.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python3
2+
from yaml import load
3+
4+
5+
class ComposeDiff:
6+
7+
def __init__(self):
8+
pass
9+
10+
def diff_images(self, old, new):
11+
old = self.images(self.read(old))
12+
new = self.images(self.read(new))
13+
14+
print('| {0} | {1} |'.format('Name', 'Version'))
15+
print('| - | - |')
16+
for key in sorted(set(list(old.keys()) + list(new.keys()))):
17+
version = self.format_version(
18+
old=old[key] if key in old else None,
19+
new=new[key] if key in new else None)
20+
21+
print('| {0} | {1} |'.format(key, version))
22+
23+
@staticmethod
24+
def format_version(old, new):
25+
if old is None:
26+
return '{0} (new)'.format(new)
27+
elif new is None:
28+
return '{0} (deleted)'.format(old)
29+
elif old == new:
30+
return old
31+
return '{0} ({1})'.format(new, old)
32+
33+
@staticmethod
34+
def read(path):
35+
with open(path, 'r') as file:
36+
return load(file.read())
37+
38+
@staticmethod
39+
def images(data):
40+
result = {}
41+
42+
if 'services' in data:
43+
data = data['services']
44+
for name, content in data.items():
45+
if content is None:
46+
continue
47+
if 'image' not in content:
48+
continue
49+
image_name, tag = ComposeDiff.split_image(content['image'])
50+
result[image_name] = tag
51+
return result
52+
53+
@staticmethod
54+
def split_image(data):
55+
if ':' not in data:
56+
return data, 'latest'
57+
return data.split(':')

compose_diff/features/images.feature

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Feature: Images
2+
As a Tester
3+
I want to see which images have changed
4+
so that I know where to test especially
5+
6+
Scenario: Diff Images
7+
Given a file named "A.yml" with:
8+
"""
9+
version: "2"
10+
services:
11+
one:
12+
image: one:1
13+
two:
14+
image: two:1
15+
four:
16+
image: four:1
17+
"""
18+
And a file named "B.yml" with:
19+
"""
20+
version: "2"
21+
services:
22+
one:
23+
image: one:1
24+
two:
25+
image: two:2
26+
three:
27+
image: three:1
28+
"""
29+
When I run `bin/compose_diff --images A.yml B.yml`
30+
Then it should pass with exactly:
31+
"""
32+
| Name | Version |
33+
| - | - |
34+
| four | 1 (deleted) |
35+
| one | 1 |
36+
| three | 1 (new) |
37+
| two | 2 (1) |
38+
"""

compose_diff/features/support/env.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require 'aruba/cucumber'

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[metadata]
2+
description-file = README.md

setup.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from setuptools import setup
2+
3+
4+
def readme():
5+
with open('README.rst') as file:
6+
return file.read()
7+
8+
setup(
9+
name='compose_diff',
10+
version='0.1.0',
11+
description='diff docker-compose files',
12+
long_description=readme(),
13+
url='http://github.com/funkwerk/compose_diff',
14+
author='Stefan Rohe',
15+
license='MIT',
16+
packages=['compose_diff'],
17+
install_requires=['pyaml'],
18+
zip_safe=False,
19+
classifiers=[
20+
'License :: OSI Approved :: MIT License',
21+
'Programming Language :: Python :: 3',
22+
'Topic :: Software Development',
23+
'Environment :: Console',
24+
'Operating System :: OS Independent',
25+
],
26+
keywords='docker-compose diff docker yml',
27+
include_package_data=True,
28+
scripts=['bin/compose_diff'])

0 commit comments

Comments
 (0)