pygitpub 0.0.59__tar.gz → 0.0.60__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.
- {pygitpub-0.0.59 → pygitpub-0.0.60}/.gitignore +51 -15
- {pygitpub-0.0.59 → pygitpub-0.0.60}/PKG-INFO +8 -5
- {pygitpub-0.0.59 → pygitpub-0.0.60}/README.md +4 -2
- {pygitpub-0.0.59 → pygitpub-0.0.60}/pyproject.toml +27 -4
- {pygitpub-0.0.59 → pygitpub-0.0.60}/src/pygitpub/main.py +9 -8
- {pygitpub-0.0.59 → pygitpub-0.0.60}/src/pygitpub/static.py +1 -1
- pygitpub-0.0.60/src/pygitpub/utils/lua.py +68 -0
- pygitpub-0.0.59/src/pygitpub/utils/importlib.py +0 -16
- {pygitpub-0.0.59 → pygitpub-0.0.60}/LICENSE +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.60}/src/pygitpub/__init__.py +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.60}/src/pygitpub/configs.py +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.60}/src/pygitpub/utils/__init__.py +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.60}/src/pygitpub/utils/misc.py +0 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# generated
|
|
2
|
-
/build/
|
|
3
2
|
/toolchain/
|
|
4
3
|
/dist/
|
|
5
|
-
/target/
|
|
6
4
|
/out/
|
|
7
5
|
/debug/
|
|
8
6
|
/download/
|
|
@@ -64,7 +62,7 @@ modules.order
|
|
|
64
62
|
|
|
65
63
|
# sphinx
|
|
66
64
|
/docs/_build/
|
|
67
|
-
/docs/.doctrees/
|
|
65
|
+
/docs/.doctrees/
|
|
68
66
|
|
|
69
67
|
# mdBook build output
|
|
70
68
|
/docs/book/
|
|
@@ -77,8 +75,6 @@ modules.order
|
|
|
77
75
|
# python
|
|
78
76
|
__pycache__/
|
|
79
77
|
*.py[oc]
|
|
80
|
-
*.pyc
|
|
81
|
-
*.pyo
|
|
82
78
|
/wheel/
|
|
83
79
|
/.venv/
|
|
84
80
|
.coverage
|
|
@@ -87,7 +83,10 @@ coverage.xml
|
|
|
87
83
|
*.egg-info/
|
|
88
84
|
|
|
89
85
|
# mine
|
|
90
|
-
|
|
86
|
+
# error files left by the bashy prompt plugins (.uv.sync.errors,
|
|
87
|
+
# .pydmt.build.errors, ...); unanchored because a sub-project's
|
|
88
|
+
# pyproject root can sit below the git root
|
|
89
|
+
.*.errors
|
|
91
90
|
/.pydmt/
|
|
92
91
|
*.stamp
|
|
93
92
|
*.stamp.*
|
|
@@ -147,10 +146,13 @@ build/
|
|
|
147
146
|
.ipynb_checkpoints/
|
|
148
147
|
|
|
149
148
|
# c#
|
|
149
|
+
# **/obj/ and **/bin/ match at any depth, which is what .NET output needs
|
|
150
|
+
# (src/<proj>/bin, src/<proj>/obj). The un-globbed [Oo]bj/ and [Bb]in/ that
|
|
151
|
+
# used to follow were redundant with these two and are gone.
|
|
150
152
|
**/obj/
|
|
151
153
|
**/bin/
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
# perl-meta keeps real Perl sources under perl/bin/Meta/, not build output.
|
|
155
|
+
!/perl/bin/
|
|
154
156
|
|
|
155
157
|
# flash/air
|
|
156
158
|
*.swf
|
|
@@ -175,7 +177,6 @@ bin-release/
|
|
|
175
177
|
.project
|
|
176
178
|
.project.xml
|
|
177
179
|
.idea/
|
|
178
|
-
/.idea/
|
|
179
180
|
build.properties
|
|
180
181
|
|
|
181
182
|
# spark
|
|
@@ -186,24 +187,26 @@ spark-warehouse/
|
|
|
186
187
|
/.terraform/
|
|
187
188
|
terraform.tfstate
|
|
188
189
|
terraform.tfstate.backup
|
|
189
|
-
/terraform.tfstate
|
|
190
|
-
/terraform.tfstate.backup
|
|
191
190
|
/terraform.lock.hcl
|
|
192
191
|
|
|
193
192
|
# scala
|
|
194
|
-
|
|
195
|
-
project/
|
|
193
|
+
# Anchored: sbt's build dir is at the repo root. Unanchored, this also
|
|
194
|
+
# swallowed source directories named project/ nested under src/.
|
|
195
|
+
/project/
|
|
196
196
|
|
|
197
197
|
# rust
|
|
198
198
|
**/*.rs.bk
|
|
199
199
|
**/mutants.out*/
|
|
200
200
|
*.pdb
|
|
201
|
-
debug
|
|
201
|
+
# Anchored: this is the root debug build dir. Unanchored (and without a
|
|
202
|
+
# trailing slash) it matched any file or directory named debug at any depth,
|
|
203
|
+
# including authored example content.
|
|
204
|
+
/debug/
|
|
202
205
|
/.rsconstruct_cache.json
|
|
203
206
|
|
|
204
207
|
# claude
|
|
205
208
|
/.claude/
|
|
206
|
-
claude/
|
|
209
|
+
/claude/
|
|
207
210
|
.claude/projects/
|
|
208
211
|
.claude/settings.local.json
|
|
209
212
|
|
|
@@ -242,3 +245,36 @@ creds.txt
|
|
|
242
245
|
|
|
243
246
|
# rsconstruct
|
|
244
247
|
/.rsconstruct/
|
|
248
|
+
|
|
249
|
+
# generated website pieces (built into the Pages artifact by CI)
|
|
250
|
+
/docs/output/
|
|
251
|
+
/docs/index.html
|
|
252
|
+
# sphinx html output: the 14 py* repos render docs/ from sphinx/ and publish
|
|
253
|
+
# it as the Pages artifact, so none of it is committed. Listed path by path
|
|
254
|
+
# rather than as /docs/ because the rs* repos keep hand-written mdBook
|
|
255
|
+
# sources there, and several others keep authored html.
|
|
256
|
+
/docs/_modules/
|
|
257
|
+
/docs/_sources/
|
|
258
|
+
/docs/_static/
|
|
259
|
+
/docs/.buildinfo
|
|
260
|
+
/docs/objects.inv
|
|
261
|
+
/docs/searchindex.js
|
|
262
|
+
/docs/.nojekyll
|
|
263
|
+
# sphinx's top-level html. Not a blanket /docs/*.html: js-jschess and the
|
|
264
|
+
# site-personal-* repos keep hand-authored html under docs/. The fixed pages
|
|
265
|
+
# (genindex, modules, search) and the authored-rst pages some repos render
|
|
266
|
+
# (architecture, notes, ...) are listed by name; the one-page-per-module
|
|
267
|
+
# output is /docs/py*.html, since every package here is named py*.
|
|
268
|
+
/docs/architecture.html
|
|
269
|
+
/docs/cli-reference.html
|
|
270
|
+
/docs/development.html
|
|
271
|
+
/docs/genindex.html
|
|
272
|
+
/docs/modules.html
|
|
273
|
+
/docs/notes.html
|
|
274
|
+
/docs/overview.html
|
|
275
|
+
/docs/py*.html
|
|
276
|
+
/docs/quota-guide.html
|
|
277
|
+
/docs/search.html
|
|
278
|
+
|
|
279
|
+
# per-machine tool resolution cache (absolute paths, not portable)
|
|
280
|
+
/.tools.versions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pygitpub
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.60
|
|
4
4
|
Summary: Pygitpub will help you work with github
|
|
5
5
|
Project-URL: Homepage, https://github.com/veltzer/pygitpub
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/veltzer/pygitpub/issues
|
|
@@ -19,9 +19,10 @@ Classifier: Operating System :: OS Independent
|
|
|
19
19
|
Classifier: Programming Language :: Python
|
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
|
21
21
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
23
|
Classifier: Topic :: Utilities
|
|
24
|
-
Requires-Python: >=3.
|
|
24
|
+
Requires-Python: >=3.14
|
|
25
|
+
Requires-Dist: lupa
|
|
25
26
|
Requires-Dist: pyapikey
|
|
26
27
|
Requires-Dist: pygithub
|
|
27
28
|
Requires-Dist: pylogconf
|
|
@@ -29,6 +30,9 @@ Requires-Dist: pytconf
|
|
|
29
30
|
Requires-Dist: pyyaml
|
|
30
31
|
Description-Content-Type: text/markdown
|
|
31
32
|
|
|
33
|
+
<!-- This file is generated. Do not edit it by hand: your changes will be
|
|
34
|
+
lost on the next build. Edit the template it is rendered from, or the
|
|
35
|
+
values that template reads, and build again. -->
|
|
32
36
|
# *pygitpub* project by Mark Veltzer
|
|
33
37
|
|
|
34
38
|
description: Pygitpub will help you work with github
|
|
@@ -37,7 +41,7 @@ project website: https://veltzer.github.io/pygitpub
|
|
|
37
41
|
|
|
38
42
|
author: Mark Veltzer
|
|
39
43
|
|
|
40
|
-
version: 0.0.
|
|
44
|
+
version: 0.0.60
|
|
41
45
|
|
|
42
46
|

