Skip to content

Commit ecaf94d

Browse files
committed
initial release
Signed-off-by: Filipe Laíns <[email protected]>
0 parents  commit ecaf94d

File tree

5 files changed

+209
-0
lines changed

5 files changed

+209
-0
lines changed

LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright © 2019 Filipe Laíns <[email protected]>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a
4+
copy of this software and associated documentation files (the "Software"),
5+
to deal in the Software without restriction, including without limitation
6+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
7+
and/or sell copies of the Software, and to permit persons to whom the
8+
Software is furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice (including the next
11+
paragraph) shall be included in all copies or substantial portions of the
12+
Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# python-build
2+
3+
A simple, correct PEP517 package builder.
4+
5+
```sh
6+
$ python -m build -h
7+
usage: __main__.py [-h] [--verbose] [--sdist] [--wheel] [--outdir ./dist] [.]
8+
9+
positional arguments:
10+
. source directory (defaults to current directory)
11+
12+
optional arguments:
13+
-h, --help show this help message and exit
14+
--verbose, -v enable verbose output
15+
--sdist, -s build a source package
16+
--wheel, -w build a wheel
17+
--outdir ./dist, -o ./dist
18+
output directory
19+
```

build/__init__.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# SPDX-License-Identifier: MIT
2+
3+
'''
4+
python-build - A simple, correct PEP517 package builder
5+
'''
6+
__version__ = '0.0.1'
7+
8+
import importlib
9+
import os
10+
11+
from typing import List
12+
13+
import pep517.wrappers
14+
import toml
15+
16+
17+
class BuildException(Exception):
18+
pass
19+
20+
21+
class BuildBackendException(Exception):
22+
pass
23+
24+
25+
class ProjectBuilder(object):
26+
def __init__(self, srcdir='.'): # type: (str) -> None
27+
self.srcdir = srcdir
28+
29+
spec_file = os.path.join(srcdir, 'pyproject.toml')
30+
31+
if not os.path.isfile(spec_file):
32+
raise BuildException(f'Missing project file: {spec_file}')
33+
34+
with open(spec_file) as f:
35+
self._spec = toml.load(f)
36+
37+
try:
38+
self._build_system = self._spec['build-system']
39+
self._backend = self._build_system['build-backend']
40+
except KeyError:
41+
raise BuildException('Missing backend definition in project file')
42+
43+
try:
44+
importlib.import_module(self._backend)
45+
except ImportError:
46+
raise BuildException(f"Backend '{self._backend}' is not available")
47+
48+
self.hook = pep517.wrappers.Pep517HookCaller(self.srcdir, self._backend,
49+
backend_path=self._build_system.get('backend-path'))
50+
51+
def check_depencencies(self, distribution): # type: (str) -> List[str]
52+
'''
53+
Returns a set of the missing dependencies
54+
'''
55+
get_requires = getattr(self.hook, f'get_requires_for_build_{distribution}')
56+
57+
dependencies = set()
58+
59+
try:
60+
dependencies.update(get_requires())
61+
except pep517.wrappers.BackendUnavailable as e:
62+
raise e
63+
except Exception as e: # noqa: E722
64+
raise BuildBackendException(f'Backend operation failed: {e}')
65+
66+
missing = []
67+
for dep in dependencies:
68+
try:
69+
importlib.import_module(dep)
70+
except ImportError:
71+
missing.append(dep)
72+
73+
return missing
74+
75+
def build(self, distribution, outdir): # type: (str, str) -> None
76+
'''
77+
Builds a distribution
78+
'''
79+
build = getattr(self.hook, f'build_{distribution}')
80+
81+
try:
82+
build(outdir)
83+
except Exception as e: # noqa: E722
84+
raise BuildBackendException(f'Backend operation failed: {e}')

build/__main__.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# SPDX-License-Identifier: MIT
2+
3+
import argparse
4+
import os
5+
import sys
6+
import traceback
7+
8+
from . import BuildException, BuildBackendException, ProjectBuilder
9+
10+
11+
def _error(msg, code=1): # type: (str, int) -> None
12+
prefix = 'ERROR'
13+
if sys.stdout.isatty():
14+
prefix = '\33[91m' + prefix + '\33[0m'
15+
print(prefix, msg)
16+
exit(code)
17+
18+
19+
if __name__ == '__main__': # noqa: C901
20+
cwd = os.getcwd()
21+
out = os.path.join(cwd, 'dist')
22+
parser = argparse.ArgumentParser()
23+
parser.add_argument('srcdir',
24+
type=str, nargs='?', metavar=cwd, default=cwd,
25+
help='source directory (defaults to current directory)')
26+
parser.add_argument('--verbose', '-v',
27+
action='store_true',
28+
help='enable verbose output')
29+
parser.add_argument('--sdist', '-s',
30+
action='store_true',
31+
help='build a source package')
32+
parser.add_argument('--wheel', '-w',
33+
action='store_true',
34+
help='build a wheel')
35+
parser.add_argument('--outdir', '-o', metavar=out,
36+
type=str, default=out,
37+
help='output directory')
38+
args = parser.parse_args()
39+
40+
distributions = []
41+
42+
if args.sdist:
43+
distributions.append('sdist')
44+
if args.wheel:
45+
distributions.append('wheel')
46+
47+
# default targets
48+
if not distributions:
49+
distributions = ['sdist', 'wheel']
50+
51+
try:
52+
builder = ProjectBuilder(args.srcdir)
53+
54+
for dist in distributions:
55+
missing = builder.check_depencencies(dist)
56+
if missing:
57+
_error(f'Missing dependencies: {" ".join(missing)}')
58+
59+
builder.build(dist, args.outdir)
60+
except BuildException as e:
61+
_error(str(e))
62+
except BuildBackendException as e:
63+
if sys.version_info >= (3, 5):
64+
print(traceback.format_exc(-1))
65+
else:
66+
print(traceback.format_exc())
67+
_error(str(e))

pyproject.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[build-system]
2+
requires = ["flit_core >=2,<3"]
3+
build-backend = "flit_core.buildapi"
4+
5+
[tool.flit.metadata]
6+
module = "build"
7+
author = "Filipe Laíns"
8+
author-email = "[email protected]"
9+
home-page = "https://github.com/FFY00/python-build"
10+
description-file = "README.md"
11+
requires = [
12+
"toml",
13+
"pep517",
14+
]
15+
classifiers = [
16+
"License :: OSI Approved :: MIT License",
17+
"Programming Language :: Python :: 2.7",
18+
"Programming Language :: Python :: 3",
19+
]

0 commit comments

Comments
 (0)