Commit e12ae297 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Copy the last version of the command build_version from track_publications.

parent 080eb26c
......@@ -19,6 +19,7 @@ private/
*plugin_extjs*
*plugin_mathjax*
sessions/
static/*-debug.js
static/*-min.js
static/docs/
uploads/
......@@ -2,41 +2,31 @@
# -*- coding: utf-8 -*-
"""
NAME
build_version -- helper script to build and tag a track_event release
build_version -- build and tag a track_publications version
SYNOPSIS
build_version [options]
DESCRIPTION
Helper script to build a release of the track_event application.
The release identifier should contains alphanumeric characters
including ".", "-" and "_".
Edit release identifier in the CHANGELOG.
Build debug and minified version of the javascript library.
Start the cycle for the release candidate in the master branch.
Tag the release in the production branch.
Build the documentation.
Helper script to build a version of the track_publications.
Push version number in the CHANGELOG.
EXAMPLES
> build_version -h
AUTHOR
R. Le Gac, legac@cppm.in2p3.fr
R. Le Gac, renaud.legac@cppm.in2p3.fr
Copyright (c) 2012-2015 R. Le Gac
"""
import argparse
import datetime
import optparse
import os
import re
import sys
import tempfile
import urllib
from os.path import join as opj
......@@ -46,29 +36,26 @@ from subprocess import call
APP = os.path.basename(os.getcwd())
API = 'api'
CHANGELOG = 'static/CHANGELOG'
DBUIJSSRC = 'static/plugin_dbui/src'
DBUISRC = 'static/plugin_dbui/src'
DOCS = 'static/docs'
DOCSRC = 'docs'
EXTJSSRC = 'static/plugin_extjs/src'
JSDOC = opj(DOCS, 'jsduck')
JSLIBDEBUG = 'static/%s-debug.js' % APP
JSLIBMIN = 'static/%s-min.js' % APP
JSLIBSRC = 'static/src'
JSLIBSRC = 'static/%s/src' % APP
LATEX = 'latex'
LATEXDOC = opj(DOCS, LATEX)
NOW = datetime.datetime.now()
PDF = "pdf"
PDFDOC = opj(DOCS, PDF)
PYDOC = opj(DOCS, 'epydoc')
REFERENCE = 'reference'
USER = 'user'
# basic commands
EPYDOC = '/usr/bin/epydoc'
GIT = '/usr/bin/git'
JSDUCK = os.path.expandvars("$HOME/bin/jsduck")
PDFLATEX = '/usr/bin/pdflatex'
SENCHA = os.path.expandvars("$HOME/bin/sencha")
SENCHA = os.path.expandvars("$HOME/lib/Sencha/Cmd/latest/sencha")
SPHINX = '/usr/bin/sphinx-build'
MSG_RELEASE = 'Enter the new release: '
......@@ -81,7 +68,7 @@ def build():
compile_js()
build_html()
for doc in (API, REFERENCE, USER):
for doc in (USER,):
docsrc = opj(DOCSRC, doc)
if os.path.exists(docsrc):
......@@ -108,10 +95,6 @@ def build_html():
if os.path.exists(docsrc):
sphinx("-b html", docsrc, opj(DOCS, doc))
# build epydoc documentation if API not defined
if not os.path.exists(opj(DOCSRC, API)):
epydoc()
def build_pdf(doc):
""" Build PDF documentations...
......@@ -122,73 +105,75 @@ def build_pdf(doc):
"""
print "Build the PDF documentations..."
latexdoc = opj(DOCS, LATEX)
# generate the latex
sphinx("-b latex", opj(DOCSRC, doc), LATEXDOC)
sphinx("-b latex", opj(DOCSRC, doc), latexdoc)
# the current directory
cwd = os.getcwd()
# find the name of the tex file
os.chdir(LATEXDOC)
li = [el for el in os.listdir('.') if el.endswith('.tex')]
fn = (li[0] if len(li) == 1 else None)
os.chdir(latexdoc)
filenames = [el for el in os.listdir('.') if el.endswith('.tex')]
filename = (filenames[0] if len(filenames) == 1 else None)
if not fn:
if not filename:
print "\n\tNo latex file !"
return
# process the latex file twice
call([PDFLATEX, fn])
call([PDFLATEX, fn])
call([PDFLATEX, filename])
call([PDFLATEX, filename])
# move the pdf file
os.chdir(cwd)
if not os.path.exists(PDFDOC):
os.mkdir(PDFDOC)
fin = fn.replace('.tex', '.pdf')
fout = "%s_%s.pdf" % (os.path.splitext(fn)[0], doc)
os.rename(opj(LATEXDOC, fin), opj(PDFDOC, fout))
pdfdir = opj(DOCS, PDF)
if not os.path.exists(pdfdir):
os.mkdir(pdfdir)
fin = filename.replace('.tex', '.pdf')
fout = "%s_%s.pdf" % (os.path.splitext(filename)[0], doc)
os.rename(opj(latexdoc, fin), opj(pdfdir, fout))
# remove the latex directory
call(["rm", "-rf", LATEXDOC])
call(["rm", "-rf", latexdoc])
print "%s documentation in" % fout, PDFDOC
print "PDF documentation in", PDFDOC
def commit_change_log():
"""Commit CHANGELOG and App.js.
def change_log():
"""Commit CHANGELOG.
"""
print "Commit CHANGELOG and App.js..."
print "Commit CHANGELOG..."
if not os.path.exists(GIT):
print '\n\tThe application git is missing !'
print '\tSkip this step.\n'
return
# move to the master branch
git("checkout master")
# Commit modified files
print 'git add', JSBASE, CHANGELOG
git("add", JSBASE, CHANGELOG)
print 'git add', CHANGELOG
git("add", CHANGELOG)
print 'git commit'
msg = "Start release candidate %s" % get_version()
msg = "Start release %s" % get_version()
git("commit -m", msg)
def compile_js():
"""compile the javascript code and generate the minified version
of the application library.
"""compile_js the javascript code and generate the debug version
as well as the minified version.
The compiler verify that the code complied with the class model
and order the file in the proper way.
The minified library can be build in several ways, including
the Ext JS class required by the applications. In the
current version, the library contains only the application classes and
the Ext JS ones have to be loaded separately.
current version, the library contains only the dbui classes and
the Ext JS ones have to be loaded separately. In that sense
this command is very similar to the yuicompressor one.
Several compressor can be used yui, closure compiler, ....
In the current version, the default yui compressor is used?
......@@ -200,72 +185,56 @@ def compile_js():
http://docs.sencha.com/extjs/4.2.2/#!/guide/command
"""
print "Compile the javascript code ..."
if not os.path.exists(SENCHA):
print '\n\tThe application sencha is missing !'
print '\tSee: http://www.sencha.com/products/sencha-cmd/download'
print '\tSkip this step.\n'
return
# clean previous build
if os.path.exists(JSLIBMIN):
os.remove(JSLIBMIN)
# Minified version of the javascript library
print '\nMinified version of the javascript library', JSLIBMIN
if not os.path.exists(JSLIBSRC):
print 'No javascript library. Exit.'
return
cwd = os.getcwd()
# clean previous version
for item in (JSLIBDEBUG, JSLIBMIN):
if os.path.exists(item):
os.remove(item)
print 'Remove old javascript library', item
cmd = ["sencha", "-sdk", os.path.join(cwd, EXTJSSRC),
"compile", "-classpath", os.path.join(cwd, DBUIJSSRC),
"-classpath", os.path.join(cwd, JSLIBSRC),
"exclude", "--namespace", "Ext", "--namespace", "App",
"and", "concat", "--yui", os.path.join(cwd, JSLIBMIN)]
# debug version of the javascript library
cmd = ["sencha", "-sdk", EXTJSSRC,
"compile", "-classpath", "%s,%s" % (JSLIBSRC, DBUISRC),
"exclude", "--namespace", "Ext,App",
"and", "concat", JSLIBDEBUG]
call(cmd)
print 'Debug version of the javascript library', JSLIBDEBUG, 'is ready'
def epydoc():
"""Generate the epydoc documentation
The HTML files are located in static/docs/epydoc
"""
if not os.path.exists(EPYDOC):
print '\n\tThe application epydoc is missing !'
print '\tSkip this step.\n'
return
# create the directory
if not os.path.exists(PYDOC):
os.makedirs(PYDOC)
# Minified version of the javascript library
cmd = ["sencha", "-sdk", EXTJSSRC,
"compile", "-classpath", "%s,%s" % (JSLIBSRC, DBUISRC),
"exclude", "--namespace", "Ext,App",
"and", "concat", "--yui", JSLIBMIN]
# clean the directory
cmd = ["rm", "-rf", PYDOC]
call(cmd)
# run epydoc
cmd = [EPYDOC, "--docformat", "epytext",
"--html",
"--name", APP,
"-o", PYDOC,
"--parse-only",
"-v",
"modules/*.py"]
print 'Minified version of the javascript library', JSLIBMIN, 'is ready'
call(cmd)
print "EPYDOC documentation in", PYDOC
def get_version():
"""Get the current version identifier.
It is searched in the CHANGELOG file
"""Get the current version identifier in the CHANGELOG
Returns:
str: the version number
"""
log = open(CHANGELOG).read()
# search pattern like 0.5.0 or 0.5.0 - 0.5.1
match = re.search(r"(\w+\.\w+(\.\w+)?)( *- *(\w+\.\w+(\.\w+)?))?", log)
match = re.search(r"(\d+\.\d+(\.\d+)*)", log)
if match:
return (match.group(4) if match.group(4) else match.group(1))
return match.group(1)
return ""
......@@ -310,6 +279,10 @@ def jsduck():
print '\tSkip this step.\n'
return
if not os.path.exists(JSLIBSRC):
print 'No javascript library. Exit.'
return
# create the directory
if not os.path.exists(JSDOC):
os.makedirs(JSDOC)
......@@ -336,20 +309,20 @@ def set_version(version):
version (str): release identifier
"""
print "Update CHANGELOG with the release identifier", version, "..."
print "Update CHANGELOG with the release", version, "..."
# check tag in git
fi = tempfile.TemporaryFile()
git("tag", stdout=fi)
fichier = tempfile.TemporaryFile()
git("tag", stdout=fichier)
fi.seek(0)
if version in fi.read():
fichier.seek(0)
if version in fichier.read():
print "\n\tRelease %s already exit in git" % version
sys.exit(1)
# look for a pattern HEAD in the CHANGELOG
# split the the string in 2 parts (pre HEAD, post HEAD)
print 'Set release identifier', version, 'in', CHANGELOG
print 'Set release', version, 'in', CHANGELOG
txt = open(CHANGELOG, 'rb').read()
match = re.match("(.+HEAD\n)(.*)", txt, re.DOTALL)
......@@ -363,15 +336,15 @@ def set_version(version):
# update the version and edit the CHANGELOG
tpl = (match.group(1), version, NOW.strftime('%b %Y'), match.group(2))
txt = '%s\n%s (%s)\n%s' % tpl
fi = open(CHANGELOG, 'wb')
fi.write(txt)
fi.close()
fichier = open(CHANGELOG, 'wb')
fichier.write(txt)
fichier.close()
call(["vim", CHANGELOG])
# cleaning
fn = "%s~" % CHANGELOG
if os.path.exists(fn):
os.remove(fn)
filename = "%s~" % CHANGELOG
if os.path.exists(filename):
os.remove(filename)
def sphinx(*args, **kwargs):
......@@ -403,15 +376,12 @@ def sphinx(*args, **kwargs):
def start_release():
"""Start the release cycle in the master branch.
Set the new release number in the CHANGELOG and App.js files.
Commit then in the master branch.
"""Start the release cycle.
"""
print "Start the release cycle..."
git("checkout master")
git("checkout", "master")
old_release = get_version()
print "Current release is", old_release
......@@ -421,182 +391,114 @@ def start_release():
sys.exit(0)
set_version(new_release)
commit_change_log()
change_log()
build()
def tag():
"""Tag the release in the production branch, locally and on the
remote repository.
"""
print "Tag the release...",
# move to production branch
git("checkout", "production")
# annotated tag
version = get_version()
print 'git tag', version
msg = "Tag %s" % version
git("tag", "-a", version, "-m", msg)
# push the tag on the server
git("push --tags")
if __name__ == '__main__':
# define script options
OPS = optparse.OptionParser()
OPS.add_option("-a", "--api-doc",
action="store_true",
dest="api_doc",
help="build the API documentation in HTML.")
OPS.add_option("-A", "--api-pdf",
action="store_true",
dest="api_pdf",
help="build the API documentation in PDF.")
OPS.add_option("-c", "--compile",
action="store_true",
dest="compile",
help="compile the javascript library specific "
"to the application.")
OPS.add_option("--commit-changelog",
action="store_true",
dest="changelog",
help="commit CHANGELOG in the master branch. "
"To be used with --write-release.")
OPS.add_option("-e", "--epydoc",
action="store_true",
dest="epydoc",
help="generate the epydoc documentation.")
OPS.add_option("-i", "--install",
action="store_true",
dest="install",
help="Build the javascript libraries specific to"
"the application as well as the documentation.")
OPS.add_option("-j", "--jsduck",
action="store_true",
dest="jsduck",
help="build the JavaScript documentation.")
OPS.add_option("-r", "--reference-doc",
action="store_true",
dest="reference_doc",
help="build the reference manual in HTML.")
OPS.add_option("-R", "--reference-pdf",
action="store_true",
dest="reference_pdf",
help="build the reference manual in PDF.")
OPS.add_option("-s", "--start-release",
action="store_true",
dest="start_release",
help="start the release candidate by setting "
"release number in change log and App.js. "
"Commit changes in the master branch. "
"Equivalent to --write-release followed by "
"--commit-changelog.")
OPS.add_option("-t", "--tag",
action="store_true",
dest="tag",
help="tag the release in the production branch "
"locally and on the remote repository.")
OPS.add_option("-u", "--user-doc",
action="store_true",
dest="user_doc",
help="build the user manual in HTML.")
OPS.add_option("-U", "--user-pdf",
action="store_true",
dest="user_pdf",
help="build the user manual in PDF.")
OPS.add_option("-v", "--version",
action="store_true",
dest="version",
help="get the current release identifier.")
OPS.add_option("--write-release",
action="store_true",
dest="release",
help="write the release number in CHANGELOG. "
"To be used with --commit-changelog.")
OPS.set_defaults(api_doc=False,
api_pdf=False,
changelog=False,
compile=False,
epydoc=False,
install=False,
jsduck=False,
reference_doc=False,
reference_pdf=False,
release=False,
start_release=False,
tag=False,
user_doc=False,
user_pdf=False,
version=False)
(OPT, ARGS) = OPS.parse_args()
if OPT.api_doc:
APS = argparse.ArgumentParser()
APS.add_argument("-a", "--api-doc",
action="store_true",
help="build the API documentation in HTML.")
APS.add_argument("-A", "--api-pdf",
action="store_true",
help="build the API documentation in PDF.")
APS.add_argument("-b", "--build",
action="store_true",
help="build the javascript library and the documentation.")
APS.add_argument("-c", "--compile",
action="store_true",
help="compile the javascript library.")
APS.add_argument("-C", "--commit-changelog",
action="store_true",
help="commit CHANGELOG. "
"To be used with --write-release. "
"Recommend to use --start-release.")
APS.add_argument("-j", "--jsduck",
action="store_true",
help="build the JavaScript documentation.")
APS.add_argument("-r", "--reference-doc",
action="store_true",
help="build the reference manual in HTML.")
APS.add_argument("-R", "--reference-pdf",
action="store_true",
help="build the reference manual in PDF.")
APS.add_argument("-s", "--start-release",
action="store_true",
help="start the new release cycle. "
"Set the release number in the changelog and "
"commit changes in the master branch. "
"Equivalent to --write-release followed by "
"--commit-changelog.")
APS.add_argument("-u", "--user-doc",
action="store_true",
help="build the user manual in HTML.")
APS.add_argument("-U", "--user-pdf",
action="store_true",
help="build the user manual in PDF.")
APS.add_argument("-v", "--version",
action="store_true",
help="get the current release identifier.")
APS.add_argument("-w", "--write-release",
action="store_true",
help="write the release number in CHANGELOG. "
"To be used with --commit-changelog. "
"Recommend to use --start-release.")
ARGS = APS.parse_args()
if ARGS.api_doc:
sphinx("-b html", opj(DOCSRC, API), opj(DOCS, API))
if OPT.api_pdf:
if ARGS.api_pdf:
build_pdf(API)
if OPT.compile:
compile_js()
if OPT.changelog:
commit_change_log()
if ARGS.build:
build()
if OPT.epydoc:
epydoc()
if ARGS.compile:
compile_js()
if OPT.install:
build()
if ARGS.commit_changelog:
change_log()
if OPT.jsduck:
if ARGS.jsduck:
jsduck()
if OPT.release:
if ARGS.write_release:
set_version(raw_input(MSG_RELEASE))
if OPT.reference_doc:
if ARGS.reference_doc:
sphinx("-b html", opj(DOCSRC, REFERENCE), opj(DOCS, REFERENCE))
if OPT.reference_pdf:
if ARGS.reference_pdf:
build_pdf(REFERENCE)