partis-pyproj 0.1.3rc3__tar.gz → 0.1.4__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.
Files changed (120) hide show
  1. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/PKG-INFO +18 -17
  2. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/pyproject.toml +2 -2
  3. partis_pyproj-0.1.4/setup.py +211 -0
  4. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/builder/builder.py +117 -3
  5. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/builder/cargo.py +3 -4
  6. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/builder/cmake.py +5 -10
  7. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/builder/meson.py +5 -10
  8. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/builder/process.py +3 -6
  9. partis_pyproj-0.1.4/src/pyproj/file.py +64 -0
  10. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/pyproj.py +5 -3
  11. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/validate.py +6 -1
  12. partis_pyproj-0.1.3rc3/setup.py +0 -211
  13. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/LICENSE.txt +0 -0
  14. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/README.rst +0 -0
  15. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/__init__.py +0 -0
  16. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/__main__.py +0 -0
  17. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/conf.py +0 -0
  18. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/glossary.rst +0 -0
  19. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/index.rst +0 -0
  20. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/backend.rst +0 -0
  21. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/builder.rst +0 -0
  22. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/dist_file.rst +0 -0
  23. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/index.rst +0 -0
  24. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/load_module.rst +0 -0
  25. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/norms.rst +0 -0
  26. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/path.rst +0 -0
  27. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/pep.rst +0 -0
  28. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/pkginfo.rst +0 -0
  29. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/pptoml.rst +0 -0
  30. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/pyproj.rst +0 -0
  31. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/doc/src/validate.rst +0 -0
  32. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/__init__.py +0 -0
  33. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/_legacy_setup.py +0 -0
  34. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/_nonprintable.py +0 -0
  35. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/backend.py +0 -0
  36. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/builder/__init__.py +0 -0
  37. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/__init__.py +0 -0
  38. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/dist_base.py +0 -0
  39. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/dist_binary.py +0 -0
  40. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/dist_copy.py +0 -0
  41. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/dist_source.py +0 -0
  42. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/dist_targz.py +0 -0
  43. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/dist_file/dist_zip.py +0 -0
  44. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/legacy.py +0 -0
  45. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/load_module.py +0 -0
  46. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/norms.py +0 -0
  47. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/path/__init__.py +0 -0
  48. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/path/match.py +0 -0
  49. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/path/pattern.py +0 -0
  50. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/path/utils.py +0 -0
  51. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/pep.py +0 -0
  52. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/pkginfo.py +0 -0
  53. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/src/pyproj/pptoml.py +0 -0
  54. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/__init__.py +0 -0
  55. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/__main__.py +0 -0
  56. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/noxfile.py +0 -0
  57. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_1/pyproject.toml +0 -0
  58. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_1/src/test_pkg/pure_mod/pure_mod.py +0 -0
  59. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_1/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py +0 -0
  60. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_1/src/test_pkg/sub_mod/sub_sub_mod/good_file.py +0 -0
  61. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_2/pkgaux/__init__.py +0 -0
  62. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_2/pyproject.toml +0 -0
  63. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_2/src/test_pkg/pure_mod/pure_mod.py +0 -0
  64. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_2/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py +0 -0
  65. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_2/src/test_pkg/sub_mod/sub_sub_mod/good_file.py +0 -0
  66. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_3/pyproject.toml +0 -0
  67. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_4/pkgaux/__init__.py +0 -0
  68. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_4/pyproject.toml +0 -0
  69. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_4/src/test_pkg/pure_mod/pure_mod.py +0 -0
  70. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_4/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py +0 -0
  71. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_4/src/test_pkg/sub_mod/sub_sub_mod/good_file.py +0 -0
  72. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_5/pkgaux/__init__.py +0 -0
  73. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_5/pyproject.toml +0 -0
  74. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_5/src/test_pkg/pure_mod/pure_mod.py +0 -0
  75. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_5/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py +0 -0
  76. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_bad_5/src/test_pkg/sub_mod/sub_sub_mod/good_file.py +0 -0
  77. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/pkgaux/__init__.py +0 -0
  78. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/pyproject.toml +0 -0
  79. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/src/test_pkg/pure_mod/pure_mod.py +0 -0
  80. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/src/test_pkg/sub_mod/bad_file.py +0 -0
  81. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/src/test_pkg/sub_mod/good_file.py +0 -0
  82. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py +0 -0
  83. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_base/src/test_pkg/sub_mod/sub_sub_mod/good_file.py +0 -0
  84. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_cmake_1/CMakeLists.txt +0 -0
  85. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_cmake_1/pyproject.toml +0 -0
  86. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_cmake_1/src/test_pkg/CMakeLists.txt +0 -0
  87. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_cmake_1/src/test_pkg/plat_mod.pyx +0 -0
  88. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_cmake_1/src/test_pkg/pure_mod.py +0 -0
  89. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_1/meson.build +0 -0
  90. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_1/meson_options.txt +0 -0
  91. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_1/pyproject.toml +0 -0
  92. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_1/src/test_pkg/plat_mod.pyx +0 -0
  93. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_1/src/test_pkg/pure_mod.py +0 -0
  94. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_2/meson.build +0 -0
  95. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_2/meson_options.txt +0 -0
  96. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_2/pyproject.toml +0 -0
  97. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_2/src/test_pkg/plat_mod.pyx +0 -0
  98. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_2/src/test_pkg/pure_mod.py +0 -0
  99. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/bad_link/meson.build +0 -0
  100. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/bad_link/meson_options.txt +0 -0
  101. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/bad_link/pyproject.toml +0 -0
  102. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/bad_link/src/test_pkg/plat_mod.pyx +0 -0
  103. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/bad_link/src/test_pkg/pure_mod.py +0 -0
  104. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/meson.build +0 -0
  105. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/meson_options.txt +0 -0
  106. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/pyproject.toml +0 -0
  107. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/src/test_pkg/plat_mod.pyx +0 -0
  108. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_meson_bad_1/src/test_pkg/pure_mod.py +0 -0
  109. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_min/pure_mod.py +0 -0
  110. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/pkg_min/pyproject.toml +0 -0
  111. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/sitecustom/partis-sitecustom.pth +0 -0
  112. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/sitecustom/pyproject.toml +0 -0
  113. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_00_validate.py +0 -0
  114. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_01_norms.py +0 -0
  115. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_02_path.py +0 -0
  116. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_03_dist.py +0 -0
  117. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_04_load_module.py +0 -0
  118. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_05_pkginfo.py +0 -0
  119. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_06_pyproj.py +0 -0
  120. {partis_pyproj-0.1.3rc3 → partis_pyproj-0.1.4}/test/test_07_backend.py +0 -0
