linkinpycli 0.0.1__py3-none-any.whl

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.
File without changes
linkinpycli/crawler.py ADDED
@@ -0,0 +1,18 @@
1
+ from importlib.metadata import EntryPoint, entry_points
2
+
3
+ LINKINPY_SCRIPT_PREFIX = "linkinpy"
4
+
5
+
6
+ def find_linkinpy_entry_points() -> list[EntryPoint]:
7
+ """Find all console-script entry points that start with 'linkinpy'."""
8
+ return [
9
+ ep
10
+ for ep in entry_points(group="console_scripts")
11
+ if ep.name.startswith(LINKINPY_SCRIPT_PREFIX)
12
+ and ep.name != "linkinpy-parse"
13
+ ]
14
+
15
+
16
+ def find_linkinpy_scripts() -> list[str]:
17
+ """Find all console scripts that start with 'linkinpy'."""
18
+ return [ep.name for ep in find_linkinpy_entry_points()]
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ import json
5
+ from importlib import import_module
6
+ from importlib.metadata import EntryPoint
7
+ from pathlib import Path
8
+
9
+ from .crawler import find_linkinpy_entry_points
10
+
11
+
12
+ _IGNORED_SIGNATURE_PARAMETERS = {"argv", "args", "kwargs"}
13
+
14
+
15
+ def _format_datatype(annotation: object) -> str:
16
+ if annotation is inspect.Signature.empty:
17
+ return "Any"
18
+ if isinstance(annotation, str):
19
+ return annotation.replace("pathlib.", "")
20
+ if getattr(annotation, "__module__", "") == "builtins":
21
+ return annotation.__name__
22
+ return str(annotation).replace("pathlib.", "")
23
+
24
+
25
+ def _format_default(default: object) -> object:
26
+ if default is inspect.Signature.empty:
27
+ return None
28
+ if isinstance(default, (str, int, float, bool)) or default is None:
29
+ return default
30
+ return repr(default)
31
+
32
+
33
+ def _signature_arguments(callable_object: object) -> list[dict[str, object]]:
34
+ signature = inspect.signature(callable_object)
35
+ arguments = []
36
+ for name, parameter in signature.parameters.items():
37
+ if name in _IGNORED_SIGNATURE_PARAMETERS:
38
+ continue
39
+ if parameter.kind in (
40
+ inspect.Parameter.VAR_POSITIONAL,
41
+ inspect.Parameter.VAR_KEYWORD,
42
+ ):
43
+ continue
44
+ arguments.append(
45
+ {
46
+ "name": name,
47
+ "datatype": _format_datatype(parameter.annotation),
48
+ "required": parameter.default is inspect.Signature.empty,
49
+ "default": _format_default(parameter.default),
50
+ }
51
+ )
52
+ return arguments
53
+
54
+
55
+ def _entry_point_reference(entry_point: EntryPoint) -> str:
56
+ return f"{entry_point.module}:{entry_point.attr}"
57
+
58
+
59
+ def _resolve_callable(entry_point: EntryPoint) -> object:
60
+ module = import_module(entry_point.module)
61
+ entry_callable = entry_point.load()
62
+ entry_arguments = _signature_arguments(entry_callable)
63
+ if entry_arguments:
64
+ return entry_callable
65
+
66
+ expected_name = entry_point.name.replace("-", "_")
67
+ expected_callable = getattr(module, expected_name, None)
68
+ if callable(expected_callable):
69
+ return expected_callable
70
+
71
+ linkinpy_callables = [
72
+ obj
73
+ for name, obj in inspect.getmembers(module, inspect.isfunction)
74
+ if name.startswith("linkinpy") and name not in {"linkinpy_parse"}
75
+ ]
76
+ if len(linkinpy_callables) == 1:
77
+ return linkinpy_callables[0]
78
+
79
+ return entry_callable
80
+
81
+
82
+ def _script_details(entry_point: EntryPoint) -> dict[str, object]:
83
+ details: dict[str, object] = {
84
+ "name": entry_point.name,
85
+ "entry_point": _entry_point_reference(entry_point),
86
+ "arguments": [],
87
+ }
88
+ try:
89
+ callable_object = _resolve_callable(entry_point)
90
+ details["callable"] = (
91
+ f"{callable_object.__module__}:{callable_object.__name__}"
92
+ )
93
+ details["arguments"] = _signature_arguments(callable_object)
94
+ except Exception as exc:
95
+ details["error"] = str(exc)
96
+ return details
97
+
98
+
99
+ def parse_linkinpy_scripts() -> None:
100
+ """Find LinkinPy console scripts and write their argument metadata to scripts.json."""
101
+ scripts = [
102
+ _script_details(entry_point)
103
+ for entry_point in find_linkinpy_entry_points()
104
+ ]
105
+ output_path = Path.cwd() / "scripts.json"
106
+ output_path.write_text(
107
+ json.dumps({"scripts": scripts}, indent=2) + "\n",
108
+ encoding="utf-8",
109
+ )
110
+ print(f"Saved {len(scripts)} scripts to {output_path}")
111
+
112
+
113
+ class LinkinPyCLI:
114
+ """Minimal example class generated by the template."""
115
+
116
+ def run(self) -> int:
117
+ return 1
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: linkinpycli
3
+ Version: 0.0.1
4
+ Summary: CLI finder for LinkinPy integration
5
+ Project-URL: Homepage, https://github.com/HenriquesLab/LinkinPy
6
+ Project-URL: Repository, https://github.com/HenriquesLab/LinkinPy
7
+ Project-URL: Issues, https://github.com/HenriquesLab/LinkinPy/issues
8
+ Project-URL: Changelog, https://github.com/HenriquesLab/LinkinPy/blob/main/CHANGELOG.md
9
+ Author-email: brunomsaraiva <bruno.msaraiva2@gmail.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE.txt
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+
20
+ # linkinpycli
21
+
22
+ CLI finder for LinkinPy integration
23
+
24
+ ## Quick Start
25
+
26
+ ```bash
27
+ uv sync
28
+ uv run pytest
29
+ ```
30
+
31
+ The project pins its local development interpreter in `.python-version` and keeps package metadata in `pyproject.toml`.
32
+
33
+ ## Common Commands
34
+
35
+ ```bash
36
+ uv sync # create/update the local environment
37
+ uv run pytest # run the test suite
38
+ uv run ruff check . # lint the codebase
39
+ uv run ruff format . # format the codebase
40
+ uv run python -m build # build the source and wheel distributions
41
+ uv run pre-commit install
42
+ ```
43
+
44
+ If you prefer shorter aliases, the same workflow is available through `make`:
45
+
46
+ ```bash
47
+ make sync
48
+ make test
49
+ make lint
50
+ make format
51
+ make build
52
+ ```
53
+
54
+ ## Project Layout
55
+
56
+ ```text
57
+ src/linkinpycli/
58
+ tests/
59
+ pyproject.toml
60
+ .python-version
61
+ GETTING_STARTED.md
62
+ CONTRIBUTING.md
63
+ ```
64
+
65
+ ## Documentation
66
+
67
+ - Start with [GETTING_STARTED.md](GETTING_STARTED.md) for first-time setup
68
+ - See [CONTRIBUTING.md](CONTRIBUTING.md) for the contributor workflow
69
+ - Track user-facing changes in [CHANGELOG.md](CHANGELOG.md)
@@ -0,0 +1,8 @@
1
+ linkinpycli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ linkinpycli/crawler.py,sha256=lPhzleGG4JJCV2VuLIr3uQehVkKXwh-5dmVXyL13gU0,571
3
+ linkinpycli/linkinpycli.py,sha256=ZEHSOgjlfiVER4Jh0oE_qThNP599lOxVKhp-zomF-L4,3620
4
+ linkinpycli-0.0.1.dist-info/METADATA,sha256=c3Q8uQ02z0z1zcVhXsVXKPIPjyc9BITte40l7Kcd26c,1834
5
+ linkinpycli-0.0.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
6
+ linkinpycli-0.0.1.dist-info/entry_points.txt,sha256=9IQg5_h0an5eW-A60MDc6N4Lv34cPGyFQC446H5kf4U,82
7
+ linkinpycli-0.0.1.dist-info/licenses/LICENSE.txt,sha256=WrrpqqQd_VEVy37iiIgoICGcWlYfAsWTsHC44JK0OGM,1079
8
+ linkinpycli-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ linkinpy-parse = linkinpycli.linkinpycli:parse_linkinpy_scripts
@@ -0,0 +1,22 @@
1
+
2
+ The MIT License (MIT)
3
+
4
+ Copyright (c) 2026 linkinpycli
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.