|
|
43
47
|
|
|
@@ -66,7 +70,6 @@ version: 0.0.59
|
|
|
66
70
|
## contact me
|
|
67
71
|
|
|
68
72
|
[mailto](mailto:mark.veltzer@gmail.com)
|
|
69
|
-

|
|
70
73
|

|
|
71
74
|

|
|
72
75
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<!-- This file is generated. Do not edit it by hand: your changes will be
|
|
2
|
+
lost on the next build. Edit the template it is rendered from, or the
|
|
3
|
+
values that template reads, and build again. -->
|
|
1
4
|
# *pygitpub* project by Mark Veltzer
|
|
2
5
|
|
|
3
6
|
description: Pygitpub will help you work with github
|
|
@@ -6,7 +9,7 @@ project website: https://veltzer.github.io/pygitpub
|
|
|
6
9
|
|
|
7
10
|
author: Mark Veltzer
|
|
8
11
|
|
|
9
|
-
version: 0.0.
|
|
12
|
+
version: 0.0.60
|
|
10
13
|
|
|
11
14
|

|
|
12
15
|
|
|
@@ -35,7 +38,6 @@ version: 0.0.59
|
|
|
35
38
|
## contact me
|
|
36
39
|
|
|
37
40
|
[mailto](mailto:mark.veltzer@gmail.com)
|
|
38
|
-