@@ -1,47 +1,48 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: partis-pyproj
3
- Version: 0.1.3rc3
3
+ Version: 0.1.4
4
4
  Requires-Python: >=3.6.2
5
5
  Author-email: "Nanohmics Inc." <software.support@nanohmics.com>
6
6
  Maintainer-email: "Nanohmics Inc." <software.support@nanohmics.com>
7
7
  Summary: Minimal set of Python project utilities (PEP-517/621)
8
8
  License-File: LICENSE.txt
9
- Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: POSIX :: Linux
10
+ Classifier: Programming Language :: Python :: 3
10
11
  Classifier: Programming Language :: Python
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Topic :: Software Development :: Build Tools
11
14
  Classifier: Operating System :: Microsoft :: Windows
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Intended Audience :: Developers
14
16
  Classifier: Development Status :: 4 - Beta
15
- Classifier: Topic :: Software Development :: Build Tools
16
- Classifier: License :: OSI Approved :: BSD License
17
17
  Provides-Extra: meson
18
18
  Provides-Extra: cmake
19
19
  Provides-Extra: doc
20
20
  Provides-Extra: test
21
21
  Provides-Extra: cov
22
22
  Provides-Extra: lint
23
- Requires-Dist: tomli>=1.2.3
24
- Requires-Dist: packaging==21.3
23
+ Requires-Dist: packaging>=21.3
25
24
  Requires-Dist: wheel
25
+ Requires-Dist: packaging==21.3
26
26
  Requires-Dist: importlib_metadata; python_version < "3.8"
27
- Requires-Dist: meson>=0.61.3; extra == "meson"
27
+ Requires-Dist: tomli>=1.2.3
28
28
  Requires-Dist: ninja>=1.10.2.3; extra == "meson"
29
+ Requires-Dist: meson>=0.61.3; extra == "meson"
29
30
  Requires-Dist: ninja>=1.10.2.3; extra == "cmake"
30
31
  Requires-Dist: cmake>=3.24.3; extra == "cmake"
31
32
  Requires-Dist: partis-utils[sphinx]>=0.1.3rc3; extra == "doc"
32
- Requires-Dist: Cython>=0.29.18; extra == "test"
33
33
  Requires-Dist: pytest>=6.2.5; extra == "test"
34
- Requires-Dist: tomli>=1.2.3; extra == "test"
35
- Requires-Dist: build>=0.7.0; extra == "test"
36
34
  Requires-Dist: cmake>=3.24.3; extra == "test"
37
- Requires-Dist: pip>=18.1; extra == "test"
38
- Requires-Dist: pytest-cov>=3.0.0; extra == "test"
39
- Requires-Dist: numpy; extra == "test"
40
- Requires-Dist: meson>=0.61.3; extra == "test"
41
35
  Requires-Dist: ninja>=1.10.2.3; extra == "test"
36
+ Requires-Dist: numpy; extra == "test"
42
37
  Requires-Dist: coverage[toml]>=6.2; extra == "test"
43
- Requires-Dist: pytest_mock>=3.6.1; extra == "test"
38
+ Requires-Dist: build>=0.7.0; extra == "test"
44
39
  Requires-Dist: nox>=2021.10.1; extra == "test"
40
+ Requires-Dist: pytest_mock>=3.6.1; extra == "test"
41
+ Requires-Dist: meson>=0.61.3; extra == "test"
42
+ Requires-Dist: pip>=18.1; extra == "test"
43
+ Requires-Dist: tomli>=1.2.3; extra == "test"
44
+ Requires-Dist: Cython>=0.29.18; extra == "test"
45
+ Requires-Dist: pytest-cov>=3.0.0; extra == "test"
45
46
  Requires-Dist: coverage[toml]>=6.2; extra == "cov"
46
47
  Requires-Dist: pyflakes==2.4.0; extra == "lint"
47
48
  Description-Content-Type: text/x-rst
@@ -26,7 +26,7 @@
26
26
 
27
27
  [project]
28
28
  name = "partis-pyproj"
29
- version = "0.1.3rc3"
29
+ version = "0.1.4"
30
30
  description = "Minimal set of Python project utilities (PEP-517/621)"
31
31
  maintainers = [
32
32
  { name = "Nanohmics Inc.", email = "software.support@nanohmics.com" } ]
