pyOpenSourceProjects 0.2.1__tar.gz → 0.2.3__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 (25) hide show
  1. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/.github/workflows/build.yml +4 -4
  2. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/PKG-INFO +4 -3
  3. pyopensourceprojects-0.2.3/osprojects/__init__.py +1 -0
  4. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/osprojects/checkos.py +91 -14
  5. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/pyproject.toml +4 -2
  6. pyopensourceprojects-0.2.3/scripts/test +132 -0
  7. pyopensourceprojects-0.2.1/osprojects/__init__.py +0 -1
  8. pyopensourceprojects-0.2.1/scripts/test +0 -9
  9. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/.github/workflows/upload-to-pypi.yml +0 -0
  10. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/.gitignore +0 -0
  11. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/.project +0 -0
  12. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/.pydevproject +0 -0
  13. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/LICENSE +0 -0
  14. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/README.md +0 -0
  15. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/mkdocs.yml +0 -0
  16. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/osprojects/editor.py +0 -0
  17. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/osprojects/osproject.py +0 -0
  18. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/scripts/blackisort +0 -0
  19. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/scripts/doc +0 -0
  20. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/scripts/install +0 -0
  21. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/scripts/installAndTest +0 -0
  22. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/scripts/release +0 -0
  23. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/tests/__init__.py +0 -0
  24. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/tests/basetest.py +0 -0
  25. {pyopensourceprojects-0.2.1 → pyopensourceprojects-0.2.3}/tests/test_osproject.py +0 -0
@@ -18,10 +18,10 @@ jobs:
18
18
  runs-on: ubuntu-latest
19
19
  strategy:
20
20
  matrix:
21
- os: [ubuntu-latest, macos-latest, windows-latest]
22
- #os: [ubuntu-latest]
23
- python-version: [ 3.9, '3.10', '3.11', '3.12' ]
24
- #python-version: ["3.10"]
21
+ #os: [ubuntu-latest, macos-latest, windows-latest]
22
+ os: [ubuntu-latest]
23
+ #python-version: [ '3.9', '3.10', '3.11', '3.12' ]
24
+ python-version: ["3.10"]
25
25
 
26
26
  steps:
27
27
  - uses: actions/checkout@v4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyOpenSourceProjects
3
- Version: 0.2.1
3
+ Version: 0.2.3
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
@@ -15,9 +15,10 @@ Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Requires-Python: >=3.9
18
+ Requires-Dist: gitpython
18
19
  Requires-Dist: packaging>=24.1
19
- Requires-Dist: py-3rdparty-mediawiki>=0.11.3
20
- Requires-Dist: pylodstorage>=0.11.6
20
+ Requires-Dist: py-3rdparty-mediawiki>=0.12.0
21
+ Requires-Dist: pylodstorage>=0.12.2
21
22
  Requires-Dist: python-dateutil>=2.8.2
22
23
  Provides-Extra: test
23
24
  Description-Content-Type: text/markdown
@@ -0,0 +1 @@
1
+ __version__ = "0.2.3"
@@ -8,6 +8,8 @@ import argparse
8
8
  import os
9
9
  from argparse import Namespace
10
10
  from dataclasses import dataclass
11
+ from git import Repo
12
+ from git.exc import InvalidGitRepositoryError, NoSuchPathError
11
13
  from typing import List
12
14
  # original at ngwidgets - use redundant local copy ...
13
15
  from osprojects.editor import Editor
@@ -49,6 +51,8 @@ class CheckOS:
49
51
  self.project = project
50
52
  self.project_path = os.path.join(self.workspace, project.id)
51
53
  self.checks = []
54
+ # python 3.12 is max version
55
+ self.max_python_version_minor=12
52
56
 
53
57
  @property
54
58
  def total(self) -> int:
@@ -91,6 +95,9 @@ class CheckOS:
91
95
  return local
92
96
 
93
97
  def check_github_workflows(self):
98
+ """
99
+ check the github workflow files
100
+ """
94
101
  workflows_path = os.path.join(self.project_path, ".github", "workflows")
95
102
  workflows_exist = self.add_path_check(workflows_path)
96
103
 
