Coverage for pesummary/_version_helper.py: 65.1%
109 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-12-09 22:34 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-12-09 22:34 +0000
1# Licensed under an MIT style license -- see LICENSE.md
3import json
4import os
5import shutil
6import subprocess
7import sys
8from pathlib import Path
10__author__ = ["Charlie Hoy <charlie.hoy@ligo.org>"]
13class GitDummy(object):
14 def __getattr__(self, attr):
15 return ""
18class GitInformation(object):
19 """Helper class to handle the git information
20 """
21 def __init__(self, directory=None):
22 if directory is None and not os.path.isdir(".git"):
23 raise TypeError(
24 "Not a git repository. Unable to get git information"
25 )
26 elif directory is None:
27 directory = "."
28 cwd = os.getcwd()
29 os.chdir(directory)
30 self.last_commit_info = self.get_last_commit_info()
31 self.last_version = self.get_last_version()
32 self.hash = self.last_commit_info[0]
33 self.author = self.last_commit_info[1]
34 self.status = self.get_status()
35 self.builder = self.get_build_name()
36 self.build_date = self.get_build_date()
37 os.chdir(cwd)
39 def call(self, arguments):
40 """Launch a subprocess to run the bash command
42 Parameters
43 ----------
44 arguments: list
45 list of bash commands
46 """
47 return subprocess.check_output(arguments)
49 def get_build_name(self):
50 """Return the username and email of the current builder
51 """
52 try:
53 name = self.call(["git", "config", "user.name"])
54 email = self.call(["git", "config", "user.email"])
55 name = name.strip()
56 email = email.strip()
57 return "%s <%s>" % (name.decode("utf-8"), email.decode("utf-8"))
58 except Exception:
59 return ""
61 def get_build_date(self):
62 """Return the current datetime
63 """
64 import time
65 return time.strftime('%Y-%m-%d %H:%M:%S +0000', time.gmtime())
67 def get_last_commit_info(self):
68 """Return the details of the last git commit
69 """
70 try:
71 string = self.call(
72 ["git", "log", "-1", "--pretty=format:%h,%an,%ae"])
73 string = string.decode("utf-8").split(",")
74 hash, username, email = string
75 author = "%s <%s>" % (username, email)
76 return hash, author
77 except Exception:
78 return ""
80 def get_status(self):
81 """Return the state of the git repository
82 """
83 git_diff = self.call(["git", "diff", "."]).decode("utf-8")
84 if git_diff:
85 return "UNCLEAN: Modified working tree"
86 return "CLEAN: All modifications committed"
88 def get_last_version(self):
89 """Return the last stable version
90 """
91 try:
92 tag = self.call(["git", "describe", "--tags", "--abbrev=0"]).decode(
93 "utf-8"
94 ).strip("\n")
95 if tag[0] != "v":
96 return tag
97 return tag[1:]
98 except Exception:
99 return "Not found"
102class PackageInformation(GitInformation):
103 """Helper class to handle package versions
104 """
105 def __init__(self):
106 self.package_info = self.get_package_info()
107 self.package_dir = self.get_package_dir()
109 @staticmethod
110 def _find_conda():
111 """Return the path of the ``conda`` executable, or `None`.
112 """
113 return os.getenv("CONDA_EXE", shutil.which("conda"))
115 def get_package_info(self):
116 """Return the package information
117 """
118 if (conda := self._find_conda()) and (Path(sys.prefix) / "conda-meta").is_dir():
119 self.package_manager = "conda"
120 raw = self.call([
121 conda,
122 "list",
123 "--json",
124 "--prefix", sys.prefix,
125 ])
126 else:
127 self.package_manager = "pypi"
128 raw = self.call([
129 sys.executable,
130 "-m", "pip",
131 "list", "installed",
132 "--format", "json",
133 ])
134 return json.loads(raw.decode('utf-8'))
136 def get_package_dir(self):
137 """Return the package directory
138 """
139 return sys.prefix
142def make_version_file(
143 version_file=None, return_string=False, version=None, add_install_path=False
144):
145 """Write a version file
147 Parameters
148 ----------
149 version_file: str
150 the path to the version file you wish to write
151 return_sting: Bool, optional
152 if True, return the version file as a string. Default False
153 """
154 from pesummary import __version_string__
156 string = __version_string__
157 if add_install_path:
158 string += install_path(return_string=True)
159 if not return_string and version_file is None:
160 raise ValueError("Please provide a version file")
161 elif not return_string:
162 with open(version_file, "w") as f:
163 f.write(string)
164 return version_file
165 return string
168def install_path(return_string=False):
169 """Return the install path of a package
170 """
171 packages = PackageInformation()
172 install_path = packages.package_dir
173 string = "# Install information\n\ninstall_path = %s\n" % (
174 install_path
175 )
176 if return_string:
177 return string
178 return packages.package_dir
181def get_version_information(short=False):
182 """Grab the version from the .version file
184 Parameters
185 ----------
186 short: Bool
187 If True, only return the version. If False, return git hash
188 """
189 try:
190 from ._version import version
191 except ModuleNotFoundError:
192 try:
193 # in build
194 import setuptools_scm
195 version = setuptools_scm.get_version()
196 except ImportError:
197 version = ""
199 if short:
200 return version.split("+")[0]
201 return version