@@ -44,7 +44,7 @@ classifiers = [
44
44
 
45
45
  requires-python = ">= 3.6.2"
46
46
  dependencies = [
47
- "packaging == 21.3",
47
+ "packaging >= 21.3",
48
48
  "tomli >= 1.2.3",
49
49
  # NOTE: 'importlib.metadata' not added to stdlib until 3.8
50
50
  "importlib_metadata; python_version < '3.8'" ]
@@ -0,0 +1,211 @@
1
+ """Usage of `setup.py` is deprecated, and is supplied only for legacy installation.
2
+ """
3
+ import sys
4
+ import os
5
+ import os.path as osp
6
+ from pathlib import (
7
+ Path,
8
+ PurePath,
9
+ PurePosixPath)
10
+ import importlib
11
+ import logging
12
+ import argparse
13
+ import subprocess
14
+ import tempfile
15
+ from argparse import RawTextHelpFormatter
16
+ logger = logging.getLogger(__name__)
17
+
18
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19
+ def egg_info( args ):
20
+
21
+ logger.warning(
22
+ "running legacy 'setup.py egg_info'" )
23
+
24
+ dir = Path(args.egg_base).joinpath(EGG_INFO_NAME)
25
+
26
+ if not dir.exists():
27
+ dir.mkdir(parents=True, exist_ok = True)
28
+
29
+ with open(dir.joinpath('PKG-INFO'), 'wb' ) as fp:
30
+ fp.write( PKG_INFO )
31
+
32
+ with open( dir.joinpath('setup_requires.txt'), 'wb' ) as fp:
33
+ fp.write( b'' )
34
+
35
+ with open( dir.joinpath('requires.txt'), 'wb' ) as fp:
36
+ fp.write( REQUIRES )
37
+
38
+ with open( dir.joinpath('SOURCES.txt'), 'wb' ) as fp:
39
+ fp.write( SOURCES )
40
+
41
+ with open( dir.joinpath('top_level.txt'), 'wb' ) as fp:
42
+ fp.write( TOP_LEVEL )
43
+
44
+ with open( dir.joinpath('entry_points.txt'), 'wb' ) as fp:
45
+ fp.write( ENTRY_POINTS )
46
+
47
+ with open(dir.joinpath('dependency_links.txt'), 'wb' ) as fp:
48
+ fp.write( b'' )
49
+
50
+ with open( dir.joinpath('not-zip-safe'), 'wb' ) as fp:
51
+ fp.write( b'' )
52
+
53
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54
+ def bdist_wheel( args ):
55
+
56
+ logger.warning(
57
+ "running legacy 'setup.py bdist_wheel'" )
58
+
59
+ sys.path = backend_path + sys.path
60
+
61
+ backend = importlib.import_module( build_backend )
62
+
63
+ backend.build_wheel(
64
+ wheel_directory = args.dist_dir or args.bdist_dir or '.' )
65
+
66
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
67
+ def install( args ):
68
+
69
+ logger.warning(
70
+ "running legacy 'setup.py install'" )
71
+
72
+ reqs = [ f"{r}" for r in build_requires ]
73
+
74
+ subprocess.check_call([
75
+ sys.executable,
76
+ '-m',
77
+ 'pip',
78
+ 'install',
79
+ *reqs ] )
80
+
81
+ sys.path = backend_path + sys.path
82
+
83
+ backend = importlib.import_module( build_backend )
84
+
85
+ with tempfile.TemporaryDirectory() as tmpdir:
86
+ wheel_name = backend.build_wheel(
87
+ wheel_directory = tmpdir )
88
+
89
+ subprocess.check_call([
90
+ sys.executable,
91
+ '-m',
92
+ 'pip',
93
+ 'install',
94
+ tmpdir.joinpath(wheel_name) ])
95
+
96
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
97
+ def dummy( args ):
98
+ pass
99
+
100
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
101
+ def main():
102
+
103
+ logging.basicConfig(
104
+ level = logging.INFO,
105
+ format = "{name}:{levelname}: {message}",
106
+ style = "{" )
107
+
108
+
109
+ logger.warning(
110
+ "'setup.py' is deprecated, limited support for legacy installs. Upgrade pip." )
111
+
112
+ parser = argparse.ArgumentParser(
113
+ description = __doc__,
114
+ formatter_class = RawTextHelpFormatter )
115
+
116
+ subparsers = parser.add_subparsers()
117
+
118
+ #.............................................................................
119
+ egg_info_parser = subparsers.add_parser( 'egg_info' )
120
+
121
+ egg_info_parser.set_defaults( func = egg_info )
122
+
123
+ egg_info_parser.add_argument( "-e", "--egg-base",
124
+ type = str,
125
+ default = '.' )
126
+
127
+ #.............................................................................
128
+ bdist_wheel_parser = subparsers.add_parser( 'bdist_wheel' )
129
+
130
+ bdist_wheel_parser.set_defaults( func = bdist_wheel )
131
+
132
+ bdist_wheel_parser.add_argument( "-b", "--bdist-dir",
133
+ type = str,
134
+ default = '' )
135
+
136
+ bdist_wheel_parser.add_argument( "-d", "--dist-dir",
137
+ type = str,
138
+ default = '' )
139
+
140
+ bdist_wheel_parser.add_argument( "--python-tag",
141
+ type = str,
142
+ default = None )
143
+
144
+ bdist_wheel_parser.add_argument( "--plat-name",
145
+ type = str,
146
+ default = None )
147
+
148
+ bdist_wheel_parser.add_argument( "--py-limited-api",
149
+ type = str,
150
+ default = None )
151
+
152
+ bdist_wheel_parser.add_argument( "--build-number",
153
+ type = str,
154
+ default = None )
155
+
156
+ #.............................................................................
157
+ install_parser = subparsers.add_parser( 'install' )
158
+
159
+ install_parser.set_defaults( func = install )
160
+
161
+ install_parser.add_argument( "--record",
162
+ type = str,
163
+ default = None )
164
+
165
+ install_parser.add_argument( "--install-headers",
166
+ type = str,
167
+ default = None )
168
+
169
+ install_parser.add_argument( "--compile",
170
+ action='store_true' )
171
+
172
+ install_parser.add_argument( "--single-version-externally-managed",
173
+ action='store_true' )
174
+
175
+ #.............................................................................
176
+ clean_parser = subparsers.add_parser( 'clean' )
177
+
178
+ clean_parser.set_defaults( func = dummy )
179
+
180
+ clean_parser.add_argument( "-a", "--all",
181
+ action='store_true' )
182
+
183
+ args = parser.parse_args( )
184
+
185
+ args.func( args )
186
+
187
+
188
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
189
+ # NOTE: these are templated literal values substituded by the backend when
190
+ # building the source distribution
191
+
192
+ build_backend = 'pyproj.backend'
193
+ backend_path = ['src']
194
+ build_requires = ['importlib_metadata; python_version < "3.8"', 'tomli>=1.2.3', 'wheel', 'packaging==21.3']
195
+
196
+ EGG_INFO_NAME = 'partis-pyproj.egg-info'
197
+
198
+ PKG_INFO = b'Metadata-Version: 2.1\nName: partis-pyproj\nVersion: 0.1.4\nRequires-Python: >=3.6.2\nAuthor-email: "Nanohmics Inc." <software.support@nanohmics.com>\nMaintainer-email: "Nanohmics Inc." <software.support@nanohmics.com>\nSummary: Minimal set of Python project utilities (PEP-517/621)\nLicense-File: LICENSE.txt\nClassifier: Operating System :: POSIX :: Linux\nClassifier: Programming Language :: Python :: 3\nClassifier: Programming Language :: Python\nClassifier: License :: OSI Approved :: BSD License\nClassifier: Topic :: Software Development :: Build Tools\nClassifier: Operating System :: Microsoft :: Windows\nClassifier: Intended Audience :: Developers\nClassifier: Development Status :: 4 - Beta\nProvides-Extra: meson\nProvides-Extra: cmake\nProvides-Extra: doc\nProvides-Extra: test\nProvides-Extra: cov\nProvides-Extra: lint\nRequires-Dist: packaging>=21.3\nRequires-Dist: wheel\nRequires-Dist: packaging==21.3\nRequires-Dist: importlib_metadata; python_version < "3.8"\nRequires-Dist: tomli>=1.2.3\nRequires-Dist: ninja>=1.10.2.3; extra == "meson"\nRequires-Dist: meson>=0.61.3; extra == "meson"\nRequires-Dist: ninja>=1.10.2.3; extra == "cmake"\nRequires-Dist: cmake>=3.24.3; extra == "cmake"\nRequires-Dist: partis-utils[sphinx]>=0.1.3rc3; extra == "doc"\nRequires-Dist: pytest>=6.2.5; extra == "test"\nRequires-Dist: cmake>=3.24.3; extra == "test"\nRequires-Dist: ninja>=1.10.2.3; extra == "test"\nRequires-Dist: numpy; extra == "test"\nRequires-Dist: coverage[toml]>=6.2; extra == "test"\nRequires-Dist: build>=0.7.0; extra == "test"\nRequires-Dist: nox>=2021.10.1; extra == "test"\nRequires-Dist: pytest_mock>=3.6.1; extra == "test"\nRequires-Dist: meson>=0.61.3; extra == "test"\nRequires-Dist: pip>=18.1; extra == "test"\nRequires-Dist: tomli>=1.2.3; extra == "test"\nRequires-Dist: Cython>=0.29.18; extra == "test"\nRequires-Dist: pytest-cov>=3.0.0; extra == "test"\nRequires-Dist: coverage[toml]>=6.2; extra == "cov"\nRequires-Dist: pyflakes==2.4.0; extra == "lint"\nDescription-Content-Type: text/x-rst\n\nThe ``partis.pyproj`` package aims to be very simple and\ntransparent implementation of a PEP-517 build back-end.\n\nhttps://nanohmics.bitbucket.io/doc/partis/pyproj'
199
+
200
+ REQUIRES = b'packaging>=21.3\nwheel\npackaging==21.3\nimportlib_metadata; python_version < "3.8"\ntomli>=1.2.3\nninja>=1.10.2.3; extra == "meson"\nmeson>=0.61.3; extra == "meson"\nninja>=1.10.2.3; extra == "cmake"\ncmake>=3.24.3; extra == "cmake"\npartis-utils[sphinx]>=0.1.3rc3; extra == "doc"\npytest>=6.2.5; extra == "test"\ncmake>=3.24.3; extra == "test"\nninja>=1.10.2.3; extra == "test"\nnumpy; extra == "test"\ncoverage[toml]>=6.2; extra == "test"\nbuild>=0.7.0; extra == "test"\nnox>=2021.10.1; extra == "test"\npytest_mock>=3.6.1; extra == "test"\nmeson>=0.61.3; extra == "test"\npip>=18.1; extra == "test"\ntomli>=1.2.3; extra == "test"\nCython>=0.29.18; extra == "test"\npytest-cov>=3.0.0; extra == "test"\ncoverage[toml]>=6.2; extra == "cov"\npyflakes==2.4.0; extra == "lint"'
201
+
202
+ SOURCES = b'partis_pyproj-0.1.4/src/pyproj/__init__.py\npartis_pyproj-0.1.4/src/pyproj/norms.py\npartis_pyproj-0.1.4/src/pyproj/pep.py\npartis_pyproj-0.1.4/src/pyproj/builder/__init__.py\npartis_pyproj-0.1.4/src/pyproj/builder/builder.py\npartis_pyproj-0.1.4/src/pyproj/builder/cargo.py\npartis_pyproj-0.1.4/src/pyproj/builder/cmake.py\npartis_pyproj-0.1.4/src/pyproj/builder/meson.py\npartis_pyproj-0.1.4/src/pyproj/builder/process.py\npartis_pyproj-0.1.4/src/pyproj/file.py\npartis_pyproj-0.1.4/src/pyproj/load_module.py\npartis_pyproj-0.1.4/src/pyproj/_legacy_setup.py\npartis_pyproj-0.1.4/src/pyproj/_nonprintable.py\npartis_pyproj-0.1.4/src/pyproj/path/__init__.py\npartis_pyproj-0.1.4/src/pyproj/path/match.py\npartis_pyproj-0.1.4/src/pyproj/path/pattern.py\npartis_pyproj-0.1.4/src/pyproj/path/utils.py\npartis_pyproj-0.1.4/src/pyproj/validate.py\npartis_pyproj-0.1.4/src/pyproj/pkginfo.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/dist_targz.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/__init__.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/dist_zip.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/dist_binary.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/dist_base.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/dist_source.py\npartis_pyproj-0.1.4/src/pyproj/dist_file/dist_copy.py\npartis_pyproj-0.1.4/src/pyproj/legacy.py\npartis_pyproj-0.1.4/src/pyproj/backend.py\npartis_pyproj-0.1.4/src/pyproj/pyproj.py\npartis_pyproj-0.1.4/src/pyproj/pptoml.py\npartis_pyproj-0.1.4/doc/conf.py\npartis_pyproj-0.1.4/doc/__init__.py\npartis_pyproj-0.1.4/doc/index.rst\npartis_pyproj-0.1.4/doc/src/pptoml.rst\npartis_pyproj-0.1.4/doc/src/index.rst\npartis_pyproj-0.1.4/doc/src/backend.rst\npartis_pyproj-0.1.4/doc/src/builder.rst\npartis_pyproj-0.1.4/doc/src/validate.rst\npartis_pyproj-0.1.4/doc/src/pkginfo.rst\npartis_pyproj-0.1.4/doc/src/pyproj.rst\npartis_pyproj-0.1.4/doc/src/path.rst\npartis_pyproj-0.1.4/doc/src/pep.rst\npartis_pyproj-0.1.4/doc/src/load_module.rst\npartis_pyproj-0.1.4/doc/src/norms.rst\npartis_pyproj-0.1.4/doc/src/dist_file.rst\npartis_pyproj-0.1.4/doc/__main__.py\npartis_pyproj-0.1.4/doc/glossary.rst\npartis_pyproj-0.1.4/test/pkg_bad_5/src/test_pkg/sub_mod/sub_sub_mod/good_file.py\npartis_pyproj-0.1.4/test/pkg_bad_5/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py\npartis_pyproj-0.1.4/test/pkg_bad_5/src/test_pkg/pure_mod/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_bad_5/pkgaux/__init__.py\npartis_pyproj-0.1.4/test/pkg_bad_5/pyproject.toml\npartis_pyproj-0.1.4/test/__init__.py\npartis_pyproj-0.1.4/test/pkg_meson_2/src/test_pkg/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_meson_2/src/test_pkg/plat_mod.pyx\npartis_pyproj-0.1.4/test/pkg_meson_2/meson.build\npartis_pyproj-0.1.4/test/pkg_meson_2/meson_options.txt\npartis_pyproj-0.1.4/test/pkg_meson_2/pyproject.toml\npartis_pyproj-0.1.4/test/pkg_bad_2/src/test_pkg/sub_mod/sub_sub_mod/good_file.py\npartis_pyproj-0.1.4/test/pkg_bad_2/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py\npartis_pyproj-0.1.4/test/pkg_bad_2/src/test_pkg/pure_mod/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_bad_2/pkgaux/__init__.py\npartis_pyproj-0.1.4/test/pkg_bad_2/pyproject.toml\npartis_pyproj-0.1.4/test/__main__.py\npartis_pyproj-0.1.4/test/test_03_dist.py\npartis_pyproj-0.1.4/test/sitecustom/partis-sitecustom.pth\npartis_pyproj-0.1.4/test/sitecustom/pyproject.toml\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/bad_link/src/test_pkg/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/bad_link/src/test_pkg/plat_mod.pyx\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/bad_link/meson.build\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/bad_link/meson_options.txt\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/bad_link/pyproject.toml\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/src/test_pkg/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/src/test_pkg/plat_mod.pyx\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/meson.build\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/meson_options.txt\npartis_pyproj-0.1.4/test/pkg_meson_bad_1/pyproject.toml\npartis_pyproj-0.1.4/test/pkg_min/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_min/pyproject.toml\npartis_pyproj-0.1.4/test/noxfile.py\npartis_pyproj-0.1.4/test/test_00_validate.py\npartis_pyproj-0.1.4/test/test_04_load_module.py\npartis_pyproj-0.1.4/test/pkg_cmake_1/src/test_pkg/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_cmake_1/src/test_pkg/plat_mod.pyx\npartis_pyproj-0.1.4/test/pkg_cmake_1/src/test_pkg/CMakeLists.txt\npartis_pyproj-0.1.4/test/pkg_cmake_1/CMakeLists.txt\npartis_pyproj-0.1.4/test/pkg_cmake_1/pyproject.toml\npartis_pyproj-0.1.4/test/test_01_norms.py\npartis_pyproj-0.1.4/test/test_05_pkginfo.py\npartis_pyproj-0.1.4/test/pkg_base/src/test_pkg/sub_mod/sub_sub_mod/good_file.py\npartis_pyproj-0.1.4/test/pkg_base/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py\npartis_pyproj-0.1.4/test/pkg_base/src/test_pkg/sub_mod/good_file.py\npartis_pyproj-0.1.4/test/pkg_base/src/test_pkg/sub_mod/bad_file.py\npartis_pyproj-0.1.4/test/pkg_base/src/test_pkg/pure_mod/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_base/pkgaux/__init__.py\npartis_pyproj-0.1.4/test/pkg_base/pyproject.toml\npartis_pyproj-0.1.4/test/test_06_pyproj.py\npartis_pyproj-0.1.4/test/test_02_path.py\npartis_pyproj-0.1.4/test/pkg_bad_3/pyproject.toml\npartis_pyproj-0.1.4/test/pkg_meson_1/src/test_pkg/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_meson_1/src/test_pkg/plat_mod.pyx\npartis_pyproj-0.1.4/test/pkg_meson_1/meson.build\npartis_pyproj-0.1.4/test/pkg_meson_1/meson_options.txt\npartis_pyproj-0.1.4/test/pkg_meson_1/pyproject.toml\npartis_pyproj-0.1.4/test/test_07_backend.py\npartis_pyproj-0.1.4/test/pkg_bad_4/src/test_pkg/sub_mod/sub_sub_mod/good_file.py\npartis_pyproj-0.1.4/test/pkg_bad_4/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py\npartis_pyproj-0.1.4/test/pkg_bad_4/src/test_pkg/pure_mod/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_bad_4/pkgaux/__init__.py\npartis_pyproj-0.1.4/test/pkg_bad_4/pyproject.toml\npartis_pyproj-0.1.4/test/pkg_bad_1/src/test_pkg/sub_mod/sub_sub_mod/good_file.py\npartis_pyproj-0.1.4/test/pkg_bad_1/src/test_pkg/sub_mod/sub_sub_mod/bad_file.py\npartis_pyproj-0.1.4/test/pkg_bad_1/src/test_pkg/pure_mod/pure_mod.py\npartis_pyproj-0.1.4/test/pkg_bad_1/pyproject.toml\npartis_pyproj-0.1.4/pyproject.toml\npartis_pyproj-0.1.4/LICENSE.txt\npartis_pyproj-0.1.4/README.rst'
203
+
204
+ TOP_LEVEL = b''
205
+
206
+ ENTRY_POINTS = b''
207
+
208
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
209
+
210
+ if __name__ == "__main__":
211
+ exit( main() )
@@ -1,10 +1,10 @@
1
1
  import os
2
- import os.path as osp
3
- import tempfile
2
+ import re
4
3
  import shutil
5
4
  import subprocess
6
5
  from pathlib import Path
7
6
 
7
+ from ..file import tail
8
8
  from ..validate import (
9
9
  validating,
10
10
  ValidationError,
@@ -16,6 +16,12 @@ from ..load_module import EntryPoint
16
16
  from ..path import (
17
17
  subdir )
18
18
 
19
+ ERROR_REC = re.compile(r"error:", re.I)
20
+
21
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22
+ class BuildCommandError(ValidationError):
23
+ pass
24
+
19
25
  #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
26
  class Builder:
21
27
  """Run build setup, compile, install commands
@@ -107,10 +113,20 @@ class Builder:
107
113
  logger = self.logger,
108
114
  entry = target.entry )
109
115
 
116
+ log_dir = self.root/'build'/'logs'
117
+ if not log_dir.exists():
118
+ log_dir.mkdir(parents=True)
119
+
120
+ runner = ProcessRunner(
121
+ logger = self.logger,
122
+ log_dir=log_dir,
123
+ target_name=f"target_{i:02d}")
124
+
110
125
  self.logger.info(f"Build targets[{i}]")
111
126
  self.logger.info(f"Working dir: {work_dir}")
112
127
  self.logger.info(f"Source dir: {src_dir}")
113
128
  self.logger.info(f"Build dir: {build_dir}")
129
+ self.logger.info(f"Log dir: {log_dir}")
114
130
  self.logger.info(f"Prefix: {prefix}")
115
131
 
116
132
  cwd = os.getcwd()
@@ -127,7 +143,8 @@ class Builder:
127
143
  setup_args = target.setup_args,
128
144
  compile_args = target.compile_args,
129
145
  install_args = target.install_args,
130
- build_clean = not build_dirty)
146
+ build_clean = not build_dirty,
147
+ runner = runner)
131
148
 
132
149
  finally:
133
150
  os.chdir(cwd)
@@ -151,3 +168,100 @@ class Builder:
151
168
  if build_dir is not None and build_dir.exists() and target.build_clean:
152
169
  self.logger.info(f"Removing build dir: {build_dir}")
153
170
  shutil.rmtree(build_dir)
171
+
172
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173
+ class ProcessRunner:
174
+ #-----------------------------------------------------------------------------
175
+ def __init__(self,
176
+ logger,
177
+ log_dir: Path,
178
+ target_name: str):
179
+
180
+ self.logger = logger
181
+ self.log_dir = log_dir
182
+ self.target_name = target_name
183
+ self.commands = {}
184
+
185
+ #-----------------------------------------------------------------------------
186
+ def run(self, args: list):
187
+ if len(args) == 0:
188
+ raise ValueError(f"Command for {self.target_name} is empty.")
189
+
190
+ cmd_exec = args[0]
191
+ cmd_exec_src = shutil.which(cmd_exec)
192
+
193
+ if cmd_exec_src is None:
194
+ raise ValueError(
195
+ f"Executable does not exist or has in-sufficient permissions: {cmd_exec}")
196
+
197
+ cmd_exec_src = Path(cmd_exec_src).resolve()
198
+ cmd_name = cmd_exec_src.name
199
+ args = [str(cmd_exec_src)]+args[1:]
200
+
201
+ cmd_hist = self.commands.setdefault(cmd_exec_src, [])
202
+ cmd_idx = len(cmd_hist)
203
+ cmd_hist.append(args)
204
+
205
+ run_name = re.sub(r'[^\w]+', "_", cmd_name)
206
+
207
+ stdout_file = self.log_dir/f"{self.target_name}.{run_name}.{cmd_idx:02d}.log"
208
+
209
+ try:
210
+ self.logger.info("Running command: "+' '.join(args))
211
+
212
+ with open(stdout_file, 'wb') as fp:
213
+ subprocess.run(
214
+ args,
215
+ shell=False,
216
+ stdout=fp,
217
+ stderr=subprocess.STDOUT,
218
+ check=True)
219
+
220
+ except subprocess.CalledProcessError as e:
221
+
222
+
223
+ num_windows = 20
224
+ window_size = 5
225
+ with open(stdout_file, 'rb') as fp:
226
+ lines = [
227
+ (lineno,line)
228
+ for lineno,line in enumerate(fp.read().decode('utf-8', errors='replace').splitlines())]
229
+
230
+ suspect_linenos = [
231
+ lineno
232
+ for lineno,line in lines
233
+ if ERROR_REC.search(line)]
234
+
235
+ # suspect_linenos = suspect_linenos[:num_windows]
236
+
237
+ extra = [
238
+ '\n'.join(
239
+ [f"{'':-<70}",f"{'':>4}⋮"]
240
+ +[f"{j:>4d}| {line}" for j,line in lines[i:i+window_size]]
241
+ +[f"{'':>4}⋮"])
242
+ for i in suspect_linenos]
243
+
244
+ m = len(lines)-num_windows
245
+
246
+ if suspect_linenos:
247
+ m = max(m, suspect_linenos[-1])
248
+
249
+ last_lines = lines[m:]
250
+
251
+ if last_lines:
252
+ extra += [
253
+ f"{'':-<70}",
254
+ f"Last {len(last_lines)} lines of command output:",
255
+ f"{'':>4}⋮"]
256
+
257
+ extra += [
258
+ f"{j:>4d}| {line}"
259
+ for j,line in last_lines]
260
+
261
+ extra += [
262
+ f"{'END':>4}| [See log file: {stdout_file}]",
263
+ f"{'':-<70}",]
264
+
265
+ raise BuildCommandError(
266
+ str(e),
267
+ extra='\n'.join(extra)) from None
@@ -25,7 +25,8 @@ def cargo(
25
25
  setup_args: list[str],
26
26
  compile_args: list[str],
27
27
  install_args: list[str],
28
- build_clean: bool ):
28
+ build_clean: bool,
29
+ runner):
29
30
  """Run cargo build
30
31
  """
31
32
 
@@ -51,7 +52,5 @@ def cargo(
51
52
  str(build_dir),
52
53
  '--root', str(prefix) ]
53
54
 
54
- logger.debug(' '.join(compile_args))
55
-
56
- subprocess.check_call(compile_args)
55
+ runner.run(compile_args)
57
56
 
@@ -31,7 +31,8 @@ def cmake(
31
31
  setup_args,
32
32
  compile_args,
33
33
  install_args,
34
- build_clean ):
34
+ build_clean,
35
+ runner):
35
36
  """Run cmake configure and install commands
36
37
 
37
38
  Parameters
@@ -87,13 +88,7 @@ def cmake(
87
88
 
88
89
 
89
90
  if setup_args:
90
- logger.debug(' '.join(setup_args))
91
- subprocess.check_call(setup_args)
91
+ runner.run(setup_args)
92
92
 
93
- logger.debug(' '.join(compile_args))
94
-
95
- subprocess.check_call(compile_args)
96
-
97
- logger.debug(' '.join(install_args))
98
-
99
- subprocess.check_call(install_args)
93
+ runner.run(compile_args)
94
+ runner.run(install_args)
@@ -31,7 +31,8 @@ def meson(
31
31
  setup_args,
32
32
  compile_args,
33
33
  install_args,
34
- build_clean ):
34
+ build_clean,
35
+ runner):
35
36
  """Run meson setup, compile, install commands
36
37
 
37
38
  Parameters
@@ -89,13 +90,7 @@ def meson(
89
90
 
90
91
 
91
92
  if setup_args:
92
- logger.debug(' '.join(setup_args))
93
- subprocess.check_call(setup_args)
93
+ runner.run(setup_args)
94
94
 
95
- logger.debug(' '.join(compile_args))
96
-
97
- subprocess.check_call(compile_args)
98
-
99
- logger.debug(' '.join(install_args))
100
-
101
- subprocess.check_call(install_args)
95
+ runner.run(compile_args)
96
+ runner.run(install_args)
@@ -23,7 +23,8 @@ def process(
23
23
  setup_args,
24
24
  compile_args,
25
25
  install_args,
26
- build_clean ):
26
+ build_clean,
27
+ runner):
27
28
  """Run general three-part set of commands
28
29
 
29
30
  Parameters
@@ -70,9 +71,5 @@ def process(
70
71
  for cmd in [setup_args, compile_args, install_args]:
71
72
 
72
73
  if cmd:
73
- if not shutil.which(cmd[0]):
74
- raise ValueError(f"The program not found: {setup_args[0]}")
75
-
76
- logger.info(f"Running command: {' '.join(cmd)}")
77
- subprocess.check_call(cmd)
74
+ runner.run(cmd)
78
75
 
@@ -0,0 +1,64 @@
1
+ import os
2
+
3
+ #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
+ def tail(path, n, bufsize = 1024, encoding = 'utf-8'):
5
+ """Reads the last n lines from a file
6
+
7
+ Parameters
8
+ ----------
9
+ path : str
10
+ n : int
11
+ Max number of lines to read from the end of the file
12
+ bufsize : int
13
+ Number of bytes to buffer at a time.
14
+
15
+ Returns
16
+ -------
17
+ lines : List[str]
18
+ Up to ``n`` lines from the end of the file
19
+ """
20
+
21
+ bufsize = int(bufsize)
22
+ bufsize = max(1, bufsize)
23
+
24
+ n = int(n)
25
+ n = max( 0, n )
26
+
27
+ buf = bytes()
28
+ nlines = 0
29
+
30
+ head = 0
31
+
32
+ with open( path, 'rb' ) as fp:
33
+ # total number of bytes in the file
34
+ tot = fp.seek( 0, os.SEEK_END )
35
+
36
+ head = tot
37
+
38
+ while nlines < n and head > 0:
39
+ # NOTE: the number of newline characters is one less than number of 'lines'
40
+ nread = min( head, bufsize )
41
+ head -= nread
42
+
43
+ fp.seek( head, os.SEEK_SET )
44
+
45
+ _buf = fp.read( nread )
46
+
47
+ # NOTE: this is not exact, since pairs of '\r\n' may happen on the read
48
+ # boundary, but should count approximately the number of LF, CR, and CR+LF.
49
+ # LF -> 1 + 0 + 0 = 1
50
+ # CR -> 0 + 1 + 0 = 1
51
+ # CR+LF -> 1 + 1 - 1 = 1
52
+ nlines += _buf.count(b'\n') + _buf.count(b'\r') - _buf.count(b'\r\n')
53
+
54
+ buf = _buf + buf
55
+
56
+ if nlines > 0 and head > 0:
57
+ # remove everything before first newline to ensure only complete lines are kept
58
+ i = buf.index(b'\n')
59
+ buf = buf[(i+1):]
60
+
61
+ res = buf.decode(encoding, errors = 'replace')
62
+ lines = res.split('\n')[-n:]
63
+
64
+ return lines
@@ -32,6 +32,7 @@ from .validate import (
32
32
  ValidationWarning,
33
33
  ValidationError,
34
34
  FileOutsideRootError,
35
+ RequiredValueError,
35
36
  valid_dict,
36
37
  validating,
37
38
  valid,
@@ -104,14 +105,15 @@ class PyProjBase:
104
105
 
105
106
  with validating(key = 'tool'):
106
107
  if 'tool' not in self.pptoml:
107
- raise RequiredValueError(f"tool.pyproj is required for backend")
108
+ # TODO: !!!
109
+ raise RequiredValueError("tool.pyproj is required for backend")
108
110
 
109
111
  with validating(key = 'pyproj'):
110
112
  if 'pyproj' not in self.pptoml.tool:
111
- raise RequiredValueError(f"tool.pyproj is required for backend")
113
+ raise RequiredValueError("tool.pyproj is required for backend")
112
114
 
113
115
  if self.project.dynamic and 'prep' not in self.pyproj:
114
- raise ValidationError(f"tool.pyproj.prep is required to resolve project.dynamic")
116
+ raise RequiredValueError("tool.pyproj.prep is required to resolve project.dynamic")
115
117
 
116
118
  #...........................................................................
117
119
  # construct a validator from the tool.pyproj.config table
@@ -67,7 +67,8 @@ class ValidationError( ValueError ):
67
67
  def __init__( self, msg,
68
68
  doc_root = None,
69
69
  doc_file = None,
70
- doc_path = None ):
70
+ doc_path = None,
71
+ extra = None):
71
72
 
72
73
  msg = inspect.cleandoc( msg )
73
74
 
@@ -75,6 +76,7 @@ class ValidationError( ValueError ):
75
76
  self.doc_root = doc_root
76
77
  self.doc_file = doc_file
77
78
  self.doc_path = doc_path or list()
79
+ self.extra = extra
78
80
 
79
81
  super().__init__( msg )
80
82
 
@@ -107,6 +109,9 @@ class ValidationError( ValueError ):
107
109
  if loc:
108
110
  msg += '\n' + loc
109
111
 
112
+ if self.extra:
113
+ msg += '\n' + str(self.extra)
114
+
110
115
  return msg
111
116
 
112
117
  #-----------------------------------------------------------------------------