|
1 | 1 | #!/usr/bin/env python
|
2 | 2 | # flake8: noqa
|
3 |
| -import os |
4 |
| -from distutils import log |
5 |
| -from distutils.core import Command |
6 |
| -from distutils.command.build import build as _build |
7 |
| -from setuptools import setup, find_packages |
8 |
| -from setuptools.command.develop import develop as _develop |
9 |
| -from setuptools.command.sdist import sdist as _sdist |
10 |
| -from setuptools.command.install import install as _install |
11 |
| - |
12 |
| - |
13 |
| -def check_output(*args, **kwargs): |
14 |
| - from subprocess import Popen |
15 |
| - |
16 |
| - proc = Popen(*args, **kwargs) |
17 |
| - output, _ = proc.communicate() |
18 |
| - rv = proc.poll() |
19 |
| - assert rv == 0, output |
20 |
| - |
21 |
| - |
22 |
| -class build_regexes(Command): |
23 |
| - description = "build supporting regular expressions from uap-core" |
24 |
| - user_options = [ |
25 |
| - ("work-path=", "w", "The working directory for source files. Defaults to ."), |
26 |
| - ("build-lib=", "b", "directory for script runtime modules"), |
27 |
| - ( |
28 |
| - "inplace", |
29 |
| - "i", |
30 |
| - "ignore build-lib and put compiled javascript files into the source " |
31 |
| - + "directory alongside your pure Python modules", |
32 |
| - ), |
33 |
| - ( |
34 |
| - "force", |
35 |
| - "f", |
36 |
| - "Force rebuilding of static content. Defaults to rebuilding on version " |
37 |
| - "change detection.", |
38 |
| - ), |
39 |
| - ] |
40 |
| - boolean_options = ["force"] |
41 |
| - |
42 |
| - def initialize_options(self): |
43 |
| - self.build_lib = None |
44 |
| - self.force = None |
45 |
| - self.work_path = None |
46 |
| - self.inplace = None |
47 |
| - |
48 |
| - def finalize_options(self): |
49 |
| - install = self.distribution.get_command_obj("install") |
50 |
| - sdist = self.distribution.get_command_obj("sdist") |
51 |
| - build_ext = self.distribution.get_command_obj("build_ext") |
52 |
| - |
53 |
| - if self.inplace is None: |
54 |
| - self.inplace = ( |
55 |
| - (build_ext.inplace or install.finalized or sdist.finalized) and 1 or 0 |
56 |
| - ) |
| 3 | +from contextlib import suppress |
| 4 | +from os import fspath |
| 5 | +from pathlib import Path |
| 6 | +from typing import Optional, List, Dict |
57 | 7 |
|
58 |
| - if self.inplace: |
59 |
| - self.build_lib = "./src" |
60 |
| - else: |
61 |
| - self.set_undefined_options("build", ("build_lib", "build_lib")) |
62 |
| - if self.work_path is None: |
63 |
| - self.work_path = os.path.realpath(os.path.join(os.path.dirname(__file__))) |
| 8 | +from setuptools import setup, Command, find_namespace_packages |
| 9 | +from setuptools.command.build import build, SubCommand |
| 10 | +from setuptools.command.editable_wheel import editable_wheel |
| 11 | + |
| 12 | +import yaml |
| 13 | + |
| 14 | + |
| 15 | +build.sub_commands.insert(0, ("compile-regexes", None)) |
| 16 | + |
| 17 | + |
| 18 | +class CompileRegexes(Command, SubCommand): |
| 19 | + def initialize_options(self) -> None: |
| 20 | + self.pkg_name: Optional[str] = None |
64 | 21 |
|
65 |
| - def run(self): |
| 22 | + def finalize_options(self) -> None: |
| 23 | + self.pkg_name = self.distribution.get_name().replace("-", "_") |
| 24 | + |
| 25 | + def get_source_files(self) -> List[str]: |
| 26 | + return ["uap-core/regexes.yaml"] |
| 27 | + |
| 28 | + def get_outputs(self) -> List[str]: |
| 29 | + return [f"{self.pkg_name}/_regexes.py"] |
| 30 | + |
| 31 | + def get_output_mapping(self) -> Dict[str, str]: |
| 32 | + return dict(zip(self.get_source_files(), self.get_outputs())) |
| 33 | + |
| 34 | + def run(self) -> None: |
| 35 | + # FIXME: check git / submodules? |
| 36 | + """ |
66 | 37 | work_path = self.work_path
|
67 | 38 | if not os.path.exists(os.path.join(work_path, ".git")):
|
68 | 39 | return
|
69 | 40 |
|
70 | 41 | log.info("initializing git submodules")
|
71 | 42 | check_output(["git", "submodule", "init"], cwd=work_path)
|
72 | 43 | check_output(["git", "submodule", "update"], cwd=work_path)
|
| 44 | + """ |
| 45 | + if not self.pkg_name: |
| 46 | + return # or error? |
73 | 47 |
|
74 |
| - yaml_src = os.path.join(work_path, "uap-core", "regexes.yaml") |
75 |
| - if not os.path.exists(yaml_src): |
| 48 | + yaml_src = Path("uap-core", "regexes.yaml") |
| 49 | + if not yaml_src.is_file(): |
76 | 50 | raise RuntimeError(
|
77 |
| - "Unable to find regexes.yaml, should be at %r" % yaml_src |
| 51 | + f"Unable to find regexes.yaml, should be at {yaml_src!r}" |
78 | 52 | )
|
79 | 53 |
|
80 |
| - def force_bytes(text): |
81 |
| - if text is None: |
82 |
| - return text |
83 |
| - return text.encode("utf8") |
84 |
| - |
85 | 54 | def write_params(fields):
|
86 | 55 | # strip trailing None values
|
87 | 56 | while len(fields) > 1 and fields[-1] is None:
|
88 | 57 | fields.pop()
|
89 | 58 |
|
90 | 59 | for field in fields:
|
91 |
| - fp.write((" %r,\n" % field).encode("utf-8")) |
| 60 | + fp.write((f" {field!r},\n").encode()) |
| 61 | + |
| 62 | + with yaml_src.open("rb") as f: |
| 63 | + regexes = yaml.safe_load(f) |
92 | 64 |
|
93 |
| - import yaml |
| 65 | + if self.editable_mode: |
| 66 | + dist_dir = Path("src") |
| 67 | + else: |
| 68 | + dist_dir = Path(self.get_finalized_command("bdist_wheel").bdist_dir) |
94 | 69 |
|
95 |
| - log.info("compiling regexes.yaml -> _regexes.py") |
96 |
| - with open(yaml_src, "rb") as fp: |
97 |
| - regexes = yaml.safe_load(fp) |
| 70 | + outdir = dist_dir / self.pkg_name |
| 71 | + outdir.mkdir(parents=True, exist_ok=True) |
98 | 72 |
|
99 |
| - lib_dest = os.path.join(self.build_lib, "ua_parser") |
100 |
| - if not os.path.exists(lib_dest): |
101 |
| - os.makedirs(lib_dest) |
| 73 | + dest = outdir / "_regexes.py" |
102 | 74 |
|
103 |
| - py_dest = os.path.join(lib_dest, "_regexes.py") |
104 |
| - with open(py_dest, "wb") as fp: |
| 75 | + with dest.open("wb") as fp: |
105 | 76 | # fmt: off
|
106 | 77 | fp.write(b"# -*- coding: utf-8 -*-\n")
|
107 |
| - fp.write(b"############################################\n") |
108 |
| - fp.write(b"# NOTICE: This file is autogenerated from #\n") |
109 |
| - fp.write(b"# regexes.yaml. Do not edit by hand, #\n") |
110 |
| - fp.write(b"# instead, re-run `setup.py build_regexes` #\n") |
111 |
| - fp.write(b"############################################\n") |
| 78 | + fp.write(b"########################################################\n") |
| 79 | + fp.write(b"# NOTICE: This file is autogenerated from regexes.yaml #\n") |
| 80 | + fp.write(b"########################################################\n") |
112 | 81 | fp.write(b"\n")
|
113 | 82 | fp.write(b"from .user_agent_parser import (\n")
|
114 | 83 | fp.write(b" UserAgentParser, DeviceParser, OSParser,\n")
|
@@ -156,77 +125,9 @@ def write_params(fields):
|
156 | 125 | fp.write(b"]\n")
|
157 | 126 | # fmt: on
|
158 | 127 |
|
159 |
| - self.update_manifest() |
160 |
| - |
161 |
| - def update_manifest(self): |
162 |
| - sdist = self.distribution.get_command_obj("sdist") |
163 |
| - if not sdist.finalized: |
164 |
| - return |
165 |
| - |
166 |
| - sdist.filelist.files.append("src/ua_parser/_regexes.py") |
167 |
| - |
168 |
| - |
169 |
| -class develop(_develop): |
170 |
| - def run(self): |
171 |
| - self.run_command("build_regexes") |
172 |
| - _develop.run(self) |
173 |
| - |
174 |
| - |
175 |
| -class install(_install): |
176 |
| - def run(self): |
177 |
| - self.run_command("build_regexes") |
178 |
| - _install.run(self) |
179 |
| - |
180 |
| - |
181 |
| -class build(_build): |
182 |
| - def run(self): |
183 |
| - self.run_command("build_regexes") |
184 |
| - _build.run(self) |
185 |
| - |
186 |
| - |
187 |
| -class sdist(_sdist): |
188 |
| - sub_commands = _sdist.sub_commands + [("build_regexes", None)] |
189 |
| - |
190 |
| - |
191 |
| -cmdclass = { |
192 |
| - "sdist": sdist, |
193 |
| - "develop": develop, |
194 |
| - "build": build, |
195 |
| - "install": install, |
196 |
| - "build_regexes": build_regexes, |
197 |
| -} |
198 |
| - |
199 | 128 |
|
200 | 129 | setup(
|
201 |
| - name="ua-parser", |
202 |
| - version="0.16.1", |
203 |
| - description="Python port of Browserscope's user agent parser", |
204 |
| - author="PBS", |
205 |
| - |
206 |
| - packages=find_packages(where="src"), |
207 |
| - package_dir={"": "src"}, |
208 |
| - license="Apache 2.0", |
209 |
| - zip_safe=False, |
210 |
| - url="https://github.com/ua-parser/uap-python", |
211 |
| - include_package_data=True, |
212 |
| - setup_requires=["pyyaml"], |
213 |
| - install_requires=[], |
214 |
| - cmdclass=cmdclass, |
215 |
| - classifiers=[ |
216 |
| - "Development Status :: 4 - Beta", |
217 |
| - "Environment :: Web Environment", |
218 |
| - "Intended Audience :: Developers", |
219 |
| - "Operating System :: OS Independent", |
220 |
| - "License :: OSI Approved :: Apache Software License", |
221 |
| - "Programming Language :: Python", |
222 |
| - "Topic :: Internet :: WWW/HTTP", |
223 |
| - "Topic :: Software Development :: Libraries :: Python Modules", |
224 |
| - "Programming Language :: Python", |
225 |
| - "Programming Language :: Python :: 3.8", |
226 |
| - "Programming Language :: Python :: 3.9", |
227 |
| - "Programming Language :: Python :: 3.10", |
228 |
| - "Programming Language :: Python :: 3.11", |
229 |
| - "Programming Language :: Python :: Implementation :: CPython", |
230 |
| - "Programming Language :: Python :: Implementation :: PyPy", |
231 |
| - ], |
| 130 | + cmdclass={ |
| 131 | + "compile-regexes": CompileRegexes, |
| 132 | + } |
232 | 133 | )
|
0 commit comments