Ver código fonte

add versioneer

Christian Mönch 2 anos atrás
pai
commit
699b503b88

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+dataladmetadatamodel/_version.py export-subst

+ 2 - 0
MANIFEST.in

@@ -0,0 +1,2 @@
+include versioneer.py
+include dataladmetadatamodel/_version.py

+ 4 - 0
dataladmetadatamodel/__init__.py

@@ -25,3 +25,7 @@ def check_serialized_version(json_object: JSONObject):
             f"Unsupported metadata version ({stored_version}) in "
             f"Unsupported metadata version ({stored_version}) in "
             f"stored {stored_class} object, expected version: "
             f"stored {stored_class} object, expected version: "
             f"{version_string}")
             f"{version_string}")
+
+
+from . import _version
+__version__ = _version.get_versions()['version']

+ 162 - 59
dataladmetadatamodel/_version.py

@@ -6,7 +6,7 @@
 # that just contains the computed version number.
 # that just contains the computed version number.
 
 
 # This file is released into the public domain. Generated by
 # This file is released into the public domain. Generated by
-# versioneer-0.18 (https://github.com/warner/python-versioneer)
+# versioneer-0.20 (https://github.com/python-versioneer/python-versioneer)
 
 
 """Git implementation of _version.py."""
 """Git implementation of _version.py."""
 
 
@@ -30,7 +30,7 @@ def get_keywords():
     return keywords
     return keywords
 
 
 
 
-class VersioneerConfig:
+class VersioneerConfig:  # pylint: disable=too-few-public-methods
     """Container for Versioneer configuration parameters."""
     """Container for Versioneer configuration parameters."""
 
 
 
 
@@ -43,7 +43,7 @@ def get_config():
     cfg.style = "pep440"
     cfg.style = "pep440"
     cfg.tag_prefix = ""
     cfg.tag_prefix = ""
     cfg.parentdir_prefix = ""
     cfg.parentdir_prefix = ""
-    cfg.versionfile_source = "datalad_metalad/_version.py"
+    cfg.versionfile_source = "dataladmetadatamodel/_version.py"
     cfg.verbose = False
     cfg.verbose = False
     return cfg
     return cfg
 
 
@@ -57,7 +57,7 @@ HANDLERS = {}
 
 
 
 
 def register_vcs_handler(vcs, method):  # decorator
 def register_vcs_handler(vcs, method):  # decorator
-    """Decorator to mark a method as the handler for a particular VCS."""
+    """Create decorator to mark a method as the handler of a VCS."""
     def decorate(f):
     def decorate(f):
         """Store f in HANDLERS[vcs][method]."""
         """Store f in HANDLERS[vcs][method]."""
         if vcs not in HANDLERS:
         if vcs not in HANDLERS:
@@ -67,19 +67,20 @@ def register_vcs_handler(vcs, method):  # decorator
     return decorate
     return decorate
 
 
 
 
+# pylint:disable=too-many-arguments,consider-using-with # noqa
 def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
 def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
                 env=None):
                 env=None):
     """Call the given command(s)."""
     """Call the given command(s)."""
     assert isinstance(commands, list)
     assert isinstance(commands, list)
-    p = None
-    for c in commands:
+    process = None
+    for command in commands:
         try:
         try:
-            dispcmd = str([c] + args)
+            dispcmd = str([command] + args)
             # remember shell=False, so use git.cmd on windows, not just git
             # remember shell=False, so use git.cmd on windows, not just git
-            p = subprocess.Popen([c] + args, cwd=cwd, env=env,
-                                 stdout=subprocess.PIPE,
-                                 stderr=(subprocess.PIPE if hide_stderr
-                                         else None))
+            process = subprocess.Popen([command] + args, cwd=cwd, env=env,
+                                       stdout=subprocess.PIPE,
+                                       stderr=(subprocess.PIPE if hide_stderr
+                                               else None))
             break
             break
         except EnvironmentError:
         except EnvironmentError:
             e = sys.exc_info()[1]
             e = sys.exc_info()[1]
