Commit 114bf10d authored by Joseph Weston's avatar Joseph Weston
Browse files

Merge branch 'feature/version' into 'master'

set zesje version from Git tags

See merge request zesje/zesje!95
parents bc0bfa5b ba2e41a5
zesje/_static_version.py export-subst
\ No newline at end of file
......@@ -73,6 +73,9 @@ zesje/static/
# Python temporary files
__pycache__/
*.pyc
*.egg-info
dist/
build/
# pytest temporary files
.pytest_cache/
......
......@@ -20,7 +20,7 @@ build:
<<: *node_modules
stage: build
script:
- python -m compileall zesje
- python3 -m compileall zesje
- yarn build
artifacts:
paths:
......
include-recursive zesje/static/*
include LICENSE
recursive-include zesje/static *
......@@ -181,7 +181,7 @@ class NavBar extends React.Component {
: <Link className='navbar-item' to='/graders'>Add grader</Link>
}
<div className='navbar-item'>
<i>Version {__COMMIT_HASH__}</i>
<i>Version {__ZESJE_VERSION__}</i>
</div>
</div>
</div>
......
......@@ -11,14 +11,14 @@
"lint:js": "standard --verbose | snazzy",
"test:js": "jest",
"lint:py": "flake8",
"test:py": "python -m pytest -v -W error::RuntimeWarning",
"test:py": "python3 -m pytest -v -W error::RuntimeWarning",
"start": "ZESJE_SETTINGS=$(pwd)/zesje.dev.cfg python3 zesje",
"analyze": "webpack --config webpack.prod.js --profile --json > stats.json; webpack-bundle-analyzer stats.json zesje/static"
},
"standard": {
"parser": "babel-eslint",
"globals": [
"__COMMIT_HASH__",
"__ZESJE_VERSION__",
"alert",
"confirm"
]
......
......@@ -3,30 +3,49 @@
import sys
from setuptools import setup, find_packages
from setuptools.command.sdist import sdist as sdist_orig
if sys.version_info < (3, 6):
print('zesje requires Python 3.6 or higher')
sys.exit(1)
class sdist(sdist_orig):
# Loads version.py module without importing the whole package.
def get_version_and_cmdclass(package_path):
import os
from importlib.util import module_from_spec, spec_from_file_location
spec = spec_from_file_location('version',
os.path.join(package_path, '_version.py'))
module = module_from_spec(spec)
spec.loader.exec_module(module)
return module.__version__, module.cmdclass
version, cmdclass = get_version_and_cmdclass('zesje')
# will be replaced by the overriding classes below
_sdist = cmdclass.pop('sdist')
class sdist(_sdist):
def run(self):
import subprocess
subprocess.check_call(['rm', '-r', 'zesje/static'])
subprocess.check_call(['yarn', 'install'])
subprocess.check_call(['yarn', 'build'])
super().run()
cmdclass['sdist'] = sdist
setup(
name="zesje",
version="0.1a",
version=version,
url="http://gitlab.kwant-project,org/zesje/zesje",
description="",
author="Zesje authors",
author_email="anton.akhmerov@tudelft.nl",
packages=find_packages('.'),
cmdclass=dict(sdist=sdist),
cmdclass=cmdclass,
package_data={'zesje': ['static/*']},
include_package_data=True,
)
......@@ -2,6 +2,7 @@
./webpack.config.js
*/
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
......@@ -11,6 +12,11 @@ const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
inject: 'body'
})
const zesjeVersion = require('child_process')
.execSync('python3 zesje/_version.py')
.toString()
.trim()
module.exports = {
entry: './client/index.jsx',
output: {
......@@ -28,5 +34,10 @@ module.exports = {
]
},
plugins: [HtmlWebpackPluginConfig]
plugins: [
HtmlWebpackPluginConfig,
new webpack.DefinePlugin({
__ZESJE_VERSION__: JSON.stringify(zesjeVersion)
})
]
}
......@@ -2,11 +2,6 @@ const webpack = require('webpack')
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const commitHash = require('child_process')
.execSync('git rev-parse --short HEAD')
.toString()
.trim()
module.exports = merge(common, {
mode: 'development',
module: {
......@@ -34,9 +29,6 @@ module.exports = merge(common, {
plugins: [
new webpack.EvalSourceMapDevToolPlugin({
sourceURLTemplate: module => `/${module.identifier}`
}),
new webpack.DefinePlugin({
__COMMIT_HASH__: JSON.stringify(commitHash + '-dev')
})
]
})
......@@ -5,11 +5,6 @@ const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const common = require('./webpack.common.js')
const commitHash = require('child_process')
.execSync('git rev-parse --short HEAD')
.toString()
.trim()
module.exports = merge(common, {
mode: 'production',
......@@ -41,9 +36,6 @@ module.exports = merge(common, {
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
}),
new webpack.DefinePlugin({
__COMMIT_HASH__: JSON.stringify(commitHash + '-prod')
})
]
})
......@@ -9,8 +9,11 @@ from werkzeug.exceptions import NotFound
from .api import api_bp
from .database import db
from ._version import __version__
__all__ = ['__version__', 'app']
STATIC_FOLDER_PATH = os.path.join(abspath(dirname(__file__)), 'static')
app = Flask(__name__, static_folder=STATIC_FOLDER_PATH)
......
# -*- coding: utf-8 -*-
# This file is part of 'miniver': https://github.com/jbweston/miniver
#
# This file will be overwritten by setup.py when a source or binary
# distribution is made. The magic value "__use_git__" is interpreted by
# version.py.
version = "__use_git__"
# These values are only set if the distribution was created with 'git archive'
refnames = "$Format:%D$"
git_hash = "$Format:%h$"
# -*- coding: utf-8 -*-
# This file is part of 'miniver': https://github.com/jbweston/miniver
#
from collections import namedtuple
import os
import subprocess
from distutils.command.build_py import build_py as build_py_orig
from setuptools.command.sdist import sdist as sdist_orig
Version = namedtuple('Version', ('release', 'dev', 'labels'))
# No public API
__all__ = []
package_root = os.path.dirname(os.path.realpath(__file__))
package_name = os.path.basename(package_root)
distr_root = os.path.dirname(package_root)
STATIC_VERSION_FILE = '_static_version.py'
def get_version(version_file=STATIC_VERSION_FILE):
version_info = {}
with open(os.path.join(package_root, version_file), 'rb') as f:
exec(f.read(), {}, version_info)
version = version_info['version']
if version == "__use_git__":
version = get_version_from_git()
if not version:
version = get_version_from_git_archive(version_info)
if not version:
version = Version("unknown", None, None)
return pep440_format(version)
else:
return version
def pep440_format(version_info):
release, dev, labels = version_info
version_parts = [release]
if dev:
if release.endswith('-dev') or release.endswith('.dev'):
version_parts.append(dev)
else: # prefer PEP440 over stric adhesion to semver
version_parts.append('.dev{}'.format(dev))
if labels:
version_parts.append('+')
version_parts.append(".".join(labels))
return "".join(version_parts)
def get_version_from_git():
try:
p = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'],
cwd=distr_root,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError:
return
if p.wait() != 0:
return
if not os.path.samefile(p.communicate()[0].decode().rstrip('\n'),
distr_root):
# The top-level directory of the current Git repository is not the same
# as the root directory of the distribution: do not extract the
# version from Git.
return
# git describe --first-parent does not take into account tags from branches
# that were merged-in.
for opts in [['--first-parent'], []]:
try:
p = subprocess.Popen(['git', 'describe', '--long'] + opts,
cwd=distr_root,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError:
return
if p.wait() == 0:
break
else:
return
description = p.communicate()[0].decode().strip('v').rstrip('\n')
release, dev, git = description.rsplit('-', 2)
labels = []
if dev == "0":
dev = None
else:
labels.append(git)
try:
p = subprocess.Popen(['git', 'diff', '--quiet'], cwd=distr_root)
except OSError:
labels.append('confused') # This should never happen.
else:
if p.wait() == 1:
labels.append('dirty')
return Version(release, dev, labels)
# TODO: change this logic when there is a git pretty-format
# that gives the same output as 'git describe'.
# Currently we can only tell the tag the current commit is
# pointing to, or its hash (with no version info)
# if it is not tagged.
def get_version_from_git_archive(version_info):
try:
refnames = version_info['refnames']
git_hash = version_info['git_hash']
except KeyError:
# These fields are not present if we are running from an sdist.
# Execution should never reach here, though
return None
if git_hash.startswith('$Format') or refnames.startswith('$Format'):
# variables not expanded during 'git archive'
return None
VTAG = 'tag: v'
refs = set(r.strip() for r in refnames.split(","))
version_tags = set(r[len(VTAG):] for r in refs if r.startswith(VTAG))
if version_tags:
release, *_ = sorted(version_tags) # prefer e.g. "2.0" over "2.0rc1"
return Version(release, dev=None, labels=None)
else:
return Version('unknown', dev=None, labels=['g{}'.format(git_hash)])
__version__ = get_version()
# The following section defines a module global 'cmdclass',
# which can be used from setup.py. The 'package_name' and
# '__version__' module globals are used (but not modified).
def _write_version(fname):
# This could be a hard link, so try to delete it first. Is there any way
# to do this atomically together with opening?
try:
os.remove(fname)
except OSError:
pass
with open(fname, 'w') as f:
f.write("# This file has been created by setup.py.\n"
"version = '{}'\n".format(__version__))
class _build_py(build_py_orig):
def run(self):
super().run()
_write_version(os.path.join(self.build_lib, package_name,
STATIC_VERSION_FILE))
class _sdist(sdist_orig):
def make_release_tree(self, base_dir, files):
super().make_release_tree(base_dir, files)
_write_version(os.path.join(base_dir, package_name,
STATIC_VERSION_FILE))
cmdclass = dict(sdist=_sdist, build_py=_build_py)
if __name__ == '__main__':
print(__version__)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment