Skip to content

Commit 89eaa7d

Browse files
committed
refactor(release): split out code from the release script
Move the code for checking the files in the released sdist into a separate script so it can more easily be run separately.
1 parent b367425 commit 89eaa7d

File tree

2 files changed

+219
-194
lines changed

2 files changed

+219
-194
lines changed

release/compare_tar_against_git.py

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
#!/usr/bin/env python3
2+
3+
from subprocess import check_output
4+
import sys
5+
import os.path
6+
7+
8+
def main(tarname, gitroot):
9+
"""Run this as ./compare_tar_against_git.py TARFILE GITROOT
10+
11+
Args
12+
====
13+
14+
TARFILE: Path to the built sdist (sympy-xx.tar.gz)
15+
GITROOT: Path ro root of git (dir containing .git)
16+
"""
17+
compare_tar_against_git(tarname, gitroot)
18+
19+
20+
## TARBALL WHITELISTS
21+
22+
# If a file does not end up in the tarball that should, add it to setup.py if
23+
# it is Python, or MANIFEST.in if it is not. (There is a command at the top
24+
# of setup.py to gather all the things that should be there).
25+
26+
# TODO: Also check that this whitelist isn't growing out of date from files
27+
# removed from git.
28+
29+
# Files that are in git that should not be in the tarball
30+
git_whitelist = {
31+
# Git specific dotfiles
32+
'.gitattributes',
33+
'.gitignore',
34+
'.mailmap',
35+
# Travis and CI
36+
'.travis.yml',
37+
'.ci/durations.json',
38+
'.ci/generate_durations_log.sh',
39+
'.ci/parse_durations_log.py',
40+
'.ci/blacklisted.json',
41+
'.ci/README.rst',
42+
'.github/FUNDING.yml',
43+
'.editorconfig',
44+
'.coveragerc',
45+
'asv.conf.travis.json',
46+
'coveragerc_travis',
47+
'codecov.yml',
48+
'pytest.ini',
49+
'MANIFEST.in',
50+
# Code of conduct
51+
'CODE_OF_CONDUCT.md',
52+
# Pull request template
53+
'PULL_REQUEST_TEMPLATE.md',
54+
# Contributing guide
55+
'CONTRIBUTING.md',
56+
# Nothing from bin/ should be shipped unless we intend to install it. Most
57+
# of this stuff is for development anyway. To run the tests from the
58+
# tarball, use setup.py test, or import sympy and run sympy.test() or
59+
# sympy.doctest().
60+
'bin/adapt_paths.py',
61+
'bin/ask_update.py',
62+
'bin/authors_update.py',
63+
'bin/build_doc.sh',
64+
'bin/coverage_doctest.py',
65+
'bin/coverage_report.py',
66+
'bin/deploy_doc.sh',
67+
'bin/diagnose_imports',
68+
'bin/doctest',
69+
'bin/generate_module_list.py',
70+
'bin/generate_test_list.py',
71+
'bin/get_sympy.py',
72+
'bin/mailmap_update.py',
73+
'bin/py.bench',
74+
'bin/strip_whitespace',
75+
'bin/sympy_time.py',
76+
'bin/sympy_time_cache.py',
77+
'bin/test',
78+
'bin/test_external_imports.py',
79+
'bin/test_executable.py',
80+
'bin/test_import',
81+
'bin/test_import.py',
82+
'bin/test_isolated',
83+
'bin/test_py2_import.py',
84+
'bin/test_setup.py',
85+
'bin/test_travis.sh',
86+
# The notebooks are not ready for shipping yet. They need to be cleaned
87+
# up, and preferably doctested. See also
88+
# https://github.com/sympy/sympy/issues/6039.
89+
'examples/advanced/identitysearch_example.ipynb',
90+
'examples/beginner/plot_advanced.ipynb',
91+
'examples/beginner/plot_colors.ipynb',
92+
'examples/beginner/plot_discont.ipynb',
93+
'examples/beginner/plot_gallery.ipynb',
94+
'examples/beginner/plot_intro.ipynb',
95+
'examples/intermediate/limit_examples_advanced.ipynb',
96+
'examples/intermediate/schwarzschild.ipynb',
97+
'examples/notebooks/density.ipynb',
98+
'examples/notebooks/fidelity.ipynb',
99+
'examples/notebooks/fresnel_integrals.ipynb',
100+
'examples/notebooks/qubits.ipynb',
101+
'examples/notebooks/sho1d_example.ipynb',
102+
'examples/notebooks/spin.ipynb',
103+
'examples/notebooks/trace.ipynb',
104+
'examples/notebooks/Bezout_Dixon_resultant.ipynb',
105+
'examples/notebooks/IntegrationOverPolytopes.ipynb',
106+
'examples/notebooks/Macaulay_resultant.ipynb',
107+
'examples/notebooks/Sylvester_resultant.ipynb',
108+
'examples/notebooks/README.txt',
109+
# This stuff :)
110+
'release/.gitignore',
111+
'release/README.md',
112+
'release/Vagrantfile',
113+
'release/fabfile.py',
114+
'release/Dockerfile',
115+
'release/Dockerfile-base',
116+
'release/release.sh',
117+
'release/rever.xsh',
118+
'release/pull_and_run_rever.sh',
119+
'release/compare_tar_against_git.py',
120+
# This is just a distribute version of setup.py. Used mainly for setup.py
121+
# develop, which we don't care about in the release tarball
122+
'setupegg.py',
123+
# pytest stuff
124+
'conftest.py',
125+
# Encrypted deploy key for deploying dev docs to GitHub
126+
'github_deploy_key.enc',
127+
}
128+
129+
# Files that should be in the tarball should not be in git
130+
131+
tarball_whitelist = {
132+
# Generated by setup.py. Contains metadata for PyPI.
133+
"PKG-INFO",
134+
# Generated by setuptools. More metadata.
135+
'setup.cfg',
136+
'sympy.egg-info/PKG-INFO',
137+
'sympy.egg-info/SOURCES.txt',
138+
'sympy.egg-info/dependency_links.txt',
139+
'sympy.egg-info/requires.txt',
140+
'sympy.egg-info/top_level.txt',
141+
'sympy.egg-info/not-zip-safe',
142+
'sympy.egg-info/entry_points.txt',
143+
# Not sure where this is generated from...
144+
'doc/commit_hash.txt',
145+
}
146+
147+
148+
def blue(text):
149+
return "\033[34m%s\033[0m" % text
150+
151+
152+
def red(text):
153+
return "\033[31m%s\033[0m" % text
154+
155+
156+
def run(*cmdline, cwd=None):
157+
"""
158+
Run command in subprocess and get lines of output
159+
"""
160+
return check_output(cmdline, encoding='utf-8', cwd=cwd).splitlines()
161+
162+
163+
def full_path_split(path):
164+
"""
165+
Function to do a full split on a path.
166+
"""
167+
# Based on https://stackoverflow.com/a/13505966/161801
168+
rest, tail = os.path.split(path)
169+
if not rest or rest == os.path.sep:
170+
return (tail,)
171+
return full_path_split(rest) + (tail,)
172+
173+
174+
def compare_tar_against_git(tarname, gitroot):
175+
"""
176+
Compare the contents of the tarball against git ls-files
177+
178+
See the bottom of the file for the whitelists.
179+
"""
180+
git_lsfiles = set(i.strip() for i in run('git', 'ls-files', cwd=gitroot))
181+
tar_output_orig = set(run('tar', 'tf', tarname))
182+
tar_output = set()
183+
for file in tar_output_orig:
184+
# The tar files are like sympy-0.7.3/sympy/__init__.py, and the git
185+
# files are like sympy/__init__.py.
186+
split_path = full_path_split(file)
187+
if split_path[-1]:
188+
# Exclude directories, as git ls-files does not include them
189+
tar_output.add(os.path.join(*split_path[1:]))
190+
# print tar_output
191+
# print git_lsfiles
192+
fail = False
193+
print()
194+
print(blue("Files in the tarball from git that should not be there:"))
195+
print()
196+
for line in sorted(tar_output.intersection(git_whitelist)):
197+
fail = True
198+
print(line)
199+
print()
200+
print(blue("Files in git but not in the tarball:"))
201+
print()
202+
for line in sorted(git_lsfiles - tar_output - git_whitelist):
203+
fail = True
204+
print(line)
205+
print()
206+
print(blue("Files in the tarball but not in git:"))
207+
print()
208+
for line in sorted(tar_output - git_lsfiles - tarball_whitelist):
209+
fail = True
210+
print(line)
211+
print()
212+
213+
if fail:
214+
sys.exit(red("Non-whitelisted files found or not found in the tarball"))
215+
216+
217+
if __name__ == "__main__":
218+
main(*sys.argv[1:])

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy