Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Aug 10, 2021. It is now read-only.

Commit d581962

Browse filesBrowse files
author
Kenneth Reitz
committed
diffing works!
1 parent fd65e4d commit d581962
Copy full SHA for d581962

File tree

Expand file treeCollapse file tree

1 file changed

+133
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+133
-0
lines changed

‎bin/pip-diff

Copy file name to clipboard
+133Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
"""Usage:
5+
pip-diff (--fresh | --stale) <reqfile1> <reqfile2>
6+
pip-diff (-h | --help)
7+
8+
Options:
9+
-h --help Show this screen.
10+
--fresh List newly added packages.
11+
--stale List removed packages.
12+
"""
13+
import os
14+
from docopt import docopt
15+
from pkg_resources import parse_requirements
16+
17+
18+
# TODO: ignore lines
19+
IGNORABLE_LINES = '#', '-r'
20+
VERSION_OPERATORS = ['==', '>=', '<=', '>', '<', ',']
21+
22+
def split(s):
23+
for operator in VERSION_OPERATORS:
24+
s = s.replace(operator, '!')
25+
26+
return s.split('!')
27+
28+
29+
# TODO: consider package upgrades.
30+
31+
class Requirements(object):
32+
"""docstring for Requirements"""
33+
def __init__(self, reqfile=None):
34+
super(Requirements, self).__init__()
35+
self.path = reqfile
36+
self.requirements = []
37+
38+
if reqfile:
39+
self.load(reqfile)
40+
41+
def __repr__(self):
42+
return '<Requirements \'{}\'>'.format(self.path)
43+
44+
def load(self, reqfile):
45+
46+
if not os.path.exists(reqfile):
47+
raise ValueError('The given requirements file does not exist.')
48+
49+
with open(reqfile) as f:
50+
data = []
51+
52+
for line in f:
53+
line = line.strip()
54+
55+
# Skip lines that start with any comment/control charecters.
56+
if not any([line.startswith(p) for p in IGNORABLE_LINES]):
57+
data.append(line)
58+
59+
for requirement in parse_requirements(data):
60+
self.requirements.append(requirement)
61+
62+
63+
# assert that the given file exists
64+
# parse the file
65+
# insert those entries into self.declarations
66+
pass
67+
68+
def diff(self, requirements, ignore_versions=False):
69+
r1 = self
70+
r2 = requirements
71+
results = {'fresh': [], 'stale': []}
72+
73+
# Generate fresh packages.
74+
other_reqs = (
75+
[r.project_name for r in r1.requirements]
76+
if ignore_versions else r1.requirements
77+
)
78+
79+
for req in r2.requirements:
80+
r = req.project_name if ignore_versions else req
81+
82+
if r not in other_reqs:
83+
results['fresh'].append(req)
84+
85+
# Generate stale packages.
86+
other_reqs = (
87+
[r.project_name for r in r2.requirements]
88+
if ignore_versions else r2.requirements
89+
)
90+
91+
for req in r1.requirements:
92+
r = req.project_name if ignore_versions else req
93+
94+
if r not in other_reqs:
95+
results['stale'].append(req)
96+
97+
return results
98+
99+
100+
101+
102+
103+
def diff(r1, r2, include_fresh=False, include_stale=False):
104+
# assert that r1 and r2 are files.
105+
106+
try:
107+
r1 = Requirements(r1)
108+
r2 = Requirements(r2)
109+
except ValueError:
110+
print 'There was a problem loading the given requirements files.'
111+
exit(os.EX_NOINPUT)
112+
113+
results = r1.diff(r2)
114+
print results
115+
116+
117+
118+
def main():
119+
args = docopt(__doc__, version='pip-diff')
120+
121+
kwargs = {
122+
'r1': args['<reqfile1>'],
123+
'r2': args['<reqfile2>'],
124+
'include_fresh': args['--fresh'],
125+
'include_stale': args['--stale']
126+
}
127+
128+
diff(**kwargs)
129+
130+
131+
132+
if __name__ == '__main__':
133+
main()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.