Skip to content

Commit a4a640d

Browse files
authored
Merge pull request #1429 from cuthbertLab/hatch
use hatch for building
2 parents 300845d + 065e70d commit a4a640d

File tree

4 files changed

+145
-253
lines changed

4 files changed

+145
-253
lines changed

dist/dist.py

Lines changed: 58 additions & 244 deletions
Original file line numberDiff line numberDiff line change
@@ -45,30 +45,27 @@
4545
12. zip up documentation/build/html and get ready to upload/delete it.
4646
Rename to music21.v.7.1.0-docs.zip (skip for Alpha/Beta)
4747
48-
12b. If any new file extensions have been added, be sure to add them to MANIFEST.in
48+
13. Run "hatch build" -- requires hatch to be installed "brew install hatch"
4949
50-
13. And finally this file. (from the command line; not as python -m...; cwd must
51-
be music21[base]/dist/ )
52-
There are major problems in SetupTools -- v8 (or even a 7.3.1) needs to
53-
fix them -- creating a dir music21.egg-info in the main dir with a
54-
requires.txt file created as root.
50+
14. Run this file -- it builds the no-corpus version of music21.
51+
DO NOT RUN THIS ON A PC -- the Mac .tar.gz might have an incorrect permission if you do.
5552
56-
14. COMMIT to GitHub at this point w/ commit comment of the new version,
53+
15. COMMIT to GitHub at this point w/ commit comment of the new version,
5754
then don't change anything until the next step is done.
5855
(.gitignore will avoid uploading the large files created here...)
5956
60-
15. Tag the commit: git tag -a vX.Y.Z -m "music21 vX.Y.Z"
57+
16. Tag the commit: git tag -a vX.Y.Z -m "music21 vX.Y.Z"
6158
Don't forget the "v" in the release tag.
6259
Sanity check that the correct commit was tagged: git log
6360
64-
16. Push tags: git push upstream --tags
61+
17. Push tags: git push upstream --tags
6562
66-
17. Create a new release on GitHub and upload the TWO files created here and docs.
63+
18. Create a new release on GitHub and upload the TWO files created here and docs.
6764
Drag in this order: .tar.gz, documentation, no-corpus.tar.gz
6865
6966
Finish this before doing the next step, even though it looks like it could be done in parallel.
7067
71-
18. Upload the new file to PyPI with "twine upload music21-7.3.5a2.tar.gz" [*]
68+
19. Upload the new file to PyPI with "twine upload music21-7.3.5a2.tar.gz" [*]
7269
7370
[*] Requires twine to be installed
7471
@@ -82,251 +79,68 @@
8279
username:your_username
8380
password:your_password
8481
85-
19. Delete the two .tar.gz files in dist...
82+
20. Delete the two .tar.gz files in dist...
8683
87-
20. For starting a new major release create a GitHub branch for the old one.
84+
21. For starting a new major release create a GitHub branch for the old one.
8885
89-
21. Immediately increment the number in _version.py and run tests on it here
86+
22. Immediately increment the number in _version.py and run tests on it here
9087
to prepare for next release.
9188
92-
22. Announce on the blog, to the list, and twitter.
93-
94-
DO NOT RUN THIS ON A PC -- the Mac .tar.gz has an incorrect permission if you do.
89+
23. Announce on the blog, to the list, and twitter.
9590
'''
96-
import hashlib
9791
import os
98-
import sys
9992
import shutil
10093
import tarfile
10194

102-
from music21 import base
103-
from music21 import common
104-
105-
from music21 import environment
106-
environLocal = environment.Environment('..dist.dist')
107-
108-
PY = sys.executable
109-
environLocal.warn(f'using python executable at {PY}')
110-
111-
class Distributor:
112-
def __init__(self):
113-
# self.fpEgg = None
114-
# self.fpWin = None
115-
self.fpTar = None
116-
117-
self.buildNoCorpus = True
118-
# self.fpEggNoCorpus = None
119-
self.fpTarNoCorpus = None
120-
121-
self.version = base.VERSION_STR
122-
123-
self._initPaths()
124-
125-
def _initPaths(self):
126-
127-
# must be in the dist dir
128-
directory = os.getcwd()
129-
parentDir = os.path.dirname(directory)
130-
parentContents = sorted(os.listdir(parentDir))
131-
# make sure we are in the proper directory
132-
if (not directory.endswith('dist')
133-
or 'music21' not in parentContents):
134-
raise Exception(f'not in the music21{os.sep}dist directory: {directory}')
135-
136-
self.fpDistDir = directory
137-
self.fpPackageDir = parentDir # dir with setup.py
138-
self.fpBuildDir = os.path.join(self.fpPackageDir, 'build')
139-
# self.fpEggInfo = os.path.join(self.fpPackageDir, 'music21.egg-info')
140-
141-
sys.path.insert(0, parentDir) # to get setup in as a possibility.
142-
143-
for fp in [self.fpDistDir, self.fpPackageDir, self.fpBuildDir]:
144-
environLocal.warn(fp)
145-
146-
147-
def updatePaths(self):
148-
'''
149-
Process output of build scripts. Get most recently produced distributions.
150-
'''
151-
contents = sorted(os.listdir(self.fpDistDir))
152-
for fn in contents:
153-
fp = os.path.join(self.fpDistDir, fn)
154-
# if self.version in fn and fn.endswith('.egg'):
155-
# self.fpEgg = fp
156-
# if self.version in fn and fn.endswith('.exe'):
157-
# fpNew = fp.replace('.macosx-10.8-intel.exe', '.win32.exe')
158-
# fpNew = fpNew.replace('.macosx-10.8-x86_64.exe', '.win32.exe')
159-
# fpNew = fpNew.replace('.macosx-10.9-intel.exe', '.win32.exe')
160-
# fpNew = fpNew.replace('.macosx-10.9-x86_64.exe', '.win32.exe')
161-
# fpNew = fpNew.replace('.macosx-10.10-intel.exe', '.win32.exe')
162-
# fpNew = fpNew.replace('.macosx-10.10-x86_64.exe', '.win32.exe')
163-
# fpNew = fpNew.replace('.macosx-10.11-intel.exe', '.win32.exe')
164-
# fpNew = fpNew.replace('.macosx-10.11-x86_64.exe', '.win32.exe')
165-
# fpNew = fpNew.replace('.macosx-10.12-intel.exe', '.win32.exe')
166-
# fpNew = fpNew.replace('.macosx-10.12-x86_64.exe', '.win32.exe')
167-
# if fpNew != fp:
168-
# os.rename(fp, fpNew)
169-
# self.fpWin = fpNew
170-
171-
print(fn)
172-
if self.version in fn and fn.endswith('.tar.gz'):
173-
self.fpTar = fp
174-
else:
175-
environLocal.warn(fn + ' does not end with .tar.gz')
176-
177-
environLocal.warn('giving path for tar.gz')
178-
for fn in [self.fpTar]:
179-
if fn is None:
180-
environLocal.warn('missing fn path')
181-
else:
182-
environLocal.warn(fn)
183-
184-
def removeCorpus(self, fp):
185-
'''
186-
Remove the corpus from a compressed file (.tar.gz) and
187-
create a new music21-noCorpus version.
188-
189-
Return the completed file path of the newly created edition.
190-
191-
NOTE: this function works only with Posix systems.
192-
'''
193-
TAR = 'TAR'
194-
# EGG = 'EGG'
195-
if fp and fp.endswith('.tar.gz'):
196-
mode = TAR
197-
modeExt = '.tar.gz'
198-
else:
199-
raise Exception('incorrect source file path')
200-
201-
fpDir, fn = os.path.split(fp)
202-
203-
# this has .tar.gz extension; this is the final completed package
204-
fnDst = fn.replace('music21', 'music21-noCorpus')
205-
fpDst = os.path.join(fpDir, fnDst)
206-
# remove file extensions
207-
fnDstDir = fnDst.replace(modeExt, '')
208-
fpDstDir = os.path.join(fpDir, fnDstDir)
209-
210-
# get the name of the dir after decompression
211-
fpSrcDir = os.path.join(fpDir, fn.replace(modeExt, ''))
212-
213-
# remove old dirs if it exists
214-
if os.path.exists(fpDst):
215-
shutil.rmtree(fpDst)
216-
217-
if os.path.exists(fpDstDir):
218-
shutil.rmtree(fpDstDir)
219-
220-
if mode == TAR:
221-
tf = tarfile.open(fp, 'r:gz')
222-
# the path here is the dir into which to expand,
223-
# not the name of that dir
224-
tf.extractall(path=fpDir)
225-
os.system(f'mv {fpSrcDir} {fpDstDir}')
226-
tf.close() # done after extraction
227-
228-
# elif mode == EGG:
229-
# os.system(f'mkdir {fpDstDir}')
230-
# # need to create dst dir to unzip into
231-
# tf = zipfile.ZipFile(fp, 'r')
232-
# tf.extractall(path=fpDstDir)
233-
234-
235-
# remove files, updates manifest
236-
for fn in common.getCorpusContentDirs():
237-
fp = os.path.join(fpDstDir, 'music21', 'corpus', fn)
238-
shutil.rmtree(fp)
239-
240-
fp = os.path.join(fpDstDir, 'music21', 'corpus', '_metadataCache')
95+
from music21._version import __version__ as version
96+
from music21.common.pathTools import getRootFilePath, getCorpusContentDirs
97+
98+
def removeCorpus():
99+
'''
100+
Remove the corpus from a compressed file (.tar.gz) and
101+
create a new music21-noCorpus version.
102+
103+
Return the completed file path of the newly created edition.
104+
105+
NOTE: this function works only with Posix systems.
106+
'''
107+
fp = getRootFilePath() / 'dist' / ('music21-' + version + '.tar.gz')
108+
fpDir, fn = os.path.split(str(fp))
109+
110+
# this has .tar.gz extension; this is the final completed package
111+
fnDst = fn.replace('music21', 'music21-noCorpus')
112+
fpDst = os.path.join(fpDir, fnDst)
113+
# remove file extensions
114+
fnDstDir = fnDst.replace('.tar.gz', '')
115+
fpDstDir = os.path.join(fpDir, fnDstDir)
116+
117+
file = tarfile.open(fp)
118+
file.extractall(fpDir)
119+
file.close()
120+
121+
os.rename(fpDstDir.replace('-noCorpus', ''), fpDstDir)
122+
123+
# remove files, updates manifest
124+
for fn in getCorpusContentDirs():
125+
fp = os.path.join(fpDstDir, 'music21', 'corpus', fn)
241126
shutil.rmtree(fp)
242127

243-
# adjust the sources Txt file
244-
# if mode == TAR:
245-
sourcesTxt = os.path.join(fpDstDir, 'music21.egg-info', 'SOURCES.txt')
246-
# else:
247-
# raise Exception('invalid mode')
248-
249-
# elif mode == EGG:
250-
# sourcesTxt = os.path.join(fpDstDir, 'EGG-INFO', 'SOURCES.txt')
251-
252-
# files will look like 'music21/corpus/haydn' in SOURCES.txt
253-
post = []
254-
f = open(sourcesTxt, 'r')
255-
corpusContentDirs = common.getCorpusContentDirs()
256-
for line in f:
257-
match = False
258-
if 'corpus' in line:
259-
for fn in corpusContentDirs:
260-
# these are relative paths
261-
fp = os.path.join('music21', 'corpus', fn)
262-
if line.startswith(fp):
263-
match = True
264-
break
265-
if not match:
266-
post.append(line)
267-
f.close()
268-
f = open(sourcesTxt, 'w')
269-
f.writelines(post)
270-
f.close()
271-
272-
if mode == TAR:
273-
# compress dst dir to dst file path name
274-
# need the -C flag to set relative dir
275-
# just name of dir
276-
cmd = f'tar -C {fpDir} -czf {fpDst} {fnDstDir}/'
277-
os.system(cmd)
278-
279-
# remove directory that was compressed
280-
if os.path.exists(fpDstDir):
281-
shutil.rmtree(fpDstDir)
282-
283-
return fpDst # full path with extension
284-
285-
286-
287-
def build(self):
288-
'''
289-
Build all distributions. Update and rename file paths if necessary;
290-
remove extract build products.
291-
'''
292-
# call setup.py
293-
# import setup # -- for some reason does not work unless called from command line
294-
for buildType in ['sdist --formats=gztar', 'bdist_wheel']:
295-
environLocal.warn(f'making {buildType}')
296-
297-
savePath = os.getcwd()
298-
os.chdir(self.fpPackageDir)
299-
os.system(f'{PY} setup.py {buildType}')
300-
os.chdir(savePath)
301-
302-
self.updatePaths()
303-
304-
environLocal.warn(f'removing {self.fpBuildDir} (except on windows...there do it yourself)')
305-
try:
306-
shutil.rmtree(self.fpBuildDir)
307-
except FileNotFoundError:
308-
environLocal.warn(
309-
'Directory was already cleaned up'
310-
)
311-
312-
if self.buildNoCorpus is True:
313-
# create no corpus versions
314-
self.fpTarNoCorpus = self.removeCorpus(fp=self.fpTar)
315-
# self.fpEggNoCorpus = self.removeCorpus(fp=self.fpEgg)
316-
317-
318-
def md5ForFile(self, path, hexReturn=True):
319-
if hexReturn:
320-
return hashlib.md5(open(path, 'rb').read()).hexdigest()
321-
else:
322-
return hashlib.md5(open(path, 'rb').read()).digest()
128+
fp = os.path.join(fpDstDir, 'music21', 'corpus', '_metadataCache')
129+
shutil.rmtree(fp)
130+
131+
# compress dst dir to dst file path name
132+
# need the -C flag to set relative dir
133+
# just name of dir
134+
cmd = f'tar -C {fpDir} -czf {fpDst} {fnDstDir}/'
135+
os.system(cmd)
136+
137+
# # remove directory that was compressed
138+
if os.path.exists(fpDstDir):
139+
shutil.rmtree(fpDstDir)
140+
141+
return fpDst # full path with extension
323142

324143

325144
# ------------------------------------------------------------------------------
326145
if __name__ == '__main__':
327-
d = Distributor()
328-
d.buildNoCorpus = True
329-
d.build()
330-
d.updatePaths()
331-
# d.getMD5Path()
332-
# d.uploadPyPi()
146+
removeCorpus()

music21/_version.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,25 @@
4141
Changing this number invalidates old pickles -- do it if the old pickles create a problem.
4242
'''
4343