@@ -93,15 +94,13 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
         if verbose:
         if verbose:
             print("unable to find command, tried %s" % (commands,))
             print("unable to find command, tried %s" % (commands,))
         return None, None
         return None, None
-    stdout = p.communicate()[0].strip()
-    if sys.version_info[0] >= 3:
-        stdout = stdout.decode()
-    if p.returncode != 0:
+    stdout = process.communicate()[0].strip().decode()
+    if process.returncode != 0:
         if verbose:
         if verbose:
             print("unable to run %s (error)" % dispcmd)
             print("unable to run %s (error)" % dispcmd)
             print("stdout was %s" % stdout)
             print("stdout was %s" % stdout)
-        return None, p.returncode
-    return stdout, p.returncode
+        return None, process.returncode
+    return stdout, process.returncode
 
 
 
 
 def versions_from_parentdir(parentdir_prefix, root, verbose):
 def versions_from_parentdir(parentdir_prefix, root, verbose):
@@ -113,15 +112,14 @@ def versions_from_parentdir(parentdir_prefix, root, verbose):
     """
     """
     rootdirs = []
     rootdirs = []
 
 
-    for i in range(3):
+    for _ in range(3):
         dirname = os.path.basename(root)
         dirname = os.path.basename(root)
         if dirname.startswith(parentdir_prefix):
         if dirname.startswith(parentdir_prefix):
             return {"version": dirname[len(parentdir_prefix):],
             return {"version": dirname[len(parentdir_prefix):],
                     "full-revisionid": None,
                     "full-revisionid": None,
                     "dirty": False, "error": None, "date": None}
                     "dirty": False, "error": None, "date": None}
