-
-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add miniver to simplify development branch descriptions #726
Changes from all commits
20d06df
31dbaa7
100c010
a2ee49c
5881ebd
92e9d93
9101813
d75002c
b461e11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# -*- coding: utf-8 -*- | ||
# This file is part of 'miniver': https://github.com/jbweston/miniver | ||
# | ||
from collections import namedtuple | ||
import os | ||
|
||
Version = namedtuple("Version", ("release", "post", "labels")) | ||
|
||
# No public API | ||
__all__ = [] | ||
|
||
package_root = os.path.dirname(os.path.realpath(__file__)) | ||
package_name = os.path.basename(package_root) | ||
STATIC_VERSION_FILE = "_static_version.py" | ||
|
||
|
||
def get_version(): | ||
version = get_version_from_git() | ||
if not version: | ||
version = Version("unknown", None, None) | ||
return pep440_format(version) | ||
|
||
|
||
def pep440_format(version_info): | ||
release, post, labels = version_info | ||
|
||
version_parts = [release] | ||
if post: | ||
if release.endswith("-post") or release.endswith(".post"): | ||
version_parts.append(post) | ||
else: # prefer PEP440 over strict adhesion to semver | ||
version_parts.append(".post{}".format(post)) | ||
|
||
if labels: | ||
version_parts.append("+") | ||
version_parts.append(".".join(labels)) | ||
|
||
return "".join(version_parts) | ||
|
||
|
||
def get_version_from_git(): | ||
import subprocess | ||
|
||
# git describe --first-parent does not take into account tags from branches | ||
# that were merged-in. The '--long' flag gets us the 'post' version and | ||
# git hash, '--always' returns the git hash even if there are no tags. | ||
for opts in [["--first-parent"], []]: | ||
try: | ||
p = subprocess.Popen( | ||
["git", "describe", "--long", "--always", "--tags", "--dirty"] + opts, | ||
Comment on lines
+49
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC this means that if someone obtains pygfx in another way than via a package manager or git repo, the version cannot be established. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. There become some "edge cases" that you have to start taking into account when people "receive" the source code. I just checked my project for example, the version downloaded from pypi burns things in due to the modifications to the setup.py but the archive from github would make it pretty difficult for people to use. |
||
cwd=package_root, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
) | ||
except OSError: | ||
return | ||
if p.wait() == 0: | ||
break | ||
else: | ||
return | ||
|
||
description = ( | ||
p.communicate()[0] | ||
.decode() | ||
.lstrip("v") # Tags can have a leading 'v', but the version should not | ||
.rstrip("\n") | ||
.rsplit("-") # Split the latest tag, commits since tag, and hash, and dirty | ||
) | ||
|
||
try: | ||
release, post, git = description[:3] | ||
except ValueError: # No tags, only the git hash | ||
# prepend 'g' to match with format returned by 'git describe' | ||
git = "g{}".format(*description) | ||
release = "nodescription" | ||
post = None | ||
|
||
labels = [] | ||
if post == "0": | ||
post = None | ||
else: | ||
labels.append(git) | ||
|
||
if description[-1] == "dirty": | ||
labels.append("dirty") | ||
|
||
return Version(release, post, labels) | ||
|
||
|
||
__version__ = get_version() | ||
|
||
|
||
# The following section defines a 'get_cmdclass' function | ||
# that can be used from setup.py. The '__version__' module | ||
# global is 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(f"__version__ = '{__version__}'") | ||
|
||
|
||
def get_cmdclass(pkg_source_path): | ||
from setuptools.command.build_py import build_py as build_py_orig | ||
from setuptools.command.sdist import sdist as sdist_orig | ||
|
||
class _build_py(build_py_orig): # noqa | ||
def run(self): | ||
super().run() | ||
|
||
src_marker = "".join(["src", os.path.sep]) | ||
|
||
if pkg_source_path.startswith(src_marker): | ||
path = pkg_source_path[len(src_marker) :] | ||
else: | ||
path = pkg_source_path | ||
_write_version(os.path.join(self.build_lib, path, "_version.py")) | ||
|
||
class _sdist(sdist_orig): # noqa | ||
def make_release_tree(self, base_dir, files): | ||
super().make_release_tree(base_dir, files) | ||
_write_version(os.path.join(base_dir, pkg_source_path, "_version.py")) | ||
|
||
return dict(sdist=_sdist, build_py=_build_py) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what behavior you want from this
version_info
tuple. I don't have such constructs in my code.I typically use
for all my comparisons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do this: