Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Install using pip (>= 19.0).

```bash
pip install --upgrade pip
pip install git+https://github.com/cms-l1-globaltrigger/tm-diff.git@0.6.3
pip install git+https://github.com/cms-l1-globaltrigger/tm-diff.git@0.7.0
```

## Basic usage
Expand Down Expand Up @@ -43,6 +43,7 @@ Use flag `-s|--skip <mode>` to ignore certain attributes. Options are

* `module` to skip implementation details (attributes `uuid_firmware`, `n_modules`, `module_id`, `module_index`)
* `comment` to skip comments (attribute `comment`)
* `labels` to skip algorithm labels (attribute `labels`)

**Example:**

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
tm-python @ git+https://github.com/cms-l1-globaltrigger/tm-python@0.7.4
tm-python @ git+https://github.com/cms-l1-globaltrigger/tm-python@0.8.0
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

setup(
name="tm-diff",
version='0.6.3',
version='0.7.0',
url="https://github.com/cms-l1-globaltrigger/tm-diff",
author="Bernhard Arnold",
author_email="bernhard.arnold@cern.ch",
description="Compare the content of two XML trigger menus.",
long_description=long_description,
packages=['tmDiff'],
install_requires=[
'tm-python @ git+https://github.com/cms-l1-globaltrigger/tm-python@0.7.4',
'tm-python @ git+https://github.com/cms-l1-globaltrigger/tm-python@0.8.0',
],
entry_points={
'console_scripts': [
Expand Down
2 changes: 1 addition & 1 deletion tmDiff/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.6.3'
__version__ = '0.7.0'
7 changes: 6 additions & 1 deletion tmDiff/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

SKIP_MODULE = 'module'
SKIP_COMMENT = 'comment'
SKIP_CHOICES = [SKIP_MODULE, SKIP_COMMENT]
SKIP_LABELS = 'labels'
SKIP_CHOICES = [SKIP_MODULE, SKIP_COMMENT, SKIP_LABELS]

SORT_INDEX = 'index'
SORT_NAME = 'name'
Expand Down Expand Up @@ -93,6 +94,10 @@ def main():
if SKIP_COMMENT in args.skip:
skip.append('comment')

# Skip comments
if SKIP_LABELS in args.skip:
skip.append('labels')

# Extract information from XMLs
from_menu = menudiff.Menu(from_file)
from_menu.skip = skip
Expand Down
166 changes: 96 additions & 70 deletions tmDiff/menudiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@
name: <name>
expression: <expression>
comment: <comment>
labels: <labels>
```

The printed line information refers to the extracted content (can be dumped
with flag -d

"""

import tmTable

import datetime
import difflib
import logging
import sys, os
import os
import sys

import tmTable

from . import __version__

Expand All @@ -37,7 +38,7 @@ class TTY:
blue = "\033[34m"
magenta = "\033[35m"

class Diffable(object):
class Diffable:
"""Implements a diffabel object. To be inherited by classes defining class
attribute `sorted_attribuites`.
"""
Expand All @@ -57,19 +58,18 @@ def fmt_attr(self, attr):
"""
return "{0}: {1}".format(attr, getattr(self, attr))

def to_diff(self, skip=[]):
def to_diff(self, skip=None):
"""Returns diff-able list of attributes for unified diff.
>>> o.to_diff()
['foo: 42', 'bar: baz']
>>> o.to_diff(skip=['bar']) # skip attributes
['foo: 42']
"""
skip = skip or []
return [self.fmt_attr(attr) for attr in self.sorted_attributes if attr not in skip]

class Meta(Diffable):
"""Simple menu metadata container.
>>> meta = Meta(**row)
"""
"""Diffable menu metadata container."""

sorted_attributes = (
'name',
Expand All @@ -83,9 +83,7 @@ class Meta(Diffable):
)

class Algorithm(Diffable):
"""Simple algorithm container.
>>> algorithm = Algorithm(**row)
"""
"""Diffable algorithm container."""

sorted_attributes = (
'index',
Expand All @@ -94,15 +92,18 @@ class Algorithm(Diffable):
'name',
'expression',
'comment',
'labels',
)

report_attributes = (
'index',
'name',
'expression',
'labels',
)

class Cut(Diffable):
"""Diffable cut container."""

sorted_attributes = (
'name',
Expand All @@ -114,7 +115,7 @@ class Cut(Diffable):
'comment',
)

class Menu(object):
class Menu:
"""Simple menu container."""

def __init__(self, filename):
Expand Down Expand Up @@ -175,7 +176,7 @@ def dump_intermediate(self, outdir=None):
if not outdir:
outdir = os.getcwd()
filename = "{0}.txt".format(os.path.basename(self.filename))
with open(os.path.join(outdir, filename), 'wb') as fp:
with open(os.path.join(outdir, filename), 'w') as fp:
for line in self.to_diff():
fp.write(line)
fp.write(os.linesep)
Expand All @@ -184,9 +185,6 @@ def report_diff(fromfile, tofile, verbose=False, ostream=sys.stdout):
"""Perform simple diff on two menus in TWiki format for reports.
>>> report_diff(fromfile, tofile)
"""
fromlist = fromfile.to_diff()
tolist = tofile.to_diff()

from_algorithms = {}
to_algorithms = {}

Expand All @@ -207,7 +205,7 @@ def added_algorithms(a, b):
removed = added_algorithms(fromfile, tofile)
updated = []

for name, fromalgorithm in from_algorithms.iteritems():
for name, fromalgorithm in from_algorithms.items():
if name in to_algorithms:
toalgorithm = to_algorithms[name]
differences = []
Expand Down Expand Up @@ -254,38 +252,51 @@ def unified_diff(fromfile, tofile, verbose=False, ostream=sys.stdout):
fromlines = fromfile.to_diff()
tolines = tofile.to_diff()

def write_added(line):
if ostream.isatty():
ostream.write(TTY.green)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_removed(line):
if ostream.isatty():
ostream.write(TTY.red)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_marker(line):
if ostream.isatty():
ostream.write(TTY.yellow)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_match(line):
ostream.write(line)

count = 0
for line in difflib.unified_diff(fromlines, tolines, fromfile=fromfile.filename, tofile=tofile.filename, lineterm=""):
if count:
ostream.write(os.linesep)
# Print added lines
if line.startswith('+'):
if ostream.isatty():
ostream.write(TTY.green)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_added(line)
# Print removed lines
elif line.startswith('-'):
if ostream.isatty():
ostream.write(TTY.red)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_removed(line)
# Print diff markers
elif line.startswith('@@'):
if ostream.isatty():
ostream.write(TTY.yellow)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_marker(line)
# Print matching lines
else:
ostream.write(os.linesep)
if ostream.isatty():
ostream.write(TTY.clear)
ostream.write(line)
ostream.write(os.linesep)
write_match(line)
count += 1

# Omit newline if nothing was written.
if count:
ostream.write(os.linesep)

def context_diff(fromfile, tofile, verbose=False, ostream=sys.stdout):
"""Perform context diff on two menus.
Expand All @@ -294,46 +305,61 @@ def context_diff(fromfile, tofile, verbose=False, ostream=sys.stdout):
fromlines = fromfile.to_diff()
tolines = tofile.to_diff()

def write_added(line):
if ostream.isatty():
ostream.write(TTY.green)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_removed(line):
if ostream.isatty():
ostream.write(TTY.red)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_changed(line):
if ostream.isatty():
ostream.write(TTY.magenta)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_marker(line):
if ostream.isatty():
ostream.write(TTY.yellow)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)

def write_match(line):
ostream.write(line)

count = 0
for line in difflib.context_diff(fromlines, tolines, fromfile=fromfile.filename, tofile=tofile.filename, lineterm=""):
if count:
ostream.write(os.linesep)
# Print added lines
if line.startswith('+ '):
if ostream.isatty():
ostream.write(TTY.green)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_added(line)
# Print removed lines
elif line.startswith('- '):
if ostream.isatty():
ostream.write(TTY.red)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_removed(line)
# Print changed lines
elif line.startswith('! '):
if ostream.isatty():
ostream.write(TTY.magenta)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_changed(line)
# Print diff markers
elif line.startswith('---') or line.startswith('***'):
if ostream.isatty():
ostream.write(TTY.yellow)
ostream.write(os.linesep)
ostream.write(line)
if ostream.isatty():
ostream.write(TTY.clear)
write_marker(line)
# Print matching lines
else:
ostream.write(os.linesep)
if ostream.isatty():
ostream.write(TTY.clear)
ostream.write(line)
ostream.write(os.linesep)
write_match(line)
count += 1

# Omit newline if nothing was written.
if count:
ostream.write(os.linesep)

def html_diff(fromfile, tofile, verbose=False, ostream=sys.stdout):
"""Perform diff on two menus and writes results to HTML table.
Expand Down