-        else:
-            rootdirs.append(root)
-            root = os.path.dirname(root)  # up a level
+        rootdirs.append(root)
+        root = os.path.dirname(root)  # up a level
 
 
     if verbose:
     if verbose:
         print("Tried directories %s but none started with prefix %s" %
         print("Tried directories %s but none started with prefix %s" %
@@ -138,21 +136,20 @@ def git_get_keywords(versionfile_abs):
     # _version.py.
     # _version.py.
     keywords = {}
     keywords = {}
     try:
     try:
-        f = open(versionfile_abs, "r")
-        for line in f.readlines():
-            if line.strip().startswith("git_refnames ="):
-                mo = re.search(r'=\s*"(.*)"', line)
-                if mo:
-                    keywords["refnames"] = mo.group(1)
-            if line.strip().startswith("git_full ="):
-                mo = re.search(r'=\s*"(.*)"', line)
-                if mo:
-                    keywords["full"] = mo.group(1)
-            if line.strip().startswith("git_date ="):
-                mo = re.search(r'=\s*"(.*)"', line)
-                if mo:
-                    keywords["date"] = mo.group(1)
-        f.close()
+        with open(versionfile_abs, "r") as fobj:
+            for line in fobj:
+                if line.strip().startswith("git_refnames ="):
+                    mo = re.search(r'=\s*"(.*)"', line)
+                    if mo:
+                        keywords["refnames"] = mo.group(1)
+                if line.strip().startswith("git_full ="):
+                    mo = re.search(r'=\s*"(.*)"', line)
+                    if mo:
+                        keywords["full"] = mo.group(1)
+                if line.strip().startswith("git_date ="):
+                    mo = re.search(r'=\s*"(.*)"', line)
+                    if mo:
+                        keywords["date"] = mo.group(1)
     except EnvironmentError:
     except EnvironmentError:
         pass
         pass
     return keywords
     return keywords
@@ -161,10 +158,14 @@ def git_get_keywords(versionfile_abs):
 @register_vcs_handler("git", "keywords")
 @register_vcs_handler("git", "keywords")
 def git_versions_from_keywords(keywords, tag_prefix, verbose):
 def git_versions_from_keywords(keywords, tag_prefix, verbose):
     """Get version information from git keywords."""
     """Get version information from git keywords."""
-    if not keywords:
-        raise NotThisMethod("no keywords at all, weird")
+    if "refnames" not in keywords:
+        raise NotThisMethod("Short version file found")
     date = keywords.get("date")
     date = keywords.get("date")
     if date is not None:
     if date is not None:
+        # Use only the last line.  Previous lines may contain GPG signature
+        # information.
+        date = date.splitlines()[-1]
+
         # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
         # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
         # datestamp. However we prefer "%ci" (which expands to an "ISO-8601
         # datestamp. However we prefer "%ci" (which expands to an "ISO-8601
         # -like" string, which we must then edit to make compliant), because
         # -like" string, which we must then edit to make compliant), because
@@ -177,11 +178,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
         if verbose:
         if verbose:
             print("keywords are unexpanded, not using")
             print("keywords are unexpanded, not using")
         raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
         raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
-    refs = set([r.strip() for r in refnames.strip("()").split(",")])
+    refs = {r.strip() for r in refnames.strip("()").split(",")}
     # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
     # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
     # just "foo-1.0". If we see a "tag: " prefix, prefer those.
     # just "foo-1.0". If we see a "tag: " prefix, prefer those.
     TAG = "tag: "
     TAG = "tag: "
-    tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
+    tags = {r[len(TAG):] for r in refs if r.startswith(TAG)}
     if not tags:
     if not tags:
         # Either we're using git < 1.8.3, or there really are no tags. We use
         # Either we're using git < 1.8.3, or there really are no tags. We use
         # a heuristic: assume all version tags have a digit. The old git %d
         # a heuristic: assume all version tags have a digit. The old git %d
@@ -190,7 +191,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
         # between branches and tags. By ignoring refnames without digits, we
         # between branches and tags. By ignoring refnames without digits, we
         # filter out many common branch names like "release" and
         # filter out many common branch names like "release" and
         # "stabilization", as well as "HEAD" and "master".
         # "stabilization", as well as "HEAD" and "master".
-        tags = set([r for r in refs if re.search(r'\d', r)])
+        tags = {r for r in refs if re.search(r'\d', r)}
         if verbose:
         if verbose:
             print("discarding '%s', no digits" % ",".join(refs - tags))
             print("discarding '%s', no digits" % ",".join(refs - tags))
     if verbose:
     if verbose:
@@ -199,6 +200,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
         # sorting will prefer e.g. "2.0" over "2.0rc1"
         # sorting will prefer e.g. "2.0" over "2.0rc1"
         if ref.startswith(tag_prefix):
         if ref.startswith(tag_prefix):
             r = ref[len(tag_prefix):]
             r = ref[len(tag_prefix):]
+            # Filter out refs that exactly match prefix or that don't start
+            # with a number once the prefix is stripped (mostly a concern
+            # when prefix is '')
+            if not re.match(r'\d', r):
+                continue
             if verbose:
             if verbose:
                 print("picking %s" % r)
                 print("picking %s" % r)
             return {"version": r,
             return {"version": r,
@@ -214,7 +220,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
 
 
 
 
 @register_vcs_handler("git", "pieces_from_vcs")
 @register_vcs_handler("git", "pieces_from_vcs")
-def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
+def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
     """Get version from 'git describe' in the root of the source tree.
     """Get version from 'git describe' in the root of the source tree.
 
 
     This only gets called if the git-archive 'subst' keywords were *not*
     This only gets called if the git-archive 'subst' keywords were *not*
@@ -225,8 +231,8 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
     if sys.platform == "win32":
     if sys.platform == "win32":
         GITS = ["git.cmd", "git.exe"]
         GITS = ["git.cmd", "git.exe"]
 
 
-    out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
-                          hide_stderr=True)
+    _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root,
+                   hide_stderr=True)
     if rc != 0:
     if rc != 0:
         if verbose:
         if verbose:
             print("Directory %s not under git control" % root)
             print("Directory %s not under git control" % root)
@@ -234,15 +240,15 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
 
 
     # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
     # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
     # if there isn't one, this yields HEX[-dirty] (no NUM)
     # if there isn't one, this yields HEX[-dirty] (no NUM)
-    describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty",
-                                          "--always", "--long",
-                                          "--match", "%s*" % tag_prefix],
-                                   cwd=root)
+    describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty",
+                                     "--always", "--long",
+                                     "--match", "%s*" % tag_prefix],
+                              cwd=root)
     # --long was added in git-1.5.5
     # --long was added in git-1.5.5
     if describe_out is None:
     if describe_out is None:
         raise NotThisMethod("'git describe' failed")
         raise NotThisMethod("'git describe' failed")
     describe_out = describe_out.strip()
     describe_out = describe_out.strip()