44-
__version_info__ = (8, 0, 0, 'rc1') # can be 3-tuple or 4+-tuple: (7, 0, 5, 'a2')
44+
def get_version_tuple(vv):
45+
v = vv.split('.')
46+
last_v = v[-1]
47+
v[-1] = ''
48+
beta = ''
49+
in_patch = True
50+
for ch in last_v:
51+
if in_patch and ch.isdigit():
52+
v[-1] += ch
53+
else:
54+
in_patch = False
55+
beta += ch
56+
if beta:
57+
v.append(beta)
58+
return tuple(v)
4559

46-
v = '.'.join(str(x) for x in __version_info__[0:3])
47-
if len(__version_info__) > 3 and __version_info__[3]: # type: ignore
48-
v += __version_info__[3] # type: ignore
49-
if len(__version_info__) > 4:
50-
v += '.' + '.'.join(__version_info__[4:])
5160

52-
__version__ = v
61+
__version__ = '8.0.0rc2'
5362

54-
del v
63+
__version_info__ = get_version_tuple(__version__)
64+
65+
del get_version_tuple

music21/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<class 'music21.base.Music21Object'>
2929
3030
>>> music21.VERSION_STR
31-
'8.0.0rc1'
31+
'8.0.0rc2'
3232
3333
Alternatively, after doing a complete import, these classes are available
3434
under the module "base":

0 commit comments

Comments
 (0)