ci-helper 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ build/*
2
+ dist/*
3
+ __pycache__
4
+ *.egg-info
5
+ *.eggs
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Christopher Billington
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.1
2
+ Name: ci-helper
3
+ Version: 0.1.0
4
+ Summary: Get info on how a package should be built on CI
5
+ Home-page: http://github.com/chrisjbillington/ci-helper
6
+ Author: Christopher Billington
7
+ Author-email: chrisjbillington@gmail.com
8
+ License: MIT
9
+ Project-URL: Source Code, https://github.com/chrisjbillington/ci-helper
10
+ Project-URL: Download, https://github.com/chrisjbillington/ci-helper/releases
11
+ Project-URL: Tracker, https://github.com/chrisjbillington/ci-helper/issues
12
+ Keywords: build setuptools conda
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE.txt
18
+ Requires-Dist: setuptools_scm
19
+ Requires-Dist: importlib_metadata
20
+ Requires-Dist: toml
21
+ Requires-Dist: requests
22
+
23
+ # ci-helper
24
+
25
+ Output information to help build a Python package in CI
26
+
27
+ ## Motivation
28
+
29
+ This tool exists to address certain issues of bit-rot and deployment of GitHub Actions
30
+ workflows (though the problem exists for CI generally) that build Python packages.
31
+
32
+ It looks up what current Python versions are supported so you can target them in your
33
+ builds without having to maintain a curated list. It determines whether building on
34
+ multiple OSs or Python versions is needed for a Python package, allowing you to deploy a
35
+ generic CI configuration for different types of packages without having to modify it for
36
+ each one specifically when they only vary in this way.
37
+
38
+ Specifically:
39
+
40
+ * It lists all stable and supported Python versions so your CI can target all supported
41
+ versions of Python without having to curate a manual list.
42
+
43
+ * It tells you what the second-most-recent minor version of Python is, so you can use that
44
+ as a sensible default for tools that require a recent-ish Python but are likely not to
45
+ work immediately after a new Python is released.
46
+
47
+ * It tells you whether a Python package is pure Python or not, so that your CI knows
48
+ whether it needs to build on multiple OSs/Python versions.
49
+
50
+ * It tells you whether a Python package's dependencies have environment markers or not, so
51
+ that your CI knows whether it needs to build on multiple OSs/Python versions, for
52
+ package formats that don't support environment markers in dependencies (e.g. conda
53
+ packages).
54
+
55
+ These functions are all serving the goals of:
56
+
57
+ * Minimising how often you need to modify your CI configs just because a new version of
58
+ Python came our or an old version reached end-of-life
59
+ * Minimising (ideally to zero) how much you need to customise an otherwise generic CI
60
+ config when you re-use it for different types of Python packages (e.g. pure vs impure)
61
+
62
+ ## Installation
63
+
64
+ This package is available on PyPI, install it to your current Python environemnt with
65
+ ```bash
66
+ pip install ci-helper
67
+ ```
68
+
69
+ ## Usage:
70
+
71
+ ```bash
72
+ # The second-most recent minor Python release, a good choice for the version to run
73
+ # tools from:
74
+ $ ci-helper defaultpython
75
+ 3.12
76
+
77
+ # All stable, non-end-of-life Python versions:
78
+ $ ci-helper pythons
79
+ 3.9,3.10,3.11,3.12,3.13
80
+
81
+ # Same but in the format used by `cibuildwheel`'s `CIBW_BUILD` environment variable (cpython-only for now):
82
+ $ ci-helper pythons --cibw
83
+ cp39-* cp310-* cp311-* cp312-* cp313-*
84
+
85
+ # Info about the source Python project in the current working directory - name, version,
86
+ # whether it's a pure Python package, and whether its build or run requirements contain
87
+ # any # environment markers (that is, whether its requirements vary by platform or
88
+ # Python version):
89
+ $ ci-helper distinfo
90
+ {
91
+ "name": "ci-helper",
92
+ "version": "0.1.dev1+g5043fb5.d20241202",
93
+ "is_pure": true,
94
+ "has_env_markers": false
95
+ }
96
+
97
+ # Same but one field at a time, more convenient for assigning to environment variables:
98
+ $ ci-helper distinfo name
99
+ ci-helper
100
+ $ ci-helper distinfo version
101
+ 0.1.0
102
+ $ ci-helper distinfo is_pure
103
+ true
104
+ $ ci-helper distinfo has_env_markers
105
+ false
106
+ ```
107
+
108
+ ## Full help text
109
+
110
+ ```shell
111
+ $ ci-helper -h
112
+ usage: ci-helper [-h] [--version] {pythons,defaultpython,distinfo} ...
113
+
114
+ positional arguments:
115
+ {pythons,defaultpython,distinfo}
116
+ Action to perform
117
+ pythons Output list of stable Python versions that have not yet reached end of life, see `ci-helper pythons -h`
118
+ defaultpython Output the second-latest stable Python version in X.Y format, useful as a good choice for a default python version
119
+ distinfo Output info about the distribution, see `ci-helper distinfo -h`
120
+
121
+ options:
122
+ -h, --help show this help message and exit
123
+ --version show program's version number and exit
124
+ ```
125
+
126
+ ```shell
127
+ $ ci-helper pythons -h
128
+ usage: ci-helper pythons [-h] [--cibw]
129
+
130
+ options:
131
+ -h, --help show this help message and exit
132
+ --cibw Output as a space-separated list in the format `cpXY-* cpXY-*` as appropriate for the CIBW_BUILD environment variable to build for all
133
+ stable CPython versions, otherwise versions are output as a comma-separated list in the format X.Y,X.Y
134
+ ```
135
+
136
+ ```shell
137
+ $ ci-helper defaultpython -h
138
+ usage: ci-helper defaultpython [-h]
139
+
140
+ options:
141
+ -h, --help show this help message and exit
142
+ ```
143
+
144
+ ```shell
145
+ $ ci-helper distinfo -h
146
+ usage: ci-helper distinfo [-h] [{name,version,is_pure,has_env_markers}]
147
+
148
+ positional arguments:
149
+ {name,version,is_pure,has_env_markers}
150
+ Name of field to output as a single json value, if not given, all info is output as json
151
+
152
+ options:
153
+ -h, --help show this help message and exit
154
+ ```
155
+
@@ -0,0 +1,133 @@
1
+ # ci-helper
2
+
3
+ Output information to help build a Python package in CI
4
+
5
+ ## Motivation
6
+
7
+ This tool exists to address certain issues of bit-rot and deployment of GitHub Actions
8
+ workflows (though the problem exists for CI generally) that build Python packages.
9
+
10
+ It looks up what current Python versions are supported so you can target them in your
11
+ builds without having to maintain a curated list. It determines whether building on
12
+ multiple OSs or Python versions is needed for a Python package, allowing you to deploy a
13
+ generic CI configuration for different types of packages without having to modify it for
14
+ each one specifically when they only vary in this way.
15
+
16
+ Specifically:
17
+
18
+ * It lists all stable and supported Python versions so your CI can target all supported
19
+ versions of Python without having to curate a manual list.
20
+
21
+ * It tells you what the second-most-recent minor version of Python is, so you can use that
22
+ as a sensible default for tools that require a recent-ish Python but are likely not to
23
+ work immediately after a new Python is released.
24
+
25
+ * It tells you whether a Python package is pure Python or not, so that your CI knows
26
+ whether it needs to build on multiple OSs/Python versions.
27
+
28
+ * It tells you whether a Python package's dependencies have environment markers or not, so
29
+ that your CI knows whether it needs to build on multiple OSs/Python versions, for
30
+ package formats that don't support environment markers in dependencies (e.g. conda
31
+ packages).
32
+
33
+ These functions are all serving the goals of:
34
+
35
+ * Minimising how often you need to modify your CI configs just because a new version of
36
+ Python came our or an old version reached end-of-life
37
+ * Minimising (ideally to zero) how much you need to customise an otherwise generic CI
38
+ config when you re-use it for different types of Python packages (e.g. pure vs impure)
39
+
40
+ ## Installation
41
+
42
+ This package is available on PyPI, install it to your current Python environemnt with
43
+ ```bash
44
+ pip install ci-helper
45
+ ```
46
+
47
+ ## Usage:
48
+
49
+ ```bash
50
+ # The second-most recent minor Python release, a good choice for the version to run
51
+ # tools from:
52
+ $ ci-helper defaultpython
53
+ 3.12
54
+
55
+ # All stable, non-end-of-life Python versions:
56
+ $ ci-helper pythons
57
+ 3.9,3.10,3.11,3.12,3.13
58
+
59
+ # Same but in the format used by `cibuildwheel`'s `CIBW_BUILD` environment variable (cpython-only for now):
60
+ $ ci-helper pythons --cibw
61
+ cp39-* cp310-* cp311-* cp312-* cp313-*
62
+
63
+ # Info about the source Python project in the current working directory - name, version,
64
+ # whether it's a pure Python package, and whether its build or run requirements contain
65
+ # any # environment markers (that is, whether its requirements vary by platform or
66
+ # Python version):
67
+ $ ci-helper distinfo
68
+ {
69
+ "name": "ci-helper",
70
+ "version": "0.1.dev1+g5043fb5.d20241202",
71
+ "is_pure": true,
72
+ "has_env_markers": false
73
+ }
74
+
75
+ # Same but one field at a time, more convenient for assigning to environment variables:
76
+ $ ci-helper distinfo name
77
+ ci-helper
78
+ $ ci-helper distinfo version
79
+ 0.1.0
80
+ $ ci-helper distinfo is_pure
81
+ true
82
+ $ ci-helper distinfo has_env_markers
83
+ false
84
+ ```
85
+
86
+ ## Full help text
87
+
88
+ ```shell
89
+ $ ci-helper -h
90
+ usage: ci-helper [-h] [--version] {pythons,defaultpython,distinfo} ...
91
+
92
+ positional arguments:
93
+ {pythons,defaultpython,distinfo}
94
+ Action to perform
95
+ pythons Output list of stable Python versions that have not yet reached end of life, see `ci-helper pythons -h`
96
+ defaultpython Output the second-latest stable Python version in X.Y format, useful as a good choice for a default python version
97
+ distinfo Output info about the distribution, see `ci-helper distinfo -h`
98
+
99
+ options:
100
+ -h, --help show this help message and exit
101
+ --version show program's version number and exit
102
+ ```
103
+
104
+ ```shell
105
+ $ ci-helper pythons -h
106
+ usage: ci-helper pythons [-h] [--cibw]
107
+
108
+ options:
109
+ -h, --help show this help message and exit
110
+ --cibw Output as a space-separated list in the format `cpXY-* cpXY-*` as appropriate for the CIBW_BUILD environment variable to build for all
111
+ stable CPython versions, otherwise versions are output as a comma-separated list in the format X.Y,X.Y
112
+ ```
113
+
114
+ ```shell
115
+ $ ci-helper defaultpython -h
116
+ usage: ci-helper defaultpython [-h]
117
+
118
+ options:
119
+ -h, --help show this help message and exit
120
+ ```
121
+
122
+ ```shell
123
+ $ ci-helper distinfo -h
124
+ usage: ci-helper distinfo [-h] [{name,version,is_pure,has_env_markers}]
125
+
126
+ positional arguments:
127
+ {name,version,is_pure,has_env_markers}
128
+ Name of field to output as a single json value, if not given, all info is output as json
129
+
130
+ options:
131
+ -h, --help show this help message and exit
132
+ ```
133
+
@@ -0,0 +1 @@
1
+ from ci_helper.ci_distinfo import ci_distinfo
@@ -0,0 +1,4 @@
1
+ try:
2
+ from .__version__ import __version__
3
+ except ImportError:
4
+ __version__ = None
@@ -0,0 +1,120 @@
1
+ import sys
2
+ from pathlib import Path
3
+ import argparse
4
+ import json
5
+ import subprocess
6
+ import requests
7
+
8
+ from .__version__ import __version__
9
+
10
+
11
+ # Command line args that can be used in place of "setup.py" for projects that lack a
12
+ # setup.py, runs a minimal setup.py similar to what pip does for projects with no
13
+ # setup.py.
14
+ _SETUP_PY_STUB = [
15
+ "-c",
16
+ 'import sys, setuptools; sys.argv[0] = __file__ = "setup.py"; setuptools.setup()',
17
+ ]
18
+
19
+
20
+ def setup_py(project_dir):
21
+ """Returns a list of command line arguments to be used in place of ["setup.py"]. If
22
+ setup.py exists, then this is just ["setup.py"]. Otherwise, if setup.cfg or
23
+ pyproject.toml exists, returns args that pass a code snippet to Python with "-c" to
24
+ execute a minimal setup.py calling setuptools.setup(). If none of pyproject.toml,
25
+ setup.cfg, or setup.py exists, raises an exception."""
26
+ if Path(project_dir, 'setup.py').exists():
27
+ return ['setup.py']
28
+ elif any(Path(project_dir, s).exists() for s in ['setup.cfg', 'pyproject.toml']):
29
+ return _SETUP_PY_STUB
30
+ msg = f"""{project_dir} does not look like a python project directory: contains no
31
+ setup.py, setup.cfg, or pyproject.toml"""
32
+ raise RuntimeError(' '.join(msg.split()))
33
+
34
+
35
+ def get_pythons():
36
+ """Return stable, non-end-of-life Python versions in X.Y format"""
37
+ URL = "https://raw.githubusercontent.com/python/devguide/refs/heads/main/include/release-cycle.json"
38
+ response = requests.get(URL, timeout=30)
39
+ if not response.ok:
40
+ raise ValueError(f"{response.status_code} {response.reason}")
41
+ pythons = response.json()
42
+ pythons = [p for p in pythons if pythons[p]['status'] in ('bugfix', 'security')]
43
+ pythons.sort(key=lambda ver: [int(part) for part in ver.split('.')])
44
+ return pythons
45
+
46
+
47
+ def main():
48
+ # Since setuptools_conda is self-hosting, it needs toml and distlib to read its own
49
+ # requirements just to know that it needs to install toml and distlib! So bootstrap
50
+ # that up if necessary.
51
+
52
+ parser = argparse.ArgumentParser(prog='ci-helper')
53
+ parser.add_argument(
54
+ '--version',
55
+ action='version',
56
+ version=__version__,
57
+ )
58
+ subparsers = parser.add_subparsers(
59
+ dest="command", required=True, help="Action to perform"
60
+ )
61
+ parser_pythons = subparsers.add_parser(
62
+ "pythons",
63
+ help="Output list of stable Python versions that have not yet reached end of "
64
+ + "life, see `ci-helper pythons -h`",
65
+ )
66
+ parser_pythons.add_argument(
67
+ "--cibw",
68
+ action="store_true",
69
+ help="Output as a space-separated list in the format "
70
+ + "`cpXY-* cpXY-*` as appropriate for the CIBW_BUILD environment variable "
71
+ + "to build for all stable CPython versions, otherwise versions are output as "
72
+ "a comma-separated list in the format X.Y,X.Y",
73
+ )
74
+ _ = subparsers.add_parser(
75
+ "defaultpython",
76
+ help="Output the second-latest stable Python version in X.Y format, "
77
+ "useful as a good choice for a default python version",
78
+ )
79
+ parser_distinfo = subparsers.add_parser(
80
+ "distinfo",
81
+ help="Output info about the distribution, see `ci-helper distinfo -h`",
82
+ )
83
+ parser_distinfo.add_argument(
84
+ "field",
85
+ choices=['name', 'version', 'is_pure', 'has_env_markers'],
86
+ nargs="?",
87
+ help="Name of field to output as a single json value, "
88
+ + "if not given, all info is output as json",
89
+ )
90
+
91
+ args = parser.parse_args()
92
+
93
+ if args.command == 'distinfo':
94
+ # distinfo_args = parser_distinfo.parse_args()
95
+ cmd = [sys.executable, *setup_py('.'), '-q', 'ci_distinfo']
96
+ result = subprocess.run(cmd, check=True, capture_output=True)
97
+ info = result.stdout.decode('utf8')
98
+ if args.field is not None:
99
+ info = json.loads(info)
100
+ value = info[args.field]
101
+ if isinstance(value, str):
102
+ print(value)
103
+ else:
104
+ print(json.dumps(value))
105
+ else:
106
+ print(info)
107
+ elif args.command == 'pythons':
108
+ pythons = get_pythons()
109
+ if args.cibw:
110
+ print(' '.join([f"cp{p.replace('.', '')}-*" for p in pythons]))
111
+ else:
112
+ print(','.join(pythons))
113
+ elif args.command == 'defaultpython':
114
+ pythons = get_pythons()
115
+ print(pythons[-2])
116
+ sys.exit(0)
117
+
118
+
119
+ if __name__ == '__main__':
120
+ main()
@@ -0,0 +1,21 @@
1
+ import os
2
+ from pathlib import Path
3
+ try:
4
+ import importlib.metadata as importlib_metadata
5
+ except ImportError:
6
+ import importlib_metadata
7
+
8
+ VERSION_SCHEME = {
9
+ "version_scheme": os.getenv("SCM_VERSION_SCHEME", "guess-next-dev"),
10
+ "local_scheme": os.getenv("SCM_LOCAL_SCHEME", "node-and-date"),
11
+ }
12
+
13
+ root = Path(__file__).parent.parent
14
+ if (root / '.git').is_dir():
15
+ from setuptools_scm import get_version
16
+ __version__ = get_version(root, **VERSION_SCHEME)
17
+ else:
18
+ try:
19
+ __version__ = importlib_metadata.version(__package__)
20
+ except importlib_metadata.PackageNotFoundError:
21
+ __version__ = None
@@ -0,0 +1,66 @@
1
+ from setuptools import Command
2
+ import json
3
+ from pathlib import Path
4
+
5
+
6
+ def get_pyproject_toml_entry(proj, *keys):
7
+ """Return [build-system] requires as read from proj/pyproject.toml, if any"""
8
+ # this import is here to avoid bootstrapping issues when building wheels for this
9
+ # package itself
10
+ import toml
11
+ pyproject_toml = Path(proj, 'pyproject.toml')
12
+ if not pyproject_toml.exists():
13
+ return None
14
+ config = toml.load(pyproject_toml)
15
+ try:
16
+ for key in keys:
17
+ config = config[key]
18
+ return config
19
+ except KeyError:
20
+ return None
21
+
22
+
23
+ def has_environment_markers(setup_requires, install_requires, extras_requires):
24
+ """Given a list of install_requires and a dict of extras_requires, return if there
25
+ are any environment markers"""
26
+ for item in install_requires:
27
+ if ';' in item:
28
+ return True
29
+ for key in extras_requires:
30
+ if key.startswith(':'):
31
+ # an extras_requires item being used as an environment marker, an old
32
+ # pattern allowed by setuptools
33
+ return True
34
+ return False
35
+
36
+
37
+ class ci_distinfo(Command):
38
+ description = "Get package info useful for building on CI"
39
+ user_options = []
40
+
41
+ def initialize_options(self):
42
+ pass
43
+
44
+ def finalize_options(self):
45
+ pass
46
+
47
+ def run(self):
48
+
49
+ setup_requires = get_pyproject_toml_entry('.', 'build-system', 'requires')
50
+ if setup_requires is None:
51
+ setup_requires = self.distribution.setup_requires
52
+
53
+ info = {
54
+ 'name': self.distribution.get_name(),
55
+ 'version': self.distribution.get_version(),
56
+ 'is_pure': not (
57
+ self.distribution.has_ext_modules()
58
+ or self.distribution.has_c_libraries()
59
+ ),
60
+ 'has_env_markers': has_environment_markers(
61
+ setup_requires,
62
+ self.distribution.install_requires,
63
+ self.distribution.extras_require,
64
+ ),
65
+ }
66
+ print(json.dumps(info, indent=4))
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.1
2
+ Name: ci-helper
3
+ Version: 0.1.0
4
+ Summary: Get info on how a package should be built on CI
5
+ Home-page: http://github.com/chrisjbillington/ci-helper
6
+ Author: Christopher Billington
7
+ Author-email: chrisjbillington@gmail.com
8
+ License: MIT
9
+ Project-URL: Source Code, https://github.com/chrisjbillington/ci-helper
10
+ Project-URL: Download, https://github.com/chrisjbillington/ci-helper/releases
11
+ Project-URL: Tracker, https://github.com/chrisjbillington/ci-helper/issues
12
+ Keywords: build setuptools conda
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE.txt
18
+ Requires-Dist: setuptools_scm
19
+ Requires-Dist: importlib_metadata
20
+ Requires-Dist: toml
21
+ Requires-Dist: requests
22
+
23
+ # ci-helper
24
+
25
+ Output information to help build a Python package in CI
26
+
27
+ ## Motivation
28
+
29
+ This tool exists to address certain issues of bit-rot and deployment of GitHub Actions
30
+ workflows (though the problem exists for CI generally) that build Python packages.
31
+
32
+ It looks up what current Python versions are supported so you can target them in your
33
+ builds without having to maintain a curated list. It determines whether building on
34
+ multiple OSs or Python versions is needed for a Python package, allowing you to deploy a
35
+ generic CI configuration for different types of packages without having to modify it for
36
+ each one specifically when they only vary in this way.
37
+
38
+ Specifically:
39
+
40
+ * It lists all stable and supported Python versions so your CI can target all supported
41
+ versions of Python without having to curate a manual list.
42
+
43
+ * It tells you what the second-most-recent minor version of Python is, so you can use that
44
+ as a sensible default for tools that require a recent-ish Python but are likely not to
45
+ work immediately after a new Python is released.
46
+
47
+ * It tells you whether a Python package is pure Python or not, so that your CI knows
48
+ whether it needs to build on multiple OSs/Python versions.
49
+
50
+ * It tells you whether a Python package's dependencies have environment markers or not, so
51
+ that your CI knows whether it needs to build on multiple OSs/Python versions, for
52
+ package formats that don't support environment markers in dependencies (e.g. conda
53
+ packages).
54
+
55
+ These functions are all serving the goals of:
56
+
57
+ * Minimising how often you need to modify your CI configs just because a new version of
58
+ Python came our or an old version reached end-of-life
59
+ * Minimising (ideally to zero) how much you need to customise an otherwise generic CI
60
+ config when you re-use it for different types of Python packages (e.g. pure vs impure)
61
+
62
+ ## Installation
63
+
64
+ This package is available on PyPI, install it to your current Python environemnt with
65
+ ```bash
66
+ pip install ci-helper
67
+ ```
68
+
69
+ ## Usage:
70
+
71
+ ```bash
72
+ # The second-most recent minor Python release, a good choice for the version to run
73
+ # tools from:
74
+ $ ci-helper defaultpython
75
+ 3.12
76
+
77
+ # All stable, non-end-of-life Python versions:
78
+ $ ci-helper pythons
79
+ 3.9,3.10,3.11,3.12,3.13
80
+
81
+ # Same but in the format used by `cibuildwheel`'s `CIBW_BUILD` environment variable (cpython-only for now):
82
+ $ ci-helper pythons --cibw
83
+ cp39-* cp310-* cp311-* cp312-* cp313-*
84
+
85
+ # Info about the source Python project in the current working directory - name, version,
86
+ # whether it's a pure Python package, and whether its build or run requirements contain
87
+ # any # environment markers (that is, whether its requirements vary by platform or
88
+ # Python version):
89
+ $ ci-helper distinfo
90
+ {
91
+ "name": "ci-helper",
92
+ "version": "0.1.dev1+g5043fb5.d20241202",
93
+ "is_pure": true,
94
+ "has_env_markers": false
95
+ }
96
+
97
+ # Same but one field at a time, more convenient for assigning to environment variables:
98
+ $ ci-helper distinfo name
99
+ ci-helper
100
+ $ ci-helper distinfo version
101
+ 0.1.0
102
+ $ ci-helper distinfo is_pure
103
+ true
104
+ $ ci-helper distinfo has_env_markers
105
+ false
106
+ ```
107
+
108
+ ## Full help text
109
+
110
+ ```shell
111
+ $ ci-helper -h
112
+ usage: ci-helper [-h] [--version] {pythons,defaultpython,distinfo} ...
113
+
114
+ positional arguments:
115
+ {pythons,defaultpython,distinfo}
116
+ Action to perform
117
+ pythons Output list of stable Python versions that have not yet reached end of life, see `ci-helper pythons -h`
118
+ defaultpython Output the second-latest stable Python version in X.Y format, useful as a good choice for a default python version
119
+ distinfo Output info about the distribution, see `ci-helper distinfo -h`
120
+
121
+ options:
122
+ -h, --help show this help message and exit
123
+ --version show program's version number and exit
124
+ ```
125
+
126
+ ```shell
127
+ $ ci-helper pythons -h
128
+ usage: ci-helper pythons [-h] [--cibw]
129
+
130
+ options:
131
+ -h, --help show this help message and exit
132
+ --cibw Output as a space-separated list in the format `cpXY-* cpXY-*` as appropriate for the CIBW_BUILD environment variable to build for all
133
+ stable CPython versions, otherwise versions are output as a comma-separated list in the format X.Y,X.Y
134
+ ```
135
+
136
+ ```shell
137
+ $ ci-helper defaultpython -h
138
+ usage: ci-helper defaultpython [-h]
139
+
140
+ options:
141
+ -h, --help show this help message and exit
142
+ ```
143
+
144
+ ```shell
145
+ $ ci-helper distinfo -h
146
+ usage: ci-helper distinfo [-h] [{name,version,is_pure,has_env_markers}]
147
+
148
+ positional arguments:
149
+ {name,version,is_pure,has_env_markers}
150
+ Name of field to output as a single json value, if not given, all info is output as json
151
+
152
+ options:
153
+ -h, --help show this help message and exit
154
+ ```
155
+
@@ -0,0 +1,17 @@
1
+ .gitignore
2
+ LICENSE.txt
3
+ README.md
4
+ ci_distinfo.py
5
+ pyproject.toml
6
+ setup.cfg
7
+ setup.py
8
+ ci_helper/__init__.py
9
+ ci_helper/__main__.py
10
+ ci_helper/__version__.py
11
+ ci_helper/ci_distinfo.py
12
+ ci_helper.egg-info/PKG-INFO
13
+ ci_helper.egg-info/SOURCES.txt
14
+ ci_helper.egg-info/dependency_links.txt
15
+ ci_helper.egg-info/entry_points.txt
16
+ ci_helper.egg-info/requires.txt
17
+ ci_helper.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ci-helper = ci_helper.__main__:main
@@ -0,0 +1,4 @@
1
+ setuptools_scm
2
+ importlib_metadata
3
+ toml
4
+ requests
@@ -0,0 +1 @@
1
+ ci_helper
@@ -0,0 +1,2 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel", "setuptools_scm"]
@@ -0,0 +1,35 @@
1
+ [metadata]
2
+ name = ci-helper
3
+ description = Get info on how a package should be built on CI
4
+ long_description = file: README.md
5
+ long_description_content_type = text/markdown
6
+ author = Christopher Billington
7
+ author_email = chrisjbillington@gmail.com
8
+ url = http://github.com/chrisjbillington/ci-helper
9
+ project_urls =
10
+ Source Code=https://github.com/chrisjbillington/ci-helper
11
+ Download=https://github.com/chrisjbillington/ci-helper/releases
12
+ Tracker=https://github.com/chrisjbillington/ci-helper/issues
13
+ keywords = build setuptools conda
14
+ license = MIT
15
+ classifiers =
16
+ License :: OSI Approved :: MIT License
17
+ Programming Language :: Python :: 3 :: Only
18
+
19
+ [options]
20
+ packages = find:
21
+ python_requires = >=3.8
22
+ install_requires =
23
+ setuptools_scm
24
+ importlib_metadata
25
+ toml
26
+ requests
27
+
28
+ [options.entry_points]
29
+ console_scripts =
30
+ ci-helper = ci_helper.__main__:main
31
+
32
+ [egg_info]
33
+ tag_build =
34
+ tag_date = 0
35
+
@@ -0,0 +1,29 @@
1
+ import sys
2
+ import os
3
+ from setuptools import setup
4
+ import sysconfig
5
+ from pathlib import Path
6
+
7
+ # Normally packages don't have to do this - the dist_conda command should be
8
+ # automatically available. But since we're installing it, it isn't there yet!
9
+ from ci_helper.ci_distinfo import ci_distinfo
10
+ CMDCLASS = {'ci_distinfo': ci_distinfo}
11
+
12
+ VERSION_SCHEME = {
13
+ "version_scheme": os.getenv("SCM_VERSION_SCHEME", "guess-next-dev"),
14
+ "local_scheme": os.getenv("SCM_LOCAL_SCHEME", "node-and-date"),
15
+ }
16
+
17
+ SITE_PACKAGES = sysconfig.get_path('purelib')
18
+
19
+ # Add the dist_conda command to the distlib vendored in setuptools:
20
+ setuptools_distutils = Path(SITE_PACKAGES) / 'setuptools' / '_distutils' / 'command'
21
+ DATA_FILES = [
22
+ (str(setuptools_distutils.relative_to(sys.prefix)), ["ci_distinfo.py"]),
23
+ ]
24
+ setup(
25
+ use_scm_version=VERSION_SCHEME,
26
+ cmdclass=CMDCLASS,
27
+ data_files=DATA_FILES,
28
+ )
29
+