This commit is contained in:
Kovid Goyal 2017-05-07 17:50:44 +05:30
parent 1ac9562931
commit a7e7b0d381
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -12,6 +12,7 @@ from setup import Command, __version__, require_clean_git, require_git_master
from setup.upload import installers from setup.upload import installers
from setup.parallel_build import parallel_build from setup.parallel_build import parallel_build
class Stage1(Command): class Stage1(Command):
description = 'Stage 1 of the publish process' description = 'Stage 1 of the publish process'
@ -29,6 +30,7 @@ class Stage1(Command):
'gui', 'gui',
] ]
class Stage2(Command): class Stage2(Command):
description = 'Stage 2 of the publish process, builds the binaries' description = 'Stage 2 of the publish process, builds the binaries'
@ -44,6 +46,7 @@ class Stage2(Command):
tdir = tempfile.mkdtemp('_build_logs') tdir = tempfile.mkdtemp('_build_logs')
atexit.register(shutil.rmtree, tdir) atexit.register(shutil.rmtree, tdir)
self.info('Starting builds for all platforms, this will take a while...') self.info('Starting builds for all platforms, this will take a while...')
def kill_child_on_parent_death(): def kill_child_on_parent_death():
import ctypes, signal import ctypes, signal
libc = ctypes.CDLL("libc.so.6") libc = ctypes.CDLL("libc.so.6")
@ -51,8 +54,11 @@ class Stage2(Command):
for x in ('linux', 'osx', 'win'): for x in ('linux', 'osx', 'win'):
r, w = pipe() r, w = pipe()
p = subprocess.Popen([sys.executable, 'setup.py', x], stdout=w, stderr=subprocess.STDOUT, p = subprocess.Popen([sys.executable, 'setup.py', x],
cwd=self.d(self.SRC), preexec_fn=kill_child_on_parent_death) stdout=w,
stderr=subprocess.STDOUT,
cwd=self.d(self.SRC),
preexec_fn=kill_child_on_parent_death)
p.log, p.start_time, p.bname = r, time.time(), x p.log, p.start_time, p.bname = r, time.time(), x
p.save = open(os.path.join(tdir, x), 'w+b') p.save = open(os.path.join(tdir, x), 'w+b')
p.duration = None p.duration = None
@ -69,11 +75,12 @@ class Stage2(Command):
running = True running = True
return running return running
stop_multitail = multitail( stop_multitail = multitail([proc.log for proc in processes],
[proc.log for proc in processes], name_map={
name_map={proc.log:proc.bname for proc in processes}, proc.log: proc.bname
copy_to=[proc.save for proc in processes] for proc in processes
)[0] },
copy_to=[proc.save for proc in processes])[0]
while workers_running(): while workers_running():
os.waitpid(-1, 0) os.waitpid(-1, 0)
@ -94,23 +101,31 @@ class Stage2(Command):
if failed: if failed:
raise SystemExit('Building of installers failed!') raise SystemExit('Building of installers failed!')
for p in sorted(processes, key=lambda p:p.duration): for p in sorted(processes, key=lambda p: p.duration):
self.info('Built %s in %d minutes and %d seconds' % (p.bname, p.duration // 60, p.duration % 60)) self.info(
'Built %s in %d minutes and %d seconds' %
(p.bname, p.duration // 60, p.duration % 60)
)
for installer in installers(include_source=False): for installer in installers(include_source=False):
if not os.path.exists(self.j(self.d(self.SRC), installer)): if not os.path.exists(self.j(self.d(self.SRC), installer)):
raise SystemExit('The installer %s does not exist' % os.path.basename(installer)) raise SystemExit(
'The installer %s does not exist' % os.path.basename(installer)
)
class Stage3(Command): class Stage3(Command):
description = 'Stage 3 of the publish process' description = 'Stage 3 of the publish process'
sub_commands = ['upload_user_manual', 'upload_demo', 'sdist', 'tag_release'] sub_commands = ['upload_user_manual', 'upload_demo', 'sdist', 'tag_release']
class Stage4(Command): class Stage4(Command):
description = 'Stage 4 of the publish process' description = 'Stage 4 of the publish process'
sub_commands = ['upload_installers'] sub_commands = ['upload_installers']
class Stage5(Command): class Stage5(Command):
description = 'Stage 5 of the publish process' description = 'Stage 5 of the publish process'
@ -119,15 +134,23 @@ class Stage5(Command):
def run(self, opts): def run(self, opts):
subprocess.check_call('rm -rf build/* dist/*', shell=True) subprocess.check_call('rm -rf build/* dist/*', shell=True)
class Publish(Command): class Publish(Command):
description = 'Publish a new calibre release' description = 'Publish a new calibre release'
sub_commands = ['stage1', 'stage2', 'stage3', 'stage4', 'stage5', ] sub_commands = [
'stage1',
'stage2',
'stage3',
'stage4',
'stage5',
]
def pre_sub_commands(self, opts): def pre_sub_commands(self, opts):
require_git_master() require_git_master()
require_clean_git() require_clean_git()
class PublishBetas(Command): class PublishBetas(Command):
sub_commands = ['stage2', 'sdist'] sub_commands = ['stage2', 'sdist']
@ -137,18 +160,32 @@ class PublishBetas(Command):
def run(self, opts): def run(self, opts):
dist = self.a(self.j(self.d(self.SRC), 'dist')) dist = self.a(self.j(self.d(self.SRC), 'dist'))
subprocess.check_call( subprocess.check_call((
('rsync --partial -rh --progress --delete-after %s/ download.calibre-ebook.com:/srv/download/betas/' % dist).split()) 'rsync --partial -rh --progress --delete-after %s/ download.calibre-ebook.com:/srv/download/betas/'
% dist
).split())
class Manual(Command): class Manual(Command):
description='''Build the User Manual ''' description = '''Build the User Manual '''
def add_options(self, parser): def add_options(self, parser):
parser.add_option('-l', '--language', action='append', default=[], parser.add_option(
help='Build translated versions for only the specified languages (can be specified multiple times)') '-l',
parser.add_option('--serve', action='store_true', default=False, '--language',
help='Run a webserver on the built manual files') action='append',
default=[],
help=(
'Build translated versions for only the specified languages (can be specified multiple times)'
)
)
parser.add_option(
'--serve',
action='store_true',
default=False,
help='Run a webserver on the built manual files'
)
def run(self, opts): def run(self, opts):
tdir = self.j(tempfile.gettempdir(), 'user-manual-build') tdir = self.j(tempfile.gettempdir(), 'user-manual-build')
@ -163,13 +200,16 @@ class Manual(Command):
shutil.rmtree(d) shutil.rmtree(d)
os.makedirs(d) os.makedirs(d)
jobs = [] jobs = []
languages = opts.language or list(json.load(open(self.j(base, 'locale', 'completed.json'), 'rb'))) languages = opts.language or list(
json.load(open(self.j(base, 'locale', 'completed.json'), 'rb'))
)
languages = ['en'] + list(set(languages) - {'en'}) languages = ['en'] + list(set(languages) - {'en'})
os.environ['ALL_USER_MANUAL_LANGUAGES'] = ' '.join(languages) os.environ['ALL_USER_MANUAL_LANGUAGES'] = ' '.join(languages)
for language in languages: for language in languages:
jobs.append((['calibre-debug', self.j(self.d(self.SRC), 'manual', 'build.py'), '--', jobs.append(([
language, self.j(tdir, language)], 'calibre-debug', self.j(self.d(self.SRC), 'manual', 'build.py'),
'\n\n**************** Building translations for: %s'%language)) '--', language, self.j(tdir, language)
], '\n\n**************** Building translations for: %s' % language))
self.info('Building manual for %d languages' % len(jobs)) self.info('Building manual for %d languages' % len(jobs))
if not parallel_build(jobs, self.info): if not parallel_build(jobs, self.info):
raise SystemExit(1) raise SystemExit(1)
@ -182,7 +222,10 @@ class Manual(Command):
self.replace_with_symlinks(x) self.replace_with_symlinks(x)
else: else:
os.symlink('..', 'en') os.symlink('..', 'en')
self.info('Built manual for %d languages in %s minutes' % (len(jobs), int((time.time() - st)/60.))) self.info(
'Built manual for %d languages in %s minutes' %
(len(jobs), int((time.time() - st) / 60.))
)
finally: finally:
os.chdir(cwd) os.chdir(cwd)
@ -201,7 +244,7 @@ class Manual(Command):
HandlerClass.protocol_version = Protocol HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass) httpd = ServerClass(server_address, HandlerClass)
print ("Serving User Manual on localhost:8000") print("Serving User Manual on localhost:8000")
from calibre.gui2 import open_url from calibre.gui2 import open_url
open_url('http://localhost:8000') open_url('http://localhost:8000')
httpd.serve_forever() httpd.serve_forever()
@ -226,11 +269,14 @@ class Manual(Command):
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) shutil.rmtree(path)
class TagRelease(Command): class TagRelease(Command):
description = 'Tag a new release in git' description = 'Tag a new release in git'
def run(self, opts): def run(self, opts):
self.info('Tagging release') self.info('Tagging release')
subprocess.check_call('git tag -s v{0} -m "version-{0}"'.format(__version__).split()) subprocess.check_call(
'git tag -s v{0} -m "version-{0}"'.format(__version__).split()
)
subprocess.check_call('git push origin v{0}'.format(__version__).split()) subprocess.check_call('git push origin v{0}'.format(__version__).split())