@@ -104,8 +111,9 @@ class CheckOS:
104
111
  content = file_exists.content
105
112
 
106
113
  if file == "build.yml":
107
- min_version = int(self.requires_python.split('.')[-1])
108
- python_versions = f"""python-version: [ {', '.join([f"'3.{i}'" for i in range(min_version, 13)])} ]"""
114
+ min_python_version_minor = int(self.requires_python.split('.')[-1])
115
+ self.add_check(min_python_version_minor==self.min_python_version_minor,msg=f"{min_python_version_minor} (build.yml)!={self.min_python_version_minor} (pyprojec.toml)",path=file_path)
116
+ python_versions = f"""python-version: [ {', '.join([f"'3.{i}'" for i in range(self.min_python_version_minor, self.max_python_version_minor+1)])} ]"""
109
117
  self.add_content_check(
110
118
  content,
111
119
  python_versions,
@@ -159,12 +167,17 @@ class CheckOS:
159
167
  if file=="doc":
160
168
  self.add_content_check(content, "sphinx", file_path, negative=True)
161
169
  self.add_content_check(content,"WF 2024-07-30 - updated",file_path)
170
+ if file=="test":
171
+ self.add_content_check(content,"WF 2024-08-03",file_path)
162
172
  if file=="release":
163
- self.add_content_check(content, "scripts/docs -d", file_path, negative=True)
173
+ self.add_content_check(content, "scripts/doc -d", file_path)
164
174
 
165
175
  def check_readme(self):
166
176
  readme_path = os.path.join(self.project_path, "README.md")
167
177
  readme_exists = self.add_path_check(readme_path)
178
+ if not hasattr(self, "project_name"):
179
+ self.add_check(False, "project_name from pyproject.toml needed for README.md check", self.project_path)
180
+ return
168
181
  if readme_exists.ok:
169
182
  readme_content = readme_exists.content
170
183
  badge_lines = [
@@ -185,7 +198,10 @@ class CheckOS:
185
198
  )
186
199
  self.add_content_check(readme_content, "readthedocs", readme_path, negative=True)
187
200
 
188
- def check_pyproject_toml(self):
201
+ def check_pyproject_toml(self)->bool:
202
+ """
203
+ pyproject.toml
204
+ """
189
205
  toml_path = os.path.join(self.project_path, "pyproject.toml")
190
206
  toml_exists = self.add_path_check(toml_path)
191
207
  if toml_exists.ok:
@@ -197,27 +213,78 @@ class CheckOS:
197
213
  requires_python_check=self.add_check("requires-python" in toml_dict["project"], "requires-python", toml_path)
198
214
  if requires_python_check.ok:
199
215
  self.requires_python = toml_dict["project"]["requires-python"]
200
- self.min_python_version = version.parse(self.requires_python.replace(">=", ""))
216
+ min_python_version = version.parse(self.requires_python.replace(">=", ""))
201
217
  min_version_needed="3.9"
202
- version_ok=self.min_python_version >= version.parse(min_version_needed)
218
+ version_ok=min_python_version >= version.parse(min_version_needed)
203
219
  self.add_check(version_ok, f"requires-python>={min_version_needed}", toml_path)
220
+ self.min_python_version_minor=int(str(min_python_version).split('.')[-1])
221
+ for minor_version in range(self.min_python_version_minor, self.max_python_version_minor+1):
222
+ needle=f"Programming Language :: Python :: 3.{minor_version}"
223
+ self.add_content_check(content, needle, toml_path)
204
224
  self.add_content_check(content, "hatchling", toml_path)
205
225
  self.add_content_check(content,"[tool.hatch.build.targets.wheel.sources]",toml_path)
226
+ return toml_exists.ok
227
+
228
+ def check_git(self):
229
+ """
230
+ Check git repository information using gitpython
231
+ """
232
+ try:
233
+ repo = Repo(self.project_path)
234
+
235
+ # Check if it's actually a git repository
236
+ if not repo.bare:
237
+ self.add_check(True, "Is a git repository", self.project_path)
238
+
239
+ # Get the remote URL
240
+ try:
241
+ remote_url = repo.remotes.origin.url
242
+ self.add_check(True, "Has remote origin", self.project_path)
206
243
 
207
- def check(self):
244
+ # Extract owner and repository name from the URL
245
+ parts = remote_url.split('/')
246
+ git_owner = parts[-2]
247
+ git_repo = parts[-1].replace('.git', '')
248
+
249
+ # Compare with the project information we have
250
+ owner_match = git_owner.lower() == self.project.owner.lower()
251
+ self.add_check(owner_match, f"Git owner ({git_owner}) matches project owner ({self.project.owner})", self.project_path)
252
+
253
+ repo_match = git_repo.lower() == self.project.id.lower()
254
+ self.add_check(repo_match, f"Git repo name ({git_repo}) matches project id ({self.project.id})", self.project_path)
255
+
256
+ except AttributeError:
257
+ self.add_check(False, "No remote origin found", self.project_path)
258
+
259
+ # Check if there are uncommitted changes
260
+ if repo.is_dirty():
261
+ self.add_check(False, "Repository has uncommitted changes", self.project_path)
262
+ else:
263
+ self.add_check(True, "Repository is clean", self.project_path)
264
+
265
+ else:
266
+ self.add_check(False, "Not a valid git repository (bare repository)", self.project_path)
267
+
268
+ except InvalidGitRepositoryError:
269
+ self.add_check(False, "Not a valid git repository", self.project_path)
270
+ except NoSuchPathError:
271
+ self.add_check(False, "Git repository path does not exist", self.project_path)
272
+
273
+ def check(self, title:str):
208
274
  """
209
275
  Check the given project and print results
210
276
  """
211
277
  self.check_local()
212
- self.check_pyproject_toml()
213
- self.check_readme()
214
- self.check_scripts()
215
- self.check_github_workflows()
278
+ self.check_git()
279
+ if self.check_pyproject_toml():
280
+ self.check_github_workflows()
281
+ self.check_readme()
282
+ self.check_scripts()
216
283
 
217
284
  # ok_count=len(ok_checks)
218
285
  failed_count = len(self.failed_checks)
219
- summary = f"❌ {failed_count}/{self.total}" if failed_count > 0 else f"✅ {self.total}/{self.total}"
220
- print(f"{self.project} {summary}: {self.project.url}")
286
+ summary = f"❌ {failed_count:2}/{self.total:2}" if failed_count > 0 else f"✅ {self.total:2}/{self.total:2}"
287
+ print(f"{title}{summary}:{self.project}→{self.project.url}")
221
288
  if failed_count > 0:
222
289
  # Sort checks by path
223
290
  sorted_checks = sorted(self.checks, key=lambda c: c.path or "")
@@ -308,9 +375,19 @@ def main(_argv=None):
308
375
  local_projects.append(project)
309
376
  projects = local_projects
310
377
 
378
+ # filter for git ownership
379
+ filtered_projects = []
311
380
  for project in projects:
312
381
  checker = CheckOS(args=args, project=project)
313
- checker.check()
382
+ checker.check_git()
383
+ git_owner_check = next((check for check in checker.checks if "Git owner" in check.msg), None)
384
+ if git_owner_check and git_owner_check.ok:
385
+ filtered_projects.append(project)
386
+ projects = filtered_projects
387
+
388
+ for i,project in enumerate(projects):
389
+ checker = CheckOS(args=args, project=project)
390
+ checker.check(f"{i+1:3}:")
314
391
  except Exception as ex:
315
392
  if args.debug:
316
393
  print(traceback.format_exc())
@@ -15,8 +15,10 @@ readme = "README.md"
15
15
  license = "Apache-2.0"
16
16
 
17
17
  dependencies = [
18
- "pyLodStorage>=0.11.6",
19
- "py-3rdparty-mediawiki>=0.11.3",
18
+ # https://pypi.org/project/GitPython/
19
+ "gitpython",
20
+ "pyLodStorage>=0.12.2",
21
+ "py-3rdparty-mediawiki>=0.12.0",
20
22
  # https://pypi.org/project/python-dateutil/
21
23
  "python-dateutil>=2.8.2",
22
24
  # https://github.com/pypa/packaging
@@ -0,0 +1,132 @@
1
+ #!/bin/bash
2
+ # WF 2022-08-20
3
+ # WF 2024-08-03
4
+
5
+ #ansi colors
6
+ #http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
7
+ blue='\033[0;34m'
8
+ red='\033[0;31m'
9
+ green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
10
+ endColor='\033[0m'
11
+
12
+ #
13
+ # a colored message
14
+ # params:
15
+ # 1: l_color - the color of the message
16
+ # 2: l_msg - the message to display
17
+ #
18
+ color_msg() {
19
+ local l_color="$1"
20
+ local l_msg="$2"
21
+ echo -e "${l_color}$l_msg${endColor}"
22
+ }
23
+
24
+ #
25
+ # error
26
+ #
27
+ # show the given error message on stderr and exit
28
+ #
29
+ # params:
30
+ # 1: l_msg - the error message to display
31
+ #
32
+ error() {
33
+ local l_msg="$1"
34
+ # use ansi red for error
35
+ color_msg $red "Error:" 1>&2
36
+ color_msg $red "\t$l_msg" 1>&2
37
+ exit 1
38
+ }
39
+
40
+ #
41
+ # show a negative message
42
+ #
43
+ negative() {
44
+ local l_msg="$1"
45
+ color_msg $red "❌:$l_msg"
46
+ }
47
+
48
+ #
49
+ # show a positive message
50
+ #
51
+ positive() {
52
+ local l_msg="$1"
53
+ color_msg $green "✅:$l_msg"
54
+ }
55
+
56
+ # show usage
57
+ #
58
+ usage() {
59
+ echo "$0 [-g|--green|-m|--module|-t|--tox|-h|--help]"
60
+ echo "-t |--tox: run tests with tox"
61
+ echo "-g |--green: run tests with green"
62
+ echo "-m |--module: run modulewise test"
63
+ echo "-h |--help: show this usage"
64
+ echo "default is running tests with unittest discover"
65
+ exit 1
66
+ }
67
+
68
+ #
69
+ # check and optional install the given package
70
+ #
71
+ check_package() {
72
+ local l_package="$1"
73
+ pip show $l_package > /dev/null
74
+ if [ $? -ne 0 ]
75
+ then
76
+ negative "$l_package"
77
+ color_msg $blue "installing $l_package"
78
+ pip install $l_package
79
+ else
80
+ positive "$l_package"
81
+ fi
82
+ }
83
+
84
+ #
85
+ # test module by module
86
+ #
87
+ modulewise_test() {
88
+ foundErrors=0
89
+ foundTests=0
90
+ for testmodule in tests/test*.py
91
+ do
92
+ echo "testing $testmodule ..."
93
+ # see https://github.com/CleanCut/green/issues/263
94
+ #green $testmodule -s1
95
+ python -m unittest $testmodule
96
+ exit_code=$?
97
+ foundErrors=$((foundErrors+exit_code))
98
+ foundTests=$((foundTests+1))
99
+ done
100
+ echo "$foundErrors/$foundTests module unit tests failed" 1>&2
101
+ if [[ $foundErrors -gt 0 ]]
102
+ then
103
+ exit 1
104
+ fi
105
+ }
106
+
107
+ export PYTHON_PATH="."
108
+ while [ "$1" != "" ]
109
+ do
110
+ option="$1"
111
+ case $option in
112
+ -h|--help)
113
+ usage
114
+ exit 0
115
+ ;;
116
+ -g|--green)
117
+ check_package green
118
+ green tests -s 1
119
+ exit 0
120
+ ;;
121
+ -m|--module)
122
+ modulewise_test
123
+ exit 0
124
+ ;;
125
+ -t|--tox)
126
+ check_package tox
127
+ tox -e py
128
+ exit 0
129
+ ;;
130
+ esac
131
+ done
132
+ python3 -m unittest discover
@@ -1 +0,0 @@
1
- __version__ = "0.2.1"
@@ -1,9 +0,0 @@
1
- #!/bin/bash
2
- # WF 2020-06-03
3
- #python3 -m unittest discover
4
- pip list | egrep "^green "
5
- if [ $? -ne 0 ]
6
- then
7
- pip install green
8
- fi
9
- green