pyOpenSourceProjects 0.3.0__tar.gz → 0.4.0__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.
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/.github/workflows/build.yml +2 -2
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/PKG-INFO +9 -7
- pyopensourceprojects-0.4.0/README.md +17 -0
- pyopensourceprojects-0.4.0/osprojects/__init__.py +1 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/osprojects/check_project.py +23 -18
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/osprojects/checkos.py +14 -11
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/osprojects/editor.py +7 -11
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/osprojects/github_api.py +20 -35
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/osprojects/osproject.py +22 -58
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/pyproject.toml +4 -3
- pyopensourceprojects-0.4.0/scripts/blackisort +15 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/tests/basetest.py +8 -21
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/tests/test_github.py +6 -15
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/tests/test_github_api.py +5 -11
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/tests/test_osproject.py +30 -23
- pyopensourceprojects-0.3.0/README.md +0 -15
- pyopensourceprojects-0.3.0/osprojects/__init__.py +0 -1
- pyopensourceprojects-0.3.0/scripts/blackisort +0 -7
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/.github/workflows/upload-to-pypi.yml +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/.gitignore +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/.project +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/.pydevproject +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/LICENSE +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/mkdocs.yml +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/scripts/doc +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/scripts/install +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/scripts/installAndTest +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/scripts/release +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/scripts/test +0 -0
- {pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/tests/__init__.py +0 -0
|
@@ -20,8 +20,8 @@ jobs:
|
|
|
20
20
|
matrix:
|
|
21
21
|
#os: [ubuntu-latest, macos-latest, windows-latest]
|
|
22
22
|
os: [ubuntu-latest]
|
|
23
|
-
#python-version: [ '3.
|
|
24
|
-
python-version: ["3.
|
|
23
|
+
#python-version: [ '3.11', '3.12', '3.13' ]
|
|
24
|
+
python-version: ["3.12"]
|
|
25
25
|
|
|
26
26
|
steps:
|
|
27
27
|
- uses: actions/checkout@v4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyOpenSourceProjects
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Dynamic: Summary
|
|
5
5
|
Project-URL: Home, https://github.com/WolfgangFahl/pyOpenSourceProjects
|
|
6
6
|
Project-URL: Documentation, http://wiki.bitplan.com/index.php/pyOpenSourceProjects
|
|
@@ -10,14 +10,14 @@ Maintainer-email: Wolfgang Fahl <wf@bitplan.com>
|
|
|
10
10
|
License-Expression: Apache-2.0
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Requires-Dist: beautifulsoup4>=4.14.2
|
|
18
18
|
Requires-Dist: gitpython
|
|
19
19
|
Requires-Dist: packaging>=24.1
|
|
20
|
-
Requires-Dist: py-3rdparty-mediawiki>=0.
|
|
20
|
+
Requires-Dist: py-3rdparty-mediawiki>=0.18.1
|
|
21
21
|
Requires-Dist: pylodstorage>=0.17.0
|
|
22
22
|
Requires-Dist: python-dateutil>=2.8.2
|
|
23
23
|
Requires-Dist: requests
|
|
@@ -26,13 +26,15 @@ Provides-Extra: test
|
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
|
|
28
28
|
# pyOpenSourceProjects
|
|
29
|
+
|
|
29
30
|
Helper Library to organize open source Projects
|
|
30
31
|
|
|
31
32
|
| | |
|
|
32
33
|
| :--- | :--- |
|
|
33
|
-
| **
|
|
34
|
-
| **
|
|
35
|
-
| **
|
|
34
|
+
| **PyPi** | [](https://pypi.python.org/pypi/pyOpenSourceProjects/) [](https://www.apache.org/licenses/LICENSE-2.0) [](https://pypi.org/project/pyOpenSourceProjects/) [](https://pypi.org/project/pyOpenSourceProjects/) [](https://pypi.org/project/pyOpenSourceProjects/) |
|
|
35
|
+
| **GitHub** | [](https://github.com/WolfgangFahl/pyOpenSourceProjects/actions/workflows/build.yml) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/releases) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/graphs/contributors) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/commits/) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/issues) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/issues/?q=is%3Aissue+is%3Aclosed) |
|
|
36
|
+
| **Code** | [](https://github.com/psf/black) [](https://pycqa.github.io/isort/) |
|
|
37
|
+
| **Docs** | [](https://WolfgangFahl.github.io/pyOpenSourceProjects/) [](https://github.com/PyCQA/docformatter) [](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |
|
|
36
38
|
|
|
37
39
|
## Documentation
|
|
38
40
|
[Wiki](https://wiki.bitplan.com/index.php/PyOpenSourceProjects)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# pyOpenSourceProjects
|
|
2
|
+
|
|
3
|
+
Helper Library to organize open source Projects
|
|
4
|
+
|
|
5
|
+
| | |
|
|
6
|
+
| :--- | :--- |
|
|
7
|
+
| **PyPi** | [](https://pypi.python.org/pypi/pyOpenSourceProjects/) [](https://www.apache.org/licenses/LICENSE-2.0) [](https://pypi.org/project/pyOpenSourceProjects/) [](https://pypi.org/project/pyOpenSourceProjects/) [](https://pypi.org/project/pyOpenSourceProjects/) |
|
|
8
|
+
| **GitHub** | [](https://github.com/WolfgangFahl/pyOpenSourceProjects/actions/workflows/build.yml) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/releases) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/graphs/contributors) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/commits/) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/issues) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/issues/?q=is%3Aissue+is%3Aclosed) |
|
|
9
|
+
| **Code** | [](https://github.com/psf/black) [](https://pycqa.github.io/isort/) |
|
|
10
|
+
| **Docs** | [](https://WolfgangFahl.github.io/pyOpenSourceProjects/) [](https://github.com/PyCQA/docformatter) [](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |
|
|
11
|
+
|
|
12
|
+
## Documentation
|
|
13
|
+
[Wiki](https://wiki.bitplan.com/index.php/PyOpenSourceProjects)
|
|
14
|
+
|
|
15
|
+
### Authors
|
|
16
|
+
* [Tim Holzheim](https://www.semantic-mediawiki.org/wiki/Tim_Holzheim)
|
|
17
|
+
* [Wolfgang Fahl](http://www.bitplan.com/Wolfgang_Fahl)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.0"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2024-08-28
|
|
1
|
+
"""Created on 2024-08-28.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -13,10 +12,9 @@ from git import Repo
|
|
|
13
12
|
from git.exc import InvalidGitRepositoryError, NoSuchPathError
|
|
14
13
|
from packaging import version
|
|
15
14
|
|
|
16
|
-
from osprojects.github_api import GitHubAction
|
|
17
|
-
|
|
18
15
|
# original at ngwidgets - use redundant local copy ...
|
|
19
16
|
from osprojects.editor import Editor
|
|
17
|
+
from osprojects.github_api import GitHubAction
|
|
20
18
|
|
|
21
19
|
|
|
22
20
|
@dataclass
|
|
@@ -42,9 +40,7 @@ class Check:
|
|
|
42
40
|
|
|
43
41
|
|
|
44
42
|
class CheckProject:
|
|
45
|
-
"""
|
|
46
|
-
Checker for an individual open source project
|
|
47
|
-
"""
|
|
43
|
+
"""Checker for an individual open source project."""
|
|
48
44
|
|
|
49
45
|
def __init__(self, parent, project, args):
|
|
50
46
|
self.parent = parent
|
|
@@ -101,14 +97,28 @@ class CheckProject:
|
|
|
101
97
|
self.checks.append(path_exists)
|
|
102
98
|
return path_exists
|
|
103
99
|
|
|
100
|
+
def generate_badge_markdown(self) -> str:
|
|
101
|
+
"""Generate README.md badge table markup."""
|
|
102
|
+
project_name = self.project_name
|
|
103
|
+
owner = self.project.owner
|
|
104
|
+
project_id = self.project.project_id
|
|
105
|
+
|
|
106
|
+
markup= f"""| | |
|
|
107
|
+
| :--- | :--- |
|
|
108
|
+
| **PyPi** | [](https://pypi.python.org/pypi/{project_name}/) [](https://www.apache.org/licenses/LICENSE-2.0) [](https://pypi.org/project/{project_name}/) [](https://pypi.org/project/{project_name}/) [](https://pypi.org/project/{project_name}/) |
|
|
109
|
+
| **GitHub** | [](https://github.com/{owner}/{project_id}/actions/workflows/build.yml) [](https://github.com/{owner}/{project_id}/releases) [](https://github.com/{owner}/{project_id}/graphs/contributors) [](https://github.com/{owner}/{project_id}/commits/) [](https://github.com/{owner}/{project_id}/issues) [](https://github.com/{owner}/{project_id}/issues/?q=is%3Aissue+is%3Aclosed) |
|
|
110
|
+
| **Code** | [](https://github.com/psf/black) [](https://pycqa.github.io/isort/) |
|
|
111
|
+
| **Docs** | [](https://{owner}.github.io/{project_id}/) [](https://github.com/PyCQA/docformatter) [](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |"""
|
|
112
|
+
return markup
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
104
116
|
def check_local(self) -> Check:
|
|
105
117
|
local = Check.file_exists(self.project_path)
|
|
106
118
|
return local
|
|
107
119
|
|
|
108
120
|
def check_github_workflows(self):
|
|
109
|
-
"""
|
|
110
|
-
check the github workflow files
|
|
111
|
-
"""
|
|
121
|
+
"""Check the github workflow files."""
|
|
112
122
|
workflows_path = os.path.join(self.project_path, ".github", "workflows")
|
|
113
123
|
workflows_exist = self.add_path_check(workflows_path)
|
|
114
124
|
|
|
@@ -231,9 +241,7 @@ class CheckProject:
|
|
|
231
241
|
)
|
|
232
242
|
|
|
233
243
|
def check_pyproject_toml(self) -> bool:
|
|
234
|
-
"""
|
|
235
|
-
pyproject.toml
|
|
236
|
-
"""
|
|
244
|
+
"""pyproject.toml."""
|
|
237
245
|
toml_path = os.path.join(self.project_path, "pyproject.toml")
|
|
238
246
|
toml_exists = self.add_path_check(toml_path)
|
|
239
247
|
if toml_exists.ok:
|
|
@@ -274,8 +282,7 @@ class CheckProject:
|
|
|
274
282
|
return toml_exists.ok
|
|
275
283
|
|
|
276
284
|
def check_git(self) -> bool:
|
|
277
|
-
"""
|
|
278
|
-
Check git repository information using GitHub class
|
|
285
|
+
"""Check git repository information using GitHub class.
|
|
279
286
|
|
|
280
287
|
Returns:
|
|
281
288
|
bool: True if git owner matches project owner and the repo is not a fork
|
|
@@ -335,9 +342,7 @@ class CheckProject:
|
|
|
335
342
|
return owner_match and not is_fork
|
|
336
343
|
|
|
337
344
|
def check(self, title: str):
|
|
338
|
-
"""
|
|
339
|
-
Check the given project and print results
|
|
340
|
-
"""
|
|
345
|
+
"""Check the given project and print results."""
|
|
341
346
|
self.check_local()
|
|
342
347
|
self.check_git()
|
|
343
348
|
if self.check_pyproject_toml():
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
"""
|
|
3
|
-
Created on 2024-07-30
|
|
2
|
+
"""Created on 2024-07-30.
|
|
4
3
|
|
|
5
4
|
@author: wf
|
|
6
5
|
"""
|
|
@@ -15,9 +14,7 @@ from osprojects.osproject import OsProjects
|
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class CheckOS:
|
|
18
|
-
"""
|
|
19
|
-
checker for a set of open source projects
|
|
20
|
-
"""
|
|
17
|
+
"""Checker for a set of open source projects."""
|
|
21
18
|
|
|
22
19
|
def __init__(
|
|
23
20
|
self, args: Namespace, osprojects: OsProjects, max_python_version_minor=12
|
|
@@ -67,9 +64,8 @@ class CheckOS:
|
|
|
67
64
|
self.osprojects.filter_projects(local_only=True)
|
|
68
65
|
|
|
69
66
|
def check_projects(self):
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
"""
|
|
67
|
+
"""Select, filter, and check all projects based on the provided
|
|
68
|
+
arguments."""
|
|
73
69
|
self.select_projects()
|
|
74
70
|
self.filter_projects()
|
|
75
71
|
|
|
@@ -78,6 +74,9 @@ class CheckOS:
|
|
|
78
74
|
):
|
|
79
75
|
checker = CheckProject(self, project, self.args)
|
|
80
76
|
checker.check(f"{i:3}:")
|
|
77
|
+
if self.args.badges:
|
|
78
|
+
print(checker.generate_badge_markdown())
|
|
79
|
+
|
|
81
80
|
|
|
82
81
|
def handle_exception(self, ex: Exception):
|
|
83
82
|
CheckOS.show_exception(ex, self.args.debug)
|
|
@@ -91,9 +90,7 @@ class CheckOS:
|
|
|
91
90
|
|
|
92
91
|
|
|
93
92
|
def main(_argv=None):
|
|
94
|
-
"""
|
|
95
|
-
main command line entry point
|
|
96
|
-
"""
|
|
93
|
+
"""Main command line entry point."""
|
|
97
94
|
parser = argparse.ArgumentParser(description="Check open source projects")
|
|
98
95
|
parser.add_argument(
|
|
99
96
|
"-d",
|
|
@@ -101,6 +98,12 @@ def main(_argv=None):
|
|
|
101
98
|
action="store_true",
|
|
102
99
|
help="add debug output",
|
|
103
100
|
)
|
|
101
|
+
parser.add_argument(
|
|
102
|
+
"-b",
|
|
103
|
+
"--badges",
|
|
104
|
+
action="store_true",
|
|
105
|
+
help="create and output standard README.md badges markup",
|
|
106
|
+
)
|
|
104
107
|
parser.add_argument(
|
|
105
108
|
"-e",
|
|
106
109
|
"--editor",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2022-11-27
|
|
1
|
+
"""Created on 2022-11-27.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -15,10 +14,10 @@ from bs4 import BeautifulSoup
|
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class Editor:
|
|
18
|
-
"""
|
|
19
|
-
helper class to open the system defined editor
|
|
17
|
+
"""Helper class to open the system defined editor.
|
|
20
18
|
|
|
21
|
-
see
|
|
19
|
+
see
|
|
20
|
+
https://stackoverflow.com/questions/1442841/lauch-default-editor-like-webbrowser-module
|
|
22
21
|
"""
|
|
23
22
|
|
|
24
23
|
@classmethod
|
|
@@ -32,8 +31,7 @@ class Editor:
|
|
|
32
31
|
|
|
33
32
|
@classmethod
|
|
34
33
|
def extract_text(cls, html_text: str) -> str:
|
|
35
|
-
"""
|
|
36
|
-
extract the text from the given html_text
|
|
34
|
+
"""Extract the text from the given html_text.
|
|
37
35
|
|
|
38
36
|
Args:
|
|
39
37
|
html_text(str): the input for the html text
|
|
@@ -65,8 +63,7 @@ class Editor:
|
|
|
65
63
|
extract_text: bool = True,
|
|
66
64
|
default_editor_cmd: str = "/usr/local/bin/atom",
|
|
67
65
|
) -> str:
|
|
68
|
-
"""
|
|
69
|
-
open an editor for the given file_source
|
|
66
|
+
"""Open an editor for the given file_source.
|
|
70
67
|
|
|
71
68
|
Args:
|
|
72
69
|
file_source(str): the path to the file
|
|
@@ -104,8 +101,7 @@ class Editor:
|
|
|
104
101
|
|
|
105
102
|
@classmethod
|
|
106
103
|
def open_tmp_text(cls, text: str, file_name: str = None) -> str:
|
|
107
|
-
"""
|
|
108
|
-
open an editor for the given text in a newly created temporary file
|
|
104
|
+
"""Open an editor for the given text in a newly created temporary file.
|
|
109
105
|
|
|
110
106
|
Args:
|
|
111
107
|
text(str): the text to write to a temporary file and then open
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2024-08-27
|
|
1
|
+
"""Created on 2024-08-27.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -25,17 +24,13 @@ class GitHubApi:
|
|
|
25
24
|
|
|
26
25
|
@classmethod
|
|
27
26
|
def get_instance(cls) -> "GitHubApi":
|
|
28
|
-
"""
|
|
29
|
-
singleton access
|
|
30
|
-
"""
|
|
27
|
+
"""Singleton access."""
|
|
31
28
|
if cls.githubapi_instance is None:
|
|
32
29
|
cls.githubapi_instance = cls()
|
|
33
30
|
return cls.githubapi_instance
|
|
34
31
|
|
|
35
32
|
def __init__(self):
|
|
36
|
-
"""
|
|
37
|
-
constructor
|
|
38
|
-
"""
|
|
33
|
+
"""constructor."""
|
|
39
34
|
home_dir = os.path.expanduser("~")
|
|
40
35
|
self.base_dir = os.path.join(home_dir, ".github")
|
|
41
36
|
os.makedirs(self.base_dir, exist_ok=True)
|
|
@@ -50,9 +45,8 @@ class GitHubApi:
|
|
|
50
45
|
self.api_url = "https://api.github.com"
|
|
51
46
|
|
|
52
47
|
def load_access_token(self) -> str:
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
"""
|
|
48
|
+
"""If $HOME/.github/access_token.json exists read the token from
|
|
49
|
+
there."""
|
|
56
50
|
# Specify the path to the access token file
|
|
57
51
|
token_file_path = os.path.join(self.base_dir, "access_token.json")
|
|
58
52
|
|
|
@@ -66,8 +60,7 @@ class GitHubApi:
|
|
|
66
60
|
return None
|
|
67
61
|
|
|
68
62
|
def get_response(self, title: str, url: str, params={}, allow_redirects=True):
|
|
69
|
-
"""
|
|
70
|
-
Get response from GitHub API or Google Docs API
|
|
63
|
+
"""Get response from GitHub API or Google Docs API.
|
|
71
64
|
|
|
72
65
|
Args:
|
|
73
66
|
title (str): Description of the request
|
|
@@ -95,8 +88,8 @@ class GitHubApi:
|
|
|
95
88
|
return response
|
|
96
89
|
|
|
97
90
|
def repos_for_owner(self, owner: str, cache_expiry: int = 300) -> list[dict]:
|
|
98
|
-
"""
|
|
99
|
-
|
|
91
|
+
"""Retrieve all repositories for the given owner, using cache if
|
|
92
|
+
available and valid, or via API otherwise.
|
|
100
93
|
|
|
101
94
|
This method first checks if the repository data is available in the cache. If not, it fetches the
|
|
102
95
|
data from the GitHub API and caches it for future use.
|
|
@@ -129,8 +122,7 @@ class GitHubApi:
|
|
|
129
122
|
def repos_for_owner_from_cache(
|
|
130
123
|
self, owner: str
|
|
131
124
|
) -> tuple[str, list[dict] | None, float | None]:
|
|
132
|
-
"""
|
|
133
|
-
Retrieve repositories for the given owner from the cache.
|
|
125
|
+
"""Retrieve repositories for the given owner from the cache.
|
|
134
126
|
|
|
135
127
|
Args:
|
|
136
128
|
owner (str): The username of the owner whose repositories are being retrieved.
|
|
@@ -154,8 +146,8 @@ class GitHubApi:
|
|
|
154
146
|
return cache_file, cache_content, cache_age
|
|
155
147
|
|
|
156
148
|
def repos_for_owner_via_api(self, owner: str) -> list[dict]:
|
|
157
|
-
"""
|
|
158
|
-
|
|
149
|
+
"""Retrieve all repositories for the given owner directly from the
|
|
150
|
+
GitHub API.
|
|
159
151
|
|
|
160
152
|
Args:
|
|
161
153
|
owner (str): The username of the owner whose repositories are being retrieved.
|
|
@@ -187,8 +179,7 @@ class GitHubApi:
|
|
|
187
179
|
|
|
188
180
|
@dataclass
|
|
189
181
|
class GitHubRepo:
|
|
190
|
-
"""
|
|
191
|
-
Represents a GitHub Repository
|
|
182
|
+
"""Represents a GitHub Repository.
|
|
192
183
|
|
|
193
184
|
Attributes:
|
|
194
185
|
owner (str): The owner of the repository.
|
|
@@ -203,8 +194,7 @@ class GitHubRepo:
|
|
|
203
194
|
|
|
204
195
|
@classmethod
|
|
205
196
|
def from_url(cls, url: str) -> (str, str):
|
|
206
|
-
"""
|
|
207
|
-
Resolve project url to owner and project name
|
|
197
|
+
"""Resolve project url to owner and project name.
|
|
208
198
|
|
|
209
199
|
Returns:
|
|
210
200
|
(owner, project)
|
|
@@ -257,8 +247,8 @@ class GitHubRepo:
|
|
|
257
247
|
|
|
258
248
|
@dataclass
|
|
259
249
|
class GitHubAction:
|
|
260
|
-
"""
|
|
261
|
-
|
|
250
|
+
"""Represents a GitHub Action with its identifying information and log
|
|
251
|
+
content.
|
|
262
252
|
|
|
263
253
|
Attributes:
|
|
264
254
|
repo (GitHubRepo): The repository associated with this action.
|
|
@@ -287,8 +277,8 @@ class GitHubAction:
|
|
|
287
277
|
|
|
288
278
|
@classmethod
|
|
289
279
|
def from_url(cls, url: str) -> "GitHubAction":
|
|
290
|
-
"""
|
|
291
|
-
|
|
280
|
+
"""Create a GitHubAction instance from a GitHub Actions URL and fetch
|
|
281
|
+
its logs.
|
|
292
282
|
|
|
293
283
|
Args:
|
|
294
284
|
url (str): The GitHub Actions URL.
|
|
@@ -313,8 +303,7 @@ class GitHubAction:
|
|
|
313
303
|
|
|
314
304
|
@classmethod
|
|
315
305
|
def get_latest_workflow_run(cls, project):
|
|
316
|
-
"""
|
|
317
|
-
Get the latest GitHub Actions workflow run for a given project.
|
|
306
|
+
"""Get the latest GitHub Actions workflow run for a given project.
|
|
318
307
|
|
|
319
308
|
Args:
|
|
320
309
|
project (OsProject): The project to check for the latest workflow run.
|
|
@@ -331,9 +320,7 @@ class GitHubAction:
|
|
|
331
320
|
return run
|
|
332
321
|
|
|
333
322
|
def fetch_logs(self):
|
|
334
|
-
"""
|
|
335
|
-
Fetch the logs for this GitHub Action.
|
|
336
|
-
"""
|
|
323
|
+
"""Fetch the logs for this GitHub Action."""
|
|
337
324
|
if self.log_content is None:
|
|
338
325
|
api_url = f"https://api.github.com/repos/{self.repo.owner}/{self.repo.project_id}/actions/jobs/{self.job_id}/logs"
|
|
339
326
|
log_response = self.repo.github.get_response(
|
|
@@ -344,9 +331,7 @@ class GitHubAction:
|
|
|
344
331
|
self.save_logs()
|
|
345
332
|
|
|
346
333
|
def save_logs(self):
|
|
347
|
-
"""
|
|
348
|
-
Save the log content to a local file.
|
|
349
|
-
"""
|
|
334
|
+
"""Save the log content to a local file."""
|
|
350
335
|
if self.log_content is None:
|
|
351
336
|
raise ValueError("No log content to save. Make sure to fetch logs first.")
|
|
352
337
|
with open(self.log_file, "w", encoding="utf-8") as f:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2022-01-24
|
|
1
|
+
"""Created on 2022-01-24.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -21,9 +20,7 @@ from osprojects.github_api import GitHubApi, GitHubRepo
|
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
class Ticket(object):
|
|
24
|
-
"""
|
|
25
|
-
a Ticket
|
|
26
|
-
"""
|
|
23
|
+
"""A Ticket."""
|
|
27
24
|
|
|
28
25
|
@staticmethod
|
|
29
26
|
def getSamples():
|
|
@@ -46,18 +43,14 @@ class Ticket(object):
|
|
|
46
43
|
|
|
47
44
|
@classmethod
|
|
48
45
|
def init_from_dict(cls, **records):
|
|
49
|
-
"""
|
|
50
|
-
inits Ticket from given args
|
|
51
|
-
"""
|
|
46
|
+
"""Inits Ticket from given args."""
|
|
52
47
|
issue = Ticket()
|
|
53
48
|
for k, v in records.items():
|
|
54
49
|
setattr(issue, k, v)
|
|
55
50
|
return issue
|
|
56
51
|
|
|
57
52
|
def toWikiMarkup(self) -> str:
|
|
58
|
-
"""
|
|
59
|
-
Returns Ticket in wiki markup
|
|
60
|
-
"""
|
|
53
|
+
"""Returns Ticket in wiki markup."""
|
|
61
54
|
return f"""# {{{{Ticket
|
|
62
55
|
|number={self.number}
|
|
63
56
|
|title={self.title}
|
|
@@ -69,9 +62,7 @@ class Ticket(object):
|
|
|
69
62
|
|
|
70
63
|
|
|
71
64
|
class Commit(object):
|
|
72
|
-
"""
|
|
73
|
-
a commit
|
|
74
|
-
"""
|
|
65
|
+
"""A commit."""
|
|
75
66
|
|
|
76
67
|
@staticmethod
|
|
77
68
|
def getSamples():
|
|
@@ -89,9 +80,7 @@ class Commit(object):
|
|
|
89
80
|
return samples
|
|
90
81
|
|
|
91
82
|
def toWikiMarkup(self):
|
|
92
|
-
"""
|
|
93
|
-
Returns Commit as wiki markup
|
|
94
|
-
"""
|
|
83
|
+
"""Returns Commit as wiki markup."""
|
|
95
84
|
params = [
|
|
96
85
|
f"{attr}={getattr(self, attr, '')}" for attr in self.getSamples()[0].keys()
|
|
97
86
|
]
|
|
@@ -100,14 +89,10 @@ class Commit(object):
|
|
|
100
89
|
|
|
101
90
|
|
|
102
91
|
class OsProjects:
|
|
103
|
-
"""
|
|
104
|
-
a set of open source projects
|
|
105
|
-
"""
|
|
92
|
+
"""A set of open source projects."""
|
|
106
93
|
|
|
107
94
|
def __init__(self):
|
|
108
|
-
"""
|
|
109
|
-
constructor
|
|
110
|
-
"""
|
|
95
|
+
"""constructor."""
|
|
111
96
|
self.projects = {}
|
|
112
97
|
self.projects_by_url = {}
|
|
113
98
|
self.local_projects = {}
|
|
@@ -124,8 +109,7 @@ class OsProjects:
|
|
|
124
109
|
self.selected_projects[project.projectUrl()] = project
|
|
125
110
|
|
|
126
111
|
def select_projects(self, owners=None, project_id=None, local_only=False):
|
|
127
|
-
"""
|
|
128
|
-
Select projects based on given criteria.
|
|
112
|
+
"""Select projects based on given criteria.
|
|
129
113
|
|
|
130
114
|
Args:
|
|
131
115
|
owners (Optional[list[str]]): The owners of the projects to select.
|
|
@@ -169,8 +153,7 @@ class OsProjects:
|
|
|
169
153
|
return self.selected_projects
|
|
170
154
|
|
|
171
155
|
def filter_projects(self, language=None, local_only=False):
|
|
172
|
-
"""
|
|
173
|
-
Filter the selected projects based on language and locality.
|
|
156
|
+
"""Filter the selected projects based on language and locality.
|
|
174
157
|
|
|
175
158
|
Args:
|
|
176
159
|
language (str, optional): The programming language to filter by.
|
|
@@ -197,9 +180,7 @@ class OsProjects:
|
|
|
197
180
|
return self.selected_projects
|
|
198
181
|
|
|
199
182
|
def add_projects_of_owner(self, owner: str, cache_expiry: int = 300):
|
|
200
|
-
"""
|
|
201
|
-
add the projects of the given owner
|
|
202
|
-
"""
|
|
183
|
+
"""Add the projects of the given owner."""
|
|
203
184
|
if not owner in self.projects:
|
|
204
185
|
self.projects[owner] = {}
|
|
205
186
|
repo_infos = self.github.repos_for_owner(owner, cache_expiry)
|
|
@@ -222,8 +203,7 @@ class OsProjects:
|
|
|
222
203
|
|
|
223
204
|
@classmethod
|
|
224
205
|
def get_project_url_from_git_config(cls, project_path: str) -> Optional[str]:
|
|
225
|
-
"""
|
|
226
|
-
Get the project URL from the git config file.
|
|
206
|
+
"""Get the project URL from the git config file.
|
|
227
207
|
|
|
228
208
|
Args:
|
|
229
209
|
project_path (str): The path to the project directory.
|
|
@@ -248,8 +228,7 @@ class OsProjects:
|
|
|
248
228
|
|
|
249
229
|
@classmethod
|
|
250
230
|
def from_folder(cls, folder_path: str, with_progress: bool = False) -> "OsProjects":
|
|
251
|
-
"""
|
|
252
|
-
Collect all github projects from the given folders.
|
|
231
|
+
"""Collect all github projects from the given folders.
|
|
253
232
|
|
|
254
233
|
Args:
|
|
255
234
|
folder_path (str): The path to the folder containing projects.
|
|
@@ -285,8 +264,7 @@ class OsProjects:
|
|
|
285
264
|
def github_repos_of_folder(
|
|
286
265
|
cls, folder_path: str
|
|
287
266
|
) -> Tuple[Set[str], Dict[str, GitHubRepo]]:
|
|
288
|
-
"""
|
|
289
|
-
Collect GitHub repositories from a given folder.
|
|
267
|
+
"""Collect GitHub repositories from a given folder.
|
|
290
268
|
|
|
291
269
|
Args:
|
|
292
270
|
folder_path (str): The path to the folder to search for repositories.
|
|
@@ -316,9 +294,7 @@ class OsProjects:
|
|
|
316
294
|
|
|
317
295
|
|
|
318
296
|
class OsProject:
|
|
319
|
-
"""
|
|
320
|
-
a GitHub based opens source project
|
|
321
|
-
"""
|
|
297
|
+
"""A GitHub based opens source project."""
|
|
322
298
|
|
|
323
299
|
def __init__(self, owner: str = None, project_id: str = None):
|
|
324
300
|
self.repo_info = None # might be fetched
|
|
@@ -328,9 +304,7 @@ class OsProject:
|
|
|
328
304
|
|
|
329
305
|
@classmethod
|
|
330
306
|
def fromUrl(cls, url: str) -> "OsProject":
|
|
331
|
-
"""
|
|
332
|
-
Init OsProject from given url
|
|
333
|
-
"""
|
|
307
|
+
"""Init OsProject from given url."""
|
|
334
308
|
if "github.com" in url:
|
|
335
309
|
os_project = cls()
|
|
336
310
|
os_project.repo = GitHubRepo.from_url(url)
|
|
@@ -340,12 +314,10 @@ class OsProject:
|
|
|
340
314
|
|
|
341
315
|
@classmethod
|
|
342
316
|
def fromRepo(cls):
|
|
343
|
-
"""
|
|
344
|
-
Init OsProject from repo in current working directory
|
|
345
|
-
"""
|
|
317
|
+
"""Init OsProject from repo in current working directory."""
|
|
346
318
|
url = subprocess.check_output(["git", "config", "--get", "remote.origin.url"])
|
|
347
319
|
url = url.decode().strip("\n")
|
|
348
|
-
repo= cls.fromUrl(url)
|
|
320
|
+
repo = cls.fromUrl(url)
|
|
349
321
|
return repo
|
|
350
322
|
|
|
351
323
|
def getIssues(self, limit: int = None, **params) -> List[Ticket]:
|
|
@@ -402,9 +374,7 @@ class OsProject:
|
|
|
402
374
|
return tickets_dict
|
|
403
375
|
|
|
404
376
|
def getComments(self, issue_number: int) -> List[dict]:
|
|
405
|
-
"""
|
|
406
|
-
Fetch all comments for a specific issue number from GitHub.
|
|
407
|
-
"""
|
|
377
|
+
"""Fetch all comments for a specific issue number from GitHub."""
|
|
408
378
|
comments_url = self.commentUrl(issue_number)
|
|
409
379
|
response = self.get_response("fetch comments", comments_url)
|
|
410
380
|
return response.json()
|
|
@@ -416,9 +386,7 @@ class OsProject:
|
|
|
416
386
|
return f"{self.projectUrl()}/commit/{commit_id}"
|
|
417
387
|
|
|
418
388
|
def commentUrl(self, issue_number: int):
|
|
419
|
-
"""
|
|
420
|
-
Construct the URL for accessing comments of a specific issue.
|
|
421
|
-
"""
|
|
389
|
+
"""Construct the URL for accessing comments of a specific issue."""
|
|
422
390
|
return f"{self.repo.github.api_url}/repos/{self.repo.owner}/{self.repo.project_id}/issues/{issue_number}/comments"
|
|
423
391
|
|
|
424
392
|
@property
|
|
@@ -530,9 +498,7 @@ class OsProject:
|
|
|
530
498
|
|
|
531
499
|
|
|
532
500
|
def gitlog2wiki(_argv=None):
|
|
533
|
-
"""
|
|
534
|
-
cmdline interface to get gitlog entries in wiki markup
|
|
535
|
-
"""
|
|
501
|
+
"""Cmdline interface to get gitlog entries in wiki markup."""
|
|
536
502
|
parser = argparse.ArgumentParser(description="gitlog2wiki")
|
|
537
503
|
if _argv:
|
|
538
504
|
_args = parser.parse_args(args=_argv)
|
|
@@ -543,9 +509,7 @@ def gitlog2wiki(_argv=None):
|
|
|
543
509
|
|
|
544
510
|
|
|
545
511
|
def main(_argv=None):
|
|
546
|
-
"""
|
|
547
|
-
main command line entry point
|
|
548
|
-
"""
|
|
512
|
+
"""Main command line entry point."""
|
|
549
513
|
parser = argparse.ArgumentParser(description="Issue2ticket")
|
|
550
514
|
parser.add_argument("-o", "--owner", help="project owner")
|
|
551
515
|
parser.add_argument("-p", "--project", help="name of the project")
|
|
@@ -15,13 +15,15 @@ readme = "README.md"
|
|
|
15
15
|
license = "Apache-2.0"
|
|
16
16
|
|
|
17
17
|
dependencies = [
|
|
18
|
+
# https://pypi.org/project/beautifulsoup4/
|
|
19
|
+
"beautifulsoup4>=4.14.2",
|
|
18
20
|
# https://pypi.org/project/GitPython/
|
|
19
21
|
"gitpython",
|
|
20
22
|
# https://pypi.org/project/requests/
|
|
21
23
|
"requests",
|
|
22
24
|
"pyLodStorage>=0.17.0",
|
|
23
25
|
# https://pypi.org/project/py-3rdparty-mediawiki/
|
|
24
|
-
'py-3rdparty-mediawiki>=0.
|
|
26
|
+
'py-3rdparty-mediawiki>=0.18.1',
|
|
25
27
|
# https://pypi.org/project/python-dateutil/
|
|
26
28
|
"python-dateutil>=2.8.2",
|
|
27
29
|
# https://github.com/pypa/packaging
|
|
@@ -29,11 +31,10 @@ dependencies = [
|
|
|
29
31
|
# https://pypi.org/project/tqdm/
|
|
30
32
|
"tqdm>=4.66.5"
|
|
31
33
|
]
|
|
32
|
-
requires-python = ">=3.
|
|
34
|
+
requires-python = ">=3.11"
|
|
33
35
|
|
|
34
36
|
classifiers = [
|
|
35
37
|
"Programming Language :: Python",
|
|
36
|
-
"Programming Language :: Python :: 3.10",
|
|
37
38
|
"Programming Language :: Python :: 3.11",
|
|
38
39
|
"Programming Language :: Python :: 3.12",
|
|
39
40
|
"Programming Language :: Python :: 3.13"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# WF 2024-01-10
|
|
3
|
+
package=osprojects
|
|
4
|
+
|
|
5
|
+
# Sort imports
|
|
6
|
+
isort tests/*.py
|
|
7
|
+
isort $package/*.py
|
|
8
|
+
|
|
9
|
+
# Format code
|
|
10
|
+
black tests/*.py
|
|
11
|
+
black $package/*.py
|
|
12
|
+
|
|
13
|
+
# Format docstrings
|
|
14
|
+
docformatter --in-place tests/*.py
|
|
15
|
+
docformatter --in-place $package/*.py
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2021-08-19
|
|
1
|
+
"""Created on 2021-08-19.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -15,14 +14,10 @@ from unittest import TestCase
|
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class BaseTest(TestCase):
|
|
18
|
-
"""
|
|
19
|
-
base test case
|
|
20
|
-
"""
|
|
17
|
+
"""Base test case."""
|
|
21
18
|
|
|
22
19
|
def setUp(self, debug=False, profile=True):
|
|
23
|
-
"""
|
|
24
|
-
setUp test environment
|
|
25
|
-
"""
|
|
20
|
+
"""SetUp test environment."""
|
|
26
21
|
TestCase.setUp(self)
|
|
27
22
|
self.debug = debug
|
|
28
23
|
self.profile = profile
|
|
@@ -35,9 +30,7 @@ class BaseTest(TestCase):
|
|
|
35
30
|
|
|
36
31
|
@staticmethod
|
|
37
32
|
def inPublicCI():
|
|
38
|
-
"""
|
|
39
|
-
are we running in a public Continuous Integration Environment?
|
|
40
|
-
"""
|
|
33
|
+
"""Are we running in a public Continuous Integration Environment?"""
|
|
41
34
|
publicCI = getpass.getuser() in ["travis", "runner"]
|
|
42
35
|
jenkins = "JENKINS_HOME" in os.environ
|
|
43
36
|
return publicCI or jenkins
|
|
@@ -71,8 +64,7 @@ class BaseTest(TestCase):
|
|
|
71
64
|
|
|
72
65
|
@staticmethod
|
|
73
66
|
def captureOutput(fn: Callable, *args, **kwargs) -> str:
|
|
74
|
-
"""
|
|
75
|
-
Captures stdout put of the given function
|
|
67
|
+
"""Captures stdout put of the given function.
|
|
76
68
|
|
|
77
69
|
Args:
|
|
78
70
|
fn(callable): function to call
|
|
@@ -93,13 +85,10 @@ if __name__ == "__main__":
|
|
|
93
85
|
|
|
94
86
|
|
|
95
87
|
class Profiler:
|
|
96
|
-
"""
|
|
97
|
-
simple profiler
|
|
98
|
-
"""
|
|
88
|
+
"""Simple profiler."""
|
|
99
89
|
|
|
100
90
|
def __init__(self, msg, profile=True):
|
|
101
|
-
"""
|
|
102
|
-
construct me with the given msg and profile active flag
|
|
91
|
+
"""Construct me with the given msg and profile active flag.
|
|
103
92
|
|
|
104
93
|
Args:
|
|
105
94
|
msg(str): the message to show if profiling is active
|
|
@@ -112,9 +101,7 @@ class Profiler:
|
|
|
112
101
|
print(f"Starting {msg} ...")
|
|
113
102
|
|
|
114
103
|
def time(self, extraMsg=""):
|
|
115
|
-
"""
|
|
116
|
-
time the action and print if profile is active
|
|
117
|
-
"""
|
|
104
|
+
"""Time the action and print if profile is active."""
|
|
118
105
|
elapsed = time.time() - self.starttime
|
|
119
106
|
if self.profile:
|
|
120
107
|
print(f"{self.msg}{extraMsg} took {elapsed:5.1f} s")
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2024-08-27
|
|
1
|
+
"""Created on 2024-08-27.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -12,17 +11,13 @@ from tests.basetest import BaseTest
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class TestGitHub(BaseTest):
|
|
15
|
-
"""
|
|
16
|
-
tests GitHub class
|
|
17
|
-
"""
|
|
14
|
+
"""Tests GitHub class."""
|
|
18
15
|
|
|
19
16
|
def setUp(self, debug=True, profile=True):
|
|
20
17
|
BaseTest.setUp(self, debug=debug, profile=profile)
|
|
21
18
|
|
|
22
19
|
def test_GitHubRepo_from_url(self):
|
|
23
|
-
"""
|
|
24
|
-
tests the creating GitHubRepos from the project url
|
|
25
|
-
"""
|
|
20
|
+
"""Tests the creating GitHubRepos from the project url."""
|
|
26
21
|
urlCases = [
|
|
27
22
|
{
|
|
28
23
|
"owner": "WolfgangFahl",
|
|
@@ -49,9 +44,7 @@ class TestGitHub(BaseTest):
|
|
|
49
44
|
self.assertEqual(expectedProject, github_repo.project_id)
|
|
50
45
|
|
|
51
46
|
def testOsProjects(self):
|
|
52
|
-
"""
|
|
53
|
-
tests the list_projects_as_os_projects method
|
|
54
|
-
"""
|
|
47
|
+
"""Tests the list_projects_as_os_projects method."""
|
|
55
48
|
owner = "WolfgangFahl"
|
|
56
49
|
project_id = "pyOpenSourceProjects"
|
|
57
50
|
osprojects = OsProjects.from_owners([owner])
|
|
@@ -105,9 +98,7 @@ class TestGitHub(BaseTest):
|
|
|
105
98
|
"Tests querying wikidata which is often blocked on public CI",
|
|
106
99
|
)
|
|
107
100
|
def test_projects_from_folder(self):
|
|
108
|
-
"""
|
|
109
|
-
test projects from a specific folder
|
|
110
|
-
"""
|
|
101
|
+
"""Test projects from a specific folder."""
|
|
111
102
|
debug = self.debug
|
|
112
103
|
# debug=True
|
|
113
104
|
home_dir = os.path.expanduser("~")
|
|
@@ -117,4 +108,4 @@ class TestGitHub(BaseTest):
|
|
|
117
108
|
if debug:
|
|
118
109
|
print(f"found {count} local projects")
|
|
119
110
|
self.assertTrue(count > 30)
|
|
120
|
-
pass
|
|
111
|
+
pass
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2024-08-27
|
|
1
|
+
"""Created on 2024-08-27.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
@@ -12,18 +11,15 @@ from tests.basetest import BaseTest
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class TestGitHubApi(BaseTest):
|
|
15
|
-
"""
|
|
16
|
-
test the GithHubApi functionalities
|
|
17
|
-
"""
|
|
14
|
+
"""Test the GithHubApi functionalities."""
|
|
18
15
|
|
|
19
16
|
def setUp(self, debug=False, profile=True):
|
|
20
17
|
BaseTest.setUp(self, debug=debug, profile=profile)
|
|
21
18
|
self.github = GitHubApi.get_instance()
|
|
22
19
|
|
|
23
20
|
def test_repos_for_owner(self):
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
"""
|
|
21
|
+
"""Test the repos_for_owner method for two owners, with caching in
|
|
22
|
+
between."""
|
|
27
23
|
owners = ["WolfgangFahl", "BITPlan"]
|
|
28
24
|
cache_expiry = 300 # 5 minutes
|
|
29
25
|
|
|
@@ -45,9 +41,7 @@ class TestGitHubApi(BaseTest):
|
|
|
45
41
|
|
|
46
42
|
@unittest.skipIf(BaseTest.inPublicCI(), "missing admin rights in public CI")
|
|
47
43
|
def test_github_action_from_url(self):
|
|
48
|
-
"""
|
|
49
|
-
Test creating GitHubAction instances from URLs.
|
|
50
|
-
"""
|
|
44
|
+
"""Test creating GitHubAction instances from URLs."""
|
|
51
45
|
test_cases = [
|
|
52
46
|
(
|
|
53
47
|
"single_failure",
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2022-01-24
|
|
1
|
+
"""Created on 2022-01-24.
|
|
3
2
|
|
|
4
3
|
@author: wf
|
|
5
4
|
"""
|
|
6
5
|
|
|
6
|
+
from argparse import Namespace
|
|
7
|
+
|
|
8
|
+
from osprojects.check_project import CheckProject
|
|
7
9
|
from osprojects.osproject import Commit, OsProject, Ticket, gitlog2wiki, main
|
|
10
|
+
|
|
8
11
|
from tests.basetest import BaseTest
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
class TestOsProject(BaseTest):
|
|
12
|
-
"""
|
|
13
|
-
test the OsProject concepts
|
|
14
|
-
"""
|
|
15
|
+
"""Test the OsProject concepts."""
|
|
15
16
|
|
|
16
17
|
def testOsProject(self):
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
"""
|
|
18
|
+
"""Tests if the projects details, commits and issues/tickets are
|
|
19
|
+
correctly queried."""
|
|
20
20
|
osProject = OsProject(owner="WolfgangFahl", project_id="pyOpenSourceProjects")
|
|
21
21
|
tickets = osProject.getAllTickets()
|
|
22
22
|
sampleTicket = self.getSampleById(Ticket, "number", 2)
|
|
@@ -33,10 +33,25 @@ class TestOsProject(BaseTest):
|
|
|
33
33
|
self.assertEqual(ticket2.project, sampleTicket.project)
|
|
34
34
|
pass
|
|
35
35
|
|
|
36
|
+
def testBadgeMarkdown(self):
|
|
37
|
+
"""Tests badge markdown generation."""
|
|
38
|
+
osProject = OsProject(owner="WolfgangFahl", project_id="pyOpenSourceProjects")
|
|
39
|
+
|
|
40
|
+
args = Namespace(badges=True, debug=False, editor=False)
|
|
41
|
+
checker = CheckProject(parent=None, project=osProject, args=args)
|
|
42
|
+
checker.project_name = "pyOpenSourceProjects"
|
|
43
|
+
|
|
44
|
+
markup = checker.generate_badge_markdown()
|
|
45
|
+
|
|
46
|
+
self.assertIn("| **PyPi** |", markup)
|
|
47
|
+
self.assertIn("| **GitHub** |", markup)
|
|
48
|
+
self.assertIn("| **Code** |", markup)
|
|
49
|
+
self.assertIn("| **Docs** |", markup)
|
|
50
|
+
self.assertIn("[![PyPI Status]", markup)
|
|
51
|
+
self.assertIn("WolfgangFahl/pyOpenSourceProjects", markup)
|
|
52
|
+
|
|
36
53
|
def testGetCommits(self):
|
|
37
|
-
"""
|
|
38
|
-
tests extraction of commits for a repository
|
|
39
|
-
"""
|
|
54
|
+
"""Tests extraction of commits for a repository."""
|
|
40
55
|
if self.inPublicCI():
|
|
41
56
|
return
|
|
42
57
|
osProject = OsProject(owner="WolfgangFahl", project_id="pyOpenSourceProjects")
|
|
@@ -46,9 +61,7 @@ class TestOsProject(BaseTest):
|
|
|
46
61
|
self.assertDictEqual(expectedCommit.__dict__, commits[0].__dict__)
|
|
47
62
|
|
|
48
63
|
def testCmdLine(self):
|
|
49
|
-
"""
|
|
50
|
-
tests cmdline of osproject
|
|
51
|
-
"""
|
|
64
|
+
"""Tests cmdline of osproject."""
|
|
52
65
|
testParams = [
|
|
53
66
|
["-o", "WolfgangFahl", "-p", "pyOpenSourceProjects"],
|
|
54
67
|
["--repo"],
|
|
@@ -59,9 +72,7 @@ class TestOsProject(BaseTest):
|
|
|
59
72
|
self.assertIn("{{Ticket", output)
|
|
60
73
|
|
|
61
74
|
def testGitlog2IssueCmdline(self):
|
|
62
|
-
"""
|
|
63
|
-
tests gitlog2issue
|
|
64
|
-
"""
|
|
75
|
+
"""Tests gitlog2issue."""
|
|
65
76
|
if self.inPublicCI():
|
|
66
77
|
return
|
|
67
78
|
commit = self.getSampleById(Commit, "hash", "106254f")
|
|
@@ -72,14 +83,10 @@ class TestOsProject(BaseTest):
|
|
|
72
83
|
|
|
73
84
|
|
|
74
85
|
class TestCommit(BaseTest):
|
|
75
|
-
"""
|
|
76
|
-
Tests Commit class
|
|
77
|
-
"""
|
|
86
|
+
"""Tests Commit class."""
|
|
78
87
|
|
|
79
88
|
def testToWikiMarkup(self):
|
|
80
|
-
"""
|
|
81
|
-
tests toWikiMarkup
|
|
82
|
-
"""
|
|
89
|
+
"""Tests toWikiMarkup."""
|
|
83
90
|
commit = self.getSampleById(Commit, "hash", "106254f")
|
|
84
91
|
expectedMarkup = "{{commit|host=https://github.com/WolfgangFahl/pyOpenSourceProjects|path=|project=pyOpenSourceProjects|subject=Initial commit|name=GitHub|date=2022-01-24 07:02:55+01:00|hash=106254f|storemode=subobject|viewmode=line}}"
|
|
85
92
|
self.assertEqual(expectedMarkup, commit.toWikiMarkup())
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# pyOpenSourceProjects
|
|
2
|
-
Helper Library to organize open source Projects
|
|
3
|
-
|
|
4
|
-
| | |
|
|
5
|
-
| :--- | :--- |
|
|
6
|
-
| **GitHub** | [](https://github.com/WolfgangFahl/pyOpenSourceProjects/actions/workflows/build.yml) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/issues) [](https://github.com/WolfgangFahl/pyOpenSourceProjects/issues/?q=is%3Aissue+is%3Aclosed) |
|
|
7
|
-
| **PyPi** | [](https://pypi.python.org/pypi/pyOpenSourceProjects/) [](https://www.apache.org/licenses/LICENSE-2.0) [](https://pypi.org/project/pyOpenSourceProjects/) |
|
|
8
|
-
| **Docs** | [](https://WolfgangFahl.github.io/pyOpenSourceProjects/) |
|
|
9
|
-
|
|
10
|
-
## Documentation
|
|
11
|
-
[Wiki](https://wiki.bitplan.com/index.php/PyOpenSourceProjects)
|
|
12
|
-
|
|
13
|
-
### Authors
|
|
14
|
-
* [Tim Holzheim](https://www.semantic-mediawiki.org/wiki/Tim_Holzheim)
|
|
15
|
-
* [Wolfgang Fahl](http://www.bitplan.com/Wolfgang_Fahl)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.0"
|
{pyopensourceprojects-0.3.0 → pyopensourceprojects-0.4.0}/.github/workflows/upload-to-pypi.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|