-    full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
+    full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root)
     if full_out is None:
     if full_out is None:
         raise NotThisMethod("'git rev-parse' failed")
         raise NotThisMethod("'git rev-parse' failed")
     full_out = full_out.strip()
     full_out = full_out.strip()
@@ -252,6 +258,39 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
     pieces["short"] = full_out[:7]  # maybe improved later
     pieces["short"] = full_out[:7]  # maybe improved later
     pieces["error"] = None
     pieces["error"] = None
 
 
+    branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"],
+                             cwd=root)
+    # --abbrev-ref was added in git-1.6.3
+    if rc != 0 or branch_name is None:
+        raise NotThisMethod("'git rev-parse --abbrev-ref' returned error")
+    branch_name = branch_name.strip()
+
+    if branch_name == "HEAD":
+        # If we aren't exactly on a branch, pick a branch which represents
+        # the current commit. If all else fails, we are on a branchless
+        # commit.
+        branches, rc = runner(GITS, ["branch", "--contains"], cwd=root)
+        # --contains was added in git-1.5.4
+        if rc != 0 or branches is None:
+            raise NotThisMethod("'git branch --contains' returned error")
+        branches = branches.split("\n")
+
+        # Remove the first line if we're running detached
+        if "(" in branches[0]:
+            branches.pop(0)
+
+        # Strip off the leading "* " from the list of branches.
+        branches = [branch[2:] for branch in branches]
+        if "master" in branches:
+            branch_name = "master"
+        elif not branches:
+            branch_name = None
+        else:
+            # Pick the first branch that is returned. Good or bad.
+            branch_name = branches[0]
+
+    pieces["branch"] = branch_name
+
     # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
     # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
     # TAG might have hyphens.
     # TAG might have hyphens.
     git_describe = describe_out
     git_describe = describe_out
@@ -293,13 +332,14 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
     else:
     else:
         # HEX: no tags
         # HEX: no tags
         pieces["closest-tag"] = None
         pieces["closest-tag"] = None
-        count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
-                                    cwd=root)
+        count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root)
         pieces["distance"] = int(count_out)  # total number of commits
         pieces["distance"] = int(count_out)  # total number of commits
 
 
     # commit date: see ISO-8601 comment in git_versions_from_keywords()
     # commit date: see ISO-8601 comment in git_versions_from_keywords()
-    date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"],
-                       cwd=root)[0].strip()
+    date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip()
+    # Use only the last line.  Previous lines may contain GPG signature
+    # information.
+    date = date.splitlines()[-1]
     pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
     pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
 
 
     return pieces
     return pieces
@@ -337,19 +377,49 @@ def render_pep440(pieces):
     return rendered
     return rendered
 
 
 
 