|
|
39
41
|

|
|
40
42
|

|
|
41
43
|
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pygitpub"
|
|
7
|
-
version = "0.0.
|
|
8
|
-
requires-python = ">=3.
|
|
7
|
+
version = "0.0.60"
|
|
8
|
+
requires-python = ">=3.14"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Mark Veltzer", email = "mark.veltzer@gmail.com" }
|
|
11
11
|
]
|
|
@@ -26,7 +26,7 @@ classifiers = [
|
|
|
26
26
|
"Programming Language :: Python",
|
|
27
27
|
"Programming Language :: Python :: 3",
|
|
28
28
|
"Programming Language :: Python :: 3 :: Only",
|
|
29
|
-
"Programming Language :: Python :: 3.
|
|
29
|
+
"Programming Language :: Python :: 3.14",
|
|
30
30
|
"Topic :: Utilities",
|
|
31
31
|
"License :: OSI Approved :: MIT License",
|
|
32
32
|
]
|
|
@@ -36,6 +36,16 @@ dependencies = [
|
|
|
36
36
|
"PyGithub",
|
|
37
37
|
"pyapikey",
|
|
38
38
|
"pyyaml",
|
|
39
|
+
"lupa",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[dependency-groups]
|
|
43
|
+
dev = [
|
|
44
|
+
"mypy",
|
|
45
|
+
"pylint",
|
|
46
|
+
"pytest",
|
|
47
|
+
"ruff",
|
|
48
|
+
"sphinx",
|
|
39
49
|
]
|
|
40
50
|
|
|
41
51
|
[project.urls]
|
|
@@ -74,10 +84,23 @@ exclude = [
|
|
|
74
84
|
]
|
|
75
85
|
|
|
76
86
|
[tool.mypy]
|
|
77
|
-
python_version = "3.
|
|
87
|
+
python_version = "3.14"
|
|
78
88
|
warn_return_any = true
|
|
79
89
|
warn_unused_configs = true
|
|
90
|
+
mypy_path = "src:python:scripts"
|
|
91
|
+
explicit_package_bases = true
|
|
92
|
+
namespace_packages = true
|
|
80
93
|
|
|
94
|
+
# Third-party libraries without type stubs; `foo.*` also matches `foo` itself.
|
|
95
|
+
[[tool.mypy.overrides]]
|
|
96
|
+
module = [
|
|
97
|
+
"github.*",
|
|
98
|
+
"lupa.*",
|
|
99
|
+
"pyapikey.*",
|
|
100
|
+
"pylogconf.*",
|
|
101
|
+
"pytconf.*",
|
|
102
|
+
]
|
|
103
|
+
ignore_missing_imports = true
|
|
81
104
|
[tool.hatch.envs.default]
|
|
82
105
|
installer = "uv"
|
|
83
106
|
|
|
@@ -16,12 +16,13 @@ from pytconf.registry import the_registry
|
|
|
16
16
|
|
|
17
17
|
import pygitpub.static
|
|
18
18
|
from pygitpub.configs import AFFILIATIONS, ConfigAlgo, ConfigGithub, ConfigOutput
|
|
19
|
-
from pygitpub.utils.
|
|
19
|
+
from pygitpub.utils.lua import config_path, load_lua_file
|
|
20
20
|
from pygitpub.utils.misc import delete, get_all_git_repos
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def get_base_dir() -> str:
|
|
24
|
-
|
|
24
|
+
base_dir: str = ConfigAlgo.base_dir
|
|
25
|
+
return os.path.expanduser(base_dir)
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def get_repo_folder(repo) -> str:
|
|
@@ -84,25 +85,25 @@ def fix_metadata() -> None:
|
|
|
84
85
|
continue
|
|
85
86
|
os.chdir(folder)
|
|
86
87
|
# print(f"doing [{folder}]...")
|
|
87
|
-
file_path = "
|
|
88
|
+
file_path = config_path("project")
|
|
88
89
|
if not os.path.isfile(file_path):
|
|
89
90
|
os.chdir(orig_folder)
|
|
90
91
|
continue
|
|
91
|
-
|
|
92
|
-
if not
|
|
92
|
+
project = load_lua_file(file_path)
|
|
93
|
+
if "DESCRIPTION_SHORT" not in project:
|
|
93
94
|
os.chdir(orig_folder)
|
|
94
95
|
continue
|
|
95
|
-
description_short =
|
|
96
|
+
description_short = project["DESCRIPTION_SHORT"]
|
|
96
97
|
if description_short != repo.description:
|
|
97
98
|
print(f"in {folder}...")
|
|
98
99
|
print(f"description_short is [{description_short}]")
|
|
99
100
|
print(f"repo.description is [{repo.description}]")
|
|
100
101
|
repo.edit(description=description_short)
|
|
101
|
-
if not
|
|
102
|
+
if "KEYWORDS" not in project:
|
|
102
103
|
print(f"{folder} no keywords")
|
|
103
104
|
os.chdir(orig_folder)
|
|
104
105
|
continue
|
|
105
|
-
keywords =
|
|
106
|
+
keywords = project["KEYWORDS"]
|
|
106
107
|
if set(keywords) != set(repo.get_topics()):
|
|
107
108
|
print(f"in {folder}...")
|
|
108
109
|
print(f"keywords is [{keywords}]")
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Load "config/*.lua" data files.
|
|
3
|
+
|
|
4
|
+
The config files used to be python modules loaded via importlib; they are now
|
|
5
|
+
lua data files (config/project.lua and friends). A file is run in a fresh lua
|
|
6
|
+
runtime and the globals it declares are returned as a plain dict.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os.path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
# lupa exposes LuaRuntime through a module level __getattr__ that points at the
|
|
13
|
+
# bundled lua version (lupa.lua54, lupa.lua55, ...), so it cannot be imported
|
|
14
|
+
# by name. Going through the package attribute works for any bundled version.
|
|
15
|
+
import lupa
|
|
16
|
+
|
|
17
|
+
CONFIG_FOLDER = "config"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def lua_to_python(value: Any) -> Any:
|
|
21
|
+
"""
|
|
22
|
+
Recursively convert a lua value into its python equivalent.
|
|
23
|
+
|
|
24
|
+
Lua has a single table type, so a table is a list if its keys are exactly
|
|
25
|
+
1..n and a dict otherwise. An empty table becomes an empty list, which
|
|
26
|
+
matches how the config files use them.
|
|
27
|
+
"""
|
|
28
|
+
if not hasattr(value, "values"):
|
|
29
|
+
return value
|
|
30
|
+
keys = list(value.keys())
|
|
31
|
+
if keys == list(range(1, len(keys) + 1)):
|
|
32
|
+
return [lua_to_python(x) for x in value.values()]
|
|
33
|
+
return {k: lua_to_python(value[k]) for k in keys}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def config_path(name: str) -> str:
|
|
37
|
+
""" return the path of a config file by its short name ("project") """
|
|
38
|
+
return os.path.join(CONFIG_FOLDER, f"{name}.lua")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def load_lua_file(path: str) -> dict[str, Any]:
|
|
42
|
+
"""
|
|
43
|
+
Run a lua file and return the globals it declared as a dict.
|
|
44
|
+
|
|
45
|
+
Raises FileNotFoundError if the file does not exist.
|
|
46
|
+
"""
|
|
47
|
+
if not os.path.isfile(path):
|
|
48
|
+
raise FileNotFoundError(path)
|
|
49
|
+
runtime = lupa.LuaRuntime()
|
|
50
|
+
with open(path, encoding="utf-8") as stream:
|
|
51
|
+
runtime.execute(stream.read())
|
|
52
|
+
globals_table = runtime.globals()
|
|
53
|
+
values = {}
|
|
54
|
+
for key in globals_table:
|
|
55
|
+
# skip the lua standard library, we only want what the file declared
|
|
56
|
+
if key in _LUA_BUILTINS:
|
|
57
|
+
continue
|
|
58
|
+
values[key] = lua_to_python(globals_table[key])
|
|
59
|
+
return values
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_LUA_BUILTINS = frozenset({
|
|
63
|
+
"_G", "_VERSION", "assert", "collectgarbage", "coroutine", "debug", "dofile",
|
|
64
|
+
"error", "getmetatable", "io", "ipairs", "load", "loadfile", "math", "next",
|
|
65
|
+
"os", "package", "pairs", "pcall", "print", "python", "rawequal", "rawget",
|
|
66
|
+
"rawlen", "rawset", "require", "select", "setmetatable", "string", "table",
|
|
67
|
+
"tonumber", "tostring", "type", "utf8", "warn", "xpcall",
|
|
68
|
+
})
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
""" importlib.py """
|
|
2
|
-
|
|
3
|
-
import importlib.util
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def module_exists(module_name):
|
|
7
|
-
""" return if a module exists or not """
|
|
8
|
-
spec = importlib.util.find_spec(module_name)
|
|
9
|
-
return spec is not None
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def import_file(file_path):
|
|
13
|
-
spec = importlib.util.spec_from_file_location("foo", file_path)
|
|
14
|
-
mod = importlib.util.module_from_spec(spec)
|
|
15
|
-
spec.loader.exec_module(mod)
|
|
16
|
-
return mod
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|