+def render_pep440_branch(pieces):
+    """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
+
+    The ".dev0" means not master branch. Note that .dev0 sorts backwards
+    (a feature branch will appear "older" than the master branch).
+
+    Exceptions:
+    1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty]
+    """
+    if pieces["closest-tag"]:
+        rendered = pieces["closest-tag"]
+        if pieces["distance"] or pieces["dirty"]:
+            if pieces["branch"] != "master":
+                rendered += ".dev0"
+            rendered += plus_or_dot(pieces)
+            rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
+            if pieces["dirty"]:
+                rendered += ".dirty"
+    else:
+        # exception #1
+        rendered = "0"
+        if pieces["branch"] != "master":
+            rendered += ".dev0"
+        rendered += "+untagged.%d.g%s" % (pieces["distance"],
+                                          pieces["short"])
+        if pieces["dirty"]:
+            rendered += ".dirty"
+    return rendered
+
+
 def render_pep440_pre(pieces):
 def render_pep440_pre(pieces):
-    """TAG[.post.devDISTANCE] -- No -dirty.
+    """TAG[.post0.devDISTANCE] -- No -dirty.
 
 
     Exceptions:
     Exceptions:
-    1: no tags. 0.post.devDISTANCE
+    1: no tags. 0.post0.devDISTANCE
     """
     """
     if pieces["closest-tag"]:
     if pieces["closest-tag"]:
         rendered = pieces["closest-tag"]
         rendered = pieces["closest-tag"]
         if pieces["distance"]:
         if pieces["distance"]:
-            rendered += ".post.dev%d" % pieces["distance"]
+            rendered += ".post0.dev%d" % pieces["distance"]
     else:
     else:
         # exception #1
         # exception #1
-        rendered = "0.post.dev%d" % pieces["distance"]
+        rendered = "0.post0.dev%d" % pieces["distance"]
     return rendered
     return rendered
 
 
 
 
@@ -380,12 +450,41 @@ def render_pep440_post(pieces):
     return rendered
     return rendered
 
 
 
 
+def render_pep440_post_branch(pieces):
+    """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
+
+    The ".dev0" means not master branch.
+
+    Exceptions:
+    1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty]
+    """
+    if pieces["closest-tag"]:
+        rendered = pieces["closest-tag"]
+        if pieces["distance"] or pieces["dirty"]:
+            rendered += ".post%d" % pieces["distance"]
+            if pieces["branch"] != "master":
+                rendered += ".dev0"
+            rendered += plus_or_dot(pieces)
+            rendered += "g%s" % pieces["short"]
+            if pieces["dirty"]:
+                rendered += ".dirty"
+    else:
+        # exception #1
+        rendered = "0.post%d" % pieces["distance"]
+        if pieces["branch"] != "master":
+            rendered += ".dev0"
+        rendered += "+g%s" % pieces["short"]
+        if pieces["dirty"]:
+            rendered += ".dirty"
+    return rendered
+
+
 def render_pep440_old(pieces):
 def render_pep440_old(pieces):
     """TAG[.postDISTANCE[.dev0]] .
     """TAG[.postDISTANCE[.dev0]] .
 
 
     The ".dev0" means dirty.
     The ".dev0" means dirty.
 
 
-    Eexceptions:
+    Exceptions:
     1: no tags. 0.postDISTANCE[.dev0]
     1: no tags. 0.postDISTANCE[.dev0]
     """
     """
     if pieces["closest-tag"]:
     if pieces["closest-tag"]:
@@ -456,10 +555,14 @@ def render(pieces, style):
 
 
     if style == "pep440":
     if style == "pep440":
         rendered = render_pep440(pieces)
         rendered = render_pep440(pieces)
+    elif style == "pep440-branch":
+        rendered = render_pep440_branch(pieces)
     elif style == "pep440-pre":
     elif style == "pep440-pre":
         rendered = render_pep440_pre(pieces)
         rendered = render_pep440_pre(pieces)
     elif style == "pep440-post":
     elif style == "pep440-post":
         rendered = render_pep440_post(pieces)
         rendered = render_pep440_post(pieces)
+    elif style == "pep440-post-branch":
+        rendered = render_pep440_post_branch(pieces)
     elif style == "pep440-old":
     elif style == "pep440-old":
         rendered = render_pep440_old(pieces)
         rendered = render_pep440_old(pieces)
     elif style == "git-describe":
     elif style == "git-describe":
@@ -495,7 +598,7 @@ def get_versions():
         # versionfile_source is the relative path from the top of the source
         # versionfile_source is the relative path from the top of the source
         # tree (where the .git directory might live) to this file. Invert
         # tree (where the .git directory might live) to this file. Invert
         # this to find the root from __file__.
         # this to find the root from __file__.
-        for i in cfg.versionfile_source.split('/'):
+        for _ in cfg.versionfile_source.split('/'):
             root = os.path.dirname(root)
             root = os.path.dirname(root)
     except NameError:
     except NameError:
         return {"version": "0+unknown", "full-revisionid": None,
         return {"version": "0+unknown", "full-revisionid": None,

+ 0 - 1
dataladmetadatamodel/version.py

@@ -1 +0,0 @@
-__version__ = '0.1.0b5'

+ 6 - 6
setup.cfg

@@ -1,5 +1,7 @@
 [metadata]
 [metadata]
-url = https://github.com/datalad/git-annex-ria-remote
+name = datalad-metadata-model
+version = 0.1.0b5
+url = https://github.com/datalad/datalad-metadata-model
 author = The DataLad Team and Contributors
 author = The DataLad Team and Contributors
 author_email = team@datalad.org
 author_email = team@datalad.org
 description = Metadata model used in DataLad's extension for semantic metadata handling
 description = Metadata model used in DataLad's extension for semantic metadata handling
@@ -8,15 +10,13 @@ long_description_content_type = text/markdown; charset=UTF-8; variant=GFM
 license = MIT
 license = MIT
 classifiers =
 classifiers =
     Programming Language :: Python
     Programming Language :: Python
-    License :: OSI Approved :: BSD License
+    License :: OSI Approved :: MIT License
     Programming Language :: Python :: 3
     Programming Language :: Python :: 3
 
 
 [options]
 [options]
-python_requires = >= 3.5
+python_requires = >= 3.6
 install_requires =
 install_requires =
-    datalad >= 0.14
-    datalad-metadata-model
-    pyyaml
+    datalad >= 0.15
 test_requires =
 test_requires =
     nose
     nose
     coverage
     coverage

+ 7 - 5
setup.py

@@ -1,13 +1,14 @@
 #!/usr/bin/env python
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 
 
-import os
-import sys
 import setuptools
 import setuptools
+import sys
+from os.path import dirname
 
 
-print(os.getcwd())
-sys.path.insert(0, os.getcwd())
-print(sys.path)
+# This is needed for versioneer to be importable when building with PEP 517.
+# See <https://github.com/warner/python-versioneer/issues/193> and links
+# therein for more information.
+sys.path.append(dirname(__file__))
 import versioneer
 import versioneer
 
 
 
 
@@ -18,6 +19,7 @@ with open("README.md", "r") as fh:
 setuptools.setup(
 setuptools.setup(
     name="datalad-metadata-model",
     name="datalad-metadata-model",
     version=versioneer.get_version(),
     version=versioneer.get_version(),
+    cmdclass=versioneer.get_cmdclass(),
     author="The Datalad Team",
     author="The Datalad Team",
     author_email="christian.moench@web.de",
     author_email="christian.moench@web.de",
     description="Datalad Metadata Model",
     description="Datalad Metadata Model",

+ 0 - 291
simple_test/persisted_object.py

@@ -1,291 +0,0 @@
-import logging
-from typing import (
-    Dict,
-    Iterable,
-    List,
-    Optional,
-    Union
-)
-
-
-from dataladmetadatamodel.mapper.gitmapper.gitbackend.subprocess import (
-    git_load_json,
-    git_load_str,
-    git_save_json,
-    git_save_str
-)
-
-
-logging.basicConfig(level=logging.DEBUG)
-repo_dir: str = "/home/cristian/tmp/mapptest"
-
-
-SReference = str
-SJSON = Union[str, int, float, Dict, List]
-
-
-class Mapper:
-    def read_in(self, mappable_object: "MappableObject", SReference):
-        raise NotImplementedError
-
-    def write_out(self, mappable_object: "MappableObject") -> SReference:
-        raise NotImplementedError
-
-
-mapper: Dict[str, Mapper] = dict()
-
-
-class ModifiableObject:
-    """
-    Object that tracks modification status.
-
-    Responsibilities:
-     - allow touching and cleaning
-     - determine modification state based
-       on subclass-implementation of is_modified_impl()
-    """
-    def __init__(self):
-        # A modifiable object is assumed
-        # to be unmodified upon creation
-        self.dirty = False
-
-    def touch(self):
-        self.dirty = True
-
-    def clean(self):
-        self.dirty = False
-
-    def is_modified(self) -> bool:
-        """
-        Determine whether the object or one of its contained
-        objects was modified.
-        """
-        if not self.dirty:
-            self.dirty = self._sub_elements_modified()
-        return self.dirty
-
-    def _sub_elements_modified(self):
-        return any(map(lambda element: element.is_modified(), self.get_modifiable_mapped_sub_elements()))
-
-    def xxxsub_elements_modified(self) -> bool:
-        """
-        By default modification state is determined by
-        the dirty flag in this object, i.e. whether
-        self.clean() or self.touch() has been invoked
-        latest.
-
-        :return: True if any sub-element exists that is
-                 modified, else False
-        """
-        return False
-
-    def get_modifiable_mapped_sub_elements(self) -> Iterable:
-        return []
-
-
-class MappableObject(ModifiableObject):
-    """
-    Base class for objects that can
-    be mapped onto a storage backend
-    """
-    def __init__(self, reference: Optional[SReference]):
-        super().__init__()
-        self.reference = reference
-        if reference is None:
-            self.mapped = True
-        else:
-            self.mapped = False
-
-    def read_in(self):
-        if self.mapped:
-            return
-        assert self.reference is not None
-        mapper[type(self).__name__].read_in(self, self.reference)
-        self.mapped = True
-        self.clean()
-
-    def write_out(self) -> SReference:
-        if self.mapped:
-            self.reference = mapper[type(self).__name__].write_out(self)
-            self.clean()
-        assert self.reference is not None
-        return self.reference
-
-    def purge(self):
-        if self.mapped:
-            self.purge_impl()
-            self.mapped = False
-            self.clean()
-
-    def purge_impl(self):
-        raise NotImplementedError
-
-
-class MappableDict(MappableObject):
-    def __init__(self, reference: Optional[SReference] = None):
-        super().__init__(reference)
-        self.content = dict()
-
-    def put(self, key: str, value: SJSON):
-        self.content[key] = value
-        self.touch()
-
-    def get(self, key: str) -> SJSON:
-        return self.content[key]
-
-    def purge_impl(self):
-        self.content = dict()
-
-
-class ComplexDict(MappableObject):
-    def __init__(self, reference: Optional[SReference] = None):
-        super().__init__(reference)
-        self.content = dict()
-
-    def put(self, key: str, value: SJSON):
-        self.content[key] = value
-        self.touch()
-
-    def get(self, key: str) -> SJSON:
-        return self.content[key]
-
-    def purge_impl(self):
-        self.content = dict()
-
-
-class CTree(MappableObject):
-    def __init__(self, reference: Optional[SReference] = None):
-        super().__init__(reference)
-        self.tree = dict()
-
-    def put_c(self, path: str, mappable_dict: MappableDict):
-        self.tree[path] = mappable_dict
-        self.touch()
-
-    def get_c(self, path: str) -> MappableDict:
-        mappable_dict = self.tree[path]
-        mappable_dict.read_in()
-        return mappable_dict
-
-    def purge_impl(self):
-        self.tree = dict()
-
-    def get_modifiable_mapped_sub_elements(self) -> Iterable:
-        yield from self.tree.values()
-
-
-class MappedDictMapper(Mapper):
-
-    def read_in(self, mappable_object: MappableDict, reference: SReference):
-        mappable_object.content = git_load_json(repo_dir, str(reference))
-
-    def write_out(self, mappable_object: MappableDict) -> SReference:
-        return git_save_json(repo_dir, mappable_object.content)
-
-
-class ComplexDictMapper(Mapper):
-
-    def read_in(self, complex_dict: ComplexDict, reference: SReference):
-        first_level = git_load_json(repo_dir, str(reference))
-        for key, value in first_level.items():
-            complex_dict.content[key] = git_load_str(repo_dir, first_level[key])
-
-    def write_out(self, complex_dict: ComplexDict) -> SReference:
-        first_level = {
-            key: git_save_str(repo_dir, value)
-            for key, value in complex_dict.content.items()
-        }
-        return git_save_json(repo_dir, first_level)
-
-
-class CTreeMapper(Mapper):
-
-    def read_in(self, c_tree: CTree, reference: SReference):
-        first_level = git_load_json(repo_dir, str(reference))
-        logging.debug(f"CTreeMapper: read_in: first_level: {first_level}")
-        for key, value in first_level.items():
-            c_tree.tree[key] = MappableDict(git_load_str(repo_dir, first_level[key])[5:])
-
-    def write_out(self, c_tree: CTree) -> SReference:
-        first_level = {
-            key: git_save_str(repo_dir, "link:" + mapped_dict.write_out())
-            for key, mapped_dict in c_tree.tree.items()
-        }
-        logging.debug(f"CTreeMapper: write_out: first_level: {first_level}")
-        return git_save_json(repo_dir, first_level)
-
-
-mapper["MappableDict"] = MappedDictMapper()
-mapper["ComplexDict"] = ComplexDictMapper()
-mapper["CTree"] = CTreeMapper()
-
-
-def test():
-
-    ct = CTree()
-    for path in ["a/b/c1", "a/b/c2", "a/b/c3"]:
-        sub_elment = MappableDict()
-        for ext in ("-v0", "-v1", "-v2"):
-            sub_elment.put(path + ext, "This is value for: " + path + ext)
-        ct.put_c(path, sub_elment)
-
-    print(ct.is_modified())
-
-    reference = ct.write_out()
-    print(reference)
-
-    print(ct.is_modified())
-
-    md = ct.get_c("a/b/c1")
-    md.put("test-mod", "a key to test modification")
-
-    print(ct.is_modified())
-
-    reference = ct.write_out()
-    print(reference)
-
-    ct.purge()
-
-    ct2 = CTree(reference)
-    ct2.read_in()
-
-    print(ct2)
-
-    return
-
-    cd = ComplexDict()
-    for key, value in (("a", "this is a"),
-                       ("b", "bbbb is here!")):
-        cd.put(key, value)
-
-    print(cd.is_modified())
-
-    reference = cd.write_out()
-    print(reference)
-
-    cd.purge()
-    cd.read_in()
-    print(cd.content)
-
-    return
-    md = MappableDict()
-    for i in range(32):
-        md.put(str(i), hex(i))
-
-    print(md.is_modified())
-
-    reference = md.write_out()
-    print(reference)
-
-    md.purge()
-    md.read_in()
-    print(md.content)
-
-
-    md2 = MappableDict(reference)
-    md2.read_in()
-    print(md2.content)
-
-
-if __name__ == "__main__":
-    test()

Diferenças do arquivo suprimidas por serem muito extensas
+ 438 - 196
versioneer.py