rsfc 0.0.1__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.
- rsfc-0.0.1/LICENSE +21 -0
- rsfc-0.0.1/PKG-INFO +197 -0
- rsfc-0.0.1/README.md +100 -0
- rsfc-0.0.1/pyproject.toml +99 -0
- rsfc-0.0.1/src/rsfc/__init__.py +3 -0
- rsfc-0.0.1/src/rsfc/main.py +13 -0
- rsfc-0.0.1/src/rsfc/model/__init__.py +0 -0
- rsfc-0.0.1/src/rsfc/model/assessedSoftware.py +117 -0
- rsfc-0.0.1/src/rsfc/model/check.py +28 -0
- rsfc-0.0.1/src/rsfc/rsfc_core.py +125 -0
- rsfc-0.0.1/src/rsfc/rsfc_tests/__init__.py +0 -0
- rsfc-0.0.1/src/rsfc/rsfc_tests/rsfc_tests.py +1175 -0
- rsfc-0.0.1/src/rsfc/templates/assessment_schema.json.j2 +35 -0
- rsfc-0.0.1/src/rsfc/utils/__init__.py +0 -0
- rsfc-0.0.1/src/rsfc/utils/constants.py +264 -0
- rsfc-0.0.1/src/rsfc/utils/rsfc_helpers.py +118 -0
rsfc-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Andrés Montero
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
rsfc-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: rsfc
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: EVERSE Research Software Fairness Checks
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Andres Montero
|
|
7
|
+
Author-email: andres.montero.martin@upm.es
|
|
8
|
+
Requires-Python: >=3.10,<=3.13
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Dist: anyascii (==0.3.2)
|
|
16
|
+
Requires-Dist: attrs (==25.3.0)
|
|
17
|
+
Requires-Dist: beautifulsoup4 (==4.13.4)
|
|
18
|
+
Requires-Dist: bibtexparser (==1.4.3)
|
|
19
|
+
Requires-Dist: bs4 (==0.0.1)
|
|
20
|
+
Requires-Dist: build (==1.2.2.post1)
|
|
21
|
+
Requires-Dist: certifi (==2025.6.15)
|
|
22
|
+
Requires-Dist: chardet (==5.2.0)
|
|
23
|
+
Requires-Dist: charset-normalizer (==3.4.2)
|
|
24
|
+
Requires-Dist: click (==8.2.1)
|
|
25
|
+
Requires-Dist: click-option-group (==0.5.7)
|
|
26
|
+
Requires-Dist: contourpy (==1.3.2)
|
|
27
|
+
Requires-Dist: contractions (==0.1.73)
|
|
28
|
+
Requires-Dist: cycler (==0.12.1)
|
|
29
|
+
Requires-Dist: duckdb (==1.3.1)
|
|
30
|
+
Requires-Dist: elementpath (==4.8.0)
|
|
31
|
+
Requires-Dist: falcon (==3.1.3)
|
|
32
|
+
Requires-Dist: fastjsonschema (==2.21.1)
|
|
33
|
+
Requires-Dist: fonttools (==4.58.4)
|
|
34
|
+
Requires-Dist: idna (==3.10)
|
|
35
|
+
Requires-Dist: imbalanced-learn (==0.11.0)
|
|
36
|
+
Requires-Dist: inflect (==7.5.0)
|
|
37
|
+
Requires-Dist: iniconfig (==2.1.0)
|
|
38
|
+
Requires-Dist: jinja2 (==3.1.6)
|
|
39
|
+
Requires-Dist: joblib (==1.5.1)
|
|
40
|
+
Requires-Dist: jsonpath-python (==1.0.6)
|
|
41
|
+
Requires-Dist: jsonschema (==4.24.0)
|
|
42
|
+
Requires-Dist: jsonschema-specifications (==2025.4.1)
|
|
43
|
+
Requires-Dist: jupyter-core (==5.8.1)
|
|
44
|
+
Requires-Dist: kiwisolver (==1.4.8)
|
|
45
|
+
Requires-Dist: lxml (==5.4.0)
|
|
46
|
+
Requires-Dist: markdown (==3.8.1)
|
|
47
|
+
Requires-Dist: markupsafe (==3.0.2)
|
|
48
|
+
Requires-Dist: matplotlib (==3.10.3)
|
|
49
|
+
Requires-Dist: more-itertools (==10.7.0)
|
|
50
|
+
Requires-Dist: morph-kgc (==2.8.1)
|
|
51
|
+
Requires-Dist: nbformat (==5.10.4)
|
|
52
|
+
Requires-Dist: nltk (==3.9.1)
|
|
53
|
+
Requires-Dist: numpy (==1.26.4)
|
|
54
|
+
Requires-Dist: packaging (==25.0)
|
|
55
|
+
Requires-Dist: pandas (==2.3.0)
|
|
56
|
+
Requires-Dist: pillow (==11.2.1)
|
|
57
|
+
Requires-Dist: platformdirs (==4.3.8)
|
|
58
|
+
Requires-Dist: pluggy (==1.6.0)
|
|
59
|
+
Requires-Dist: pyahocorasick (==2.2.0)
|
|
60
|
+
Requires-Dist: pyoxigraph (==0.3.22)
|
|
61
|
+
Requires-Dist: pyparsing (==3.2.3)
|
|
62
|
+
Requires-Dist: pyproject-hooks (==1.2.0)
|
|
63
|
+
Requires-Dist: pystache (>=0.6.8,<0.7.0)
|
|
64
|
+
Requires-Dist: pytest (==7.4.4)
|
|
65
|
+
Requires-Dist: python-dateutil (==2.9.0.post0)
|
|
66
|
+
Requires-Dist: pytz (==2025.2)
|
|
67
|
+
Requires-Dist: pyyaml (==6.0.2)
|
|
68
|
+
Requires-Dist: rdflib (==7.1.4)
|
|
69
|
+
Requires-Dist: rdflib-jsonld (==0.6.2)
|
|
70
|
+
Requires-Dist: referencing (==0.36.2)
|
|
71
|
+
Requires-Dist: regex (==2024.11.6)
|
|
72
|
+
Requires-Dist: requests (==2.32.4)
|
|
73
|
+
Requires-Dist: rpds-py (==0.25.1)
|
|
74
|
+
Requires-Dist: ruamel-yaml (==0.18.14)
|
|
75
|
+
Requires-Dist: ruamel-yaml-clib (==0.2.12)
|
|
76
|
+
Requires-Dist: scikit-learn (==1.3.2)
|
|
77
|
+
Requires-Dist: scipy (==1.15.3)
|
|
78
|
+
Requires-Dist: six (==1.17.0)
|
|
79
|
+
Requires-Dist: somef (==0.9.11)
|
|
80
|
+
Requires-Dist: soupsieve (==2.7)
|
|
81
|
+
Requires-Dist: textblob (==0.17.1)
|
|
82
|
+
Requires-Dist: textsearch (==0.0.24)
|
|
83
|
+
Requires-Dist: threadpoolctl (==3.6.0)
|
|
84
|
+
Requires-Dist: toml (==0.10.2)
|
|
85
|
+
Requires-Dist: tomli (==2.2.1)
|
|
86
|
+
Requires-Dist: tqdm (==4.67.1)
|
|
87
|
+
Requires-Dist: traitlets (==5.14.3)
|
|
88
|
+
Requires-Dist: typeguard (==4.4.4)
|
|
89
|
+
Requires-Dist: typing-extensions (==4.14.0)
|
|
90
|
+
Requires-Dist: tzdata (==2025.2)
|
|
91
|
+
Requires-Dist: urllib3 (==2.5.0)
|
|
92
|
+
Requires-Dist: validators (==0.22.0)
|
|
93
|
+
Requires-Dist: xgboost (==2.1.4)
|
|
94
|
+
Project-URL: Homepage, https://github.com/oeg-upm/rsfc
|
|
95
|
+
Description-Content-Type: text/markdown
|
|
96
|
+
|
|
97
|
+
# Research Software Fairness Checks (RSFC)
|
|
98
|
+
|
|
99
|
+
A command line interface to automatically evaluate the quality of a Github or Gitlab repository.
|
|
100
|
+
|
|
101
|
+
**Authors**: Daniel Garijo, Andrés Montero
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
## Features
|
|
105
|
+
|
|
106
|
+
Given a repository URL, RSFC will perform a series of checks based on a list of research software quality indicators (RSQI). The RSQIs currently covered by the package are:
|
|
107
|
+
|
|
108
|
+
- software_has_license
|
|
109
|
+
- software_has_citation
|
|
110
|
+
- has_releases
|
|
111
|
+
- repository_workflows
|
|
112
|
+
- version_control_use
|
|
113
|
+
- requirements_specified
|
|
114
|
+
- software_documentation
|
|
115
|
+
- persistent_and_unique_identifier
|
|
116
|
+
- descriptive_metadata
|
|
117
|
+
|
|
118
|
+
For more information about these RSQIs, you can check https://github.com/EVERSE-ResearchSoftware/indicators. We have plans to implement all of the RSQIs available in that repository.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## Requirements
|
|
122
|
+
|
|
123
|
+
Python 3.10.8 or higher
|
|
124
|
+
|
|
125
|
+
Dependencies are available in the requirements.txt or pyproject.toml file located in the root of the repository
|
|
126
|
+
|
|
127
|
+
## Install from Github with Poetry
|
|
128
|
+
|
|
129
|
+
To install the package, first clone the repository in your machine.
|
|
130
|
+
This project uses Poetry for dependency and environment management.
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
git clone https://github.com/oeg-upm/rsfc.git
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Go to the project's root directory
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
cd rsfc
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Install Poetry (if you haven’t already)
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
curl -sSL https://install.python-poetry.org | python3 -
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Make sure Poetry is available in your PATH
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
poetry --version
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Create the virtual environment and install dependencies
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
poetry install
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Activate the virtual environment (Optional)
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
source $(poetry env info --path)/bin/activate
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Your terminal prompt should now show something like:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
(rsfc-py3.11) your-user@your-machine rsfc %
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
With virtual environment activated you can tried like this:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
rsfc --help
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Without poetry virtual environment activated you need to use the poetry run:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
poetry run rsfc --help
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Usage
|
|
185
|
+
|
|
186
|
+
After installation, you can use the package by running if you activated the poetry env
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
rsfc <repo_url>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
or like this without the poetry env
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
poetry ruyn rsfc <repo_url>
|
|
196
|
+
```
|
|
197
|
+
|
rsfc-0.0.1/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Research Software Fairness Checks (RSFC)
|
|
2
|
+
|
|
3
|
+
A command line interface to automatically evaluate the quality of a Github or Gitlab repository.
|
|
4
|
+
|
|
5
|
+
**Authors**: Daniel Garijo, Andrés Montero
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
Given a repository URL, RSFC will perform a series of checks based on a list of research software quality indicators (RSQI). The RSQIs currently covered by the package are:
|
|
11
|
+
|
|
12
|
+
- software_has_license
|
|
13
|
+
- software_has_citation
|
|
14
|
+
- has_releases
|
|
15
|
+
- repository_workflows
|
|
16
|
+
- version_control_use
|
|
17
|
+
- requirements_specified
|
|
18
|
+
- software_documentation
|
|
19
|
+
- persistent_and_unique_identifier
|
|
20
|
+
- descriptive_metadata
|
|
21
|
+
|
|
22
|
+
For more information about these RSQIs, you can check https://github.com/EVERSE-ResearchSoftware/indicators. We have plans to implement all of the RSQIs available in that repository.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
Python 3.10.8 or higher
|
|
28
|
+
|
|
29
|
+
Dependencies are available in the requirements.txt or pyproject.toml file located in the root of the repository
|
|
30
|
+
|
|
31
|
+
## Install from Github with Poetry
|
|
32
|
+
|
|
33
|
+
To install the package, first clone the repository in your machine.
|
|
34
|
+
This project uses Poetry for dependency and environment management.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
git clone https://github.com/oeg-upm/rsfc.git
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Go to the project's root directory
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
cd rsfc
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Install Poetry (if you haven’t already)
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
curl -sSL https://install.python-poetry.org | python3 -
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Make sure Poetry is available in your PATH
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
poetry --version
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Create the virtual environment and install dependencies
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
poetry install
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Activate the virtual environment (Optional)
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
source $(poetry env info --path)/bin/activate
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Your terminal prompt should now show something like:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
(rsfc-py3.11) your-user@your-machine rsfc %
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
With virtual environment activated you can tried like this:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
rsfc --help
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Without poetry virtual environment activated you need to use the poetry run:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
poetry run rsfc --help
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
|
|
90
|
+
After installation, you can use the package by running if you activated the poetry env
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
rsfc <repo_url>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
or like this without the poetry env
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
poetry ruyn rsfc <repo_url>
|
|
100
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "rsfc"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "EVERSE Research Software Fairness Checks"
|
|
5
|
+
authors = ["Andres Montero <andres.montero.martin@upm.es>"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
packages = [{ include = "rsfc", from = "src" }]
|
|
9
|
+
homepage = "https://github.com/oeg-upm/rsfc"
|
|
10
|
+
|
|
11
|
+
[tool.poetry.dependencies]
|
|
12
|
+
python = ">=3.10,<=3.13"
|
|
13
|
+
somef = "0.9.11"
|
|
14
|
+
regex = "2024.11.6"
|
|
15
|
+
requests = "2.32.4"
|
|
16
|
+
anyascii = "0.3.2"
|
|
17
|
+
attrs = "25.3.0"
|
|
18
|
+
beautifulsoup4 = "4.13.4"
|
|
19
|
+
bibtexparser = "1.4.3"
|
|
20
|
+
bs4 = "0.0.1"
|
|
21
|
+
build = "1.2.2.post1"
|
|
22
|
+
certifi = "2025.6.15"
|
|
23
|
+
chardet = "5.2.0"
|
|
24
|
+
charset-normalizer = "3.4.2"
|
|
25
|
+
click = "8.2.1"
|
|
26
|
+
click-option-group = "0.5.7"
|
|
27
|
+
contourpy = "1.3.2"
|
|
28
|
+
contractions = "0.1.73"
|
|
29
|
+
cycler = "0.12.1"
|
|
30
|
+
duckdb = "1.3.1"
|
|
31
|
+
elementpath = "4.8.0"
|
|
32
|
+
falcon = "3.1.3"
|
|
33
|
+
fastjsonschema = "2.21.1"
|
|
34
|
+
fonttools = "4.58.4"
|
|
35
|
+
idna = "3.10"
|
|
36
|
+
imbalanced-learn = "0.11.0"
|
|
37
|
+
inflect = "7.5.0"
|
|
38
|
+
iniconfig = "2.1.0"
|
|
39
|
+
jinja2 = "3.1.6"
|
|
40
|
+
joblib = "1.5.1"
|
|
41
|
+
jsonpath-python = "1.0.6"
|
|
42
|
+
jsonschema = "4.24.0"
|
|
43
|
+
jsonschema-specifications = "2025.4.1"
|
|
44
|
+
jupyter-core = "5.8.1"
|
|
45
|
+
kiwisolver = "1.4.8"
|
|
46
|
+
lxml = "5.4.0"
|
|
47
|
+
markdown = "3.8.1"
|
|
48
|
+
markupsafe = "3.0.2"
|
|
49
|
+
matplotlib = "3.10.3"
|
|
50
|
+
more-itertools = "10.7.0"
|
|
51
|
+
morph-kgc = "2.8.1"
|
|
52
|
+
nbformat = "5.10.4"
|
|
53
|
+
nltk = "3.9.1"
|
|
54
|
+
numpy = "1.26.4"
|
|
55
|
+
packaging = "25.0"
|
|
56
|
+
pandas = "2.3.0"
|
|
57
|
+
pillow = "11.2.1"
|
|
58
|
+
platformdirs = "4.3.8"
|
|
59
|
+
pluggy = "1.6.0"
|
|
60
|
+
pyahocorasick = "2.2.0"
|
|
61
|
+
pyoxigraph = "0.3.22"
|
|
62
|
+
pyparsing = "3.2.3"
|
|
63
|
+
pyproject-hooks = "1.2.0"
|
|
64
|
+
pytest = "7.4.4"
|
|
65
|
+
python-dateutil = "2.9.0.post0"
|
|
66
|
+
pytz = "2025.2"
|
|
67
|
+
pyyaml = "6.0.2"
|
|
68
|
+
rdflib = "7.1.4"
|
|
69
|
+
rdflib-jsonld = "0.6.2"
|
|
70
|
+
referencing = "0.36.2"
|
|
71
|
+
rpds-py = "0.25.1"
|
|
72
|
+
ruamel-yaml = "0.18.14"
|
|
73
|
+
ruamel-yaml-clib = "0.2.12"
|
|
74
|
+
scikit-learn = "1.3.2"
|
|
75
|
+
scipy = "1.15.3"
|
|
76
|
+
six = "1.17.0"
|
|
77
|
+
soupsieve = "2.7"
|
|
78
|
+
textblob = "0.17.1"
|
|
79
|
+
textsearch = "0.0.24"
|
|
80
|
+
threadpoolctl = "3.6.0"
|
|
81
|
+
toml = "0.10.2"
|
|
82
|
+
tomli = "2.2.1"
|
|
83
|
+
tqdm = "4.67.1"
|
|
84
|
+
traitlets = "5.14.3"
|
|
85
|
+
typeguard = "4.4.4"
|
|
86
|
+
typing-extensions = "4.14.0"
|
|
87
|
+
tzdata = "2025.2"
|
|
88
|
+
urllib3 = "2.5.0"
|
|
89
|
+
validators = "0.22.0"
|
|
90
|
+
xgboost = "2.1.4"
|
|
91
|
+
pystache = "^0.6.8"
|
|
92
|
+
|
|
93
|
+
[tool.poetry.scripts]
|
|
94
|
+
rsfc = "rsfc.main:main"
|
|
95
|
+
|
|
96
|
+
[build-system]
|
|
97
|
+
requires = ["poetry-core"]
|
|
98
|
+
build-backend = "poetry.core.masonry.api"
|
|
99
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
def main():
|
|
4
|
+
parser = argparse.ArgumentParser(description="RSFC - EVERSE Research Software Fairness Checks")
|
|
5
|
+
parser.add_argument("repo_url", help="URL of the Github repository to be analyzed")
|
|
6
|
+
|
|
7
|
+
args = parser.parse_args()
|
|
8
|
+
|
|
9
|
+
from rsfc.rsfc_core import build_assessment
|
|
10
|
+
build_assessment(args.repo_url)
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import urllib
|
|
2
|
+
from urllib.parse import unquote
|
|
3
|
+
import requests
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
class AssessedSoftware:
|
|
7
|
+
def __init__(self, repo_url, repo_type):
|
|
8
|
+
self.software_url = repo_url
|
|
9
|
+
base_url = self.get_repo_base_url(repo_url, repo_type)
|
|
10
|
+
self.software_name = self.get_soft_name(unquote(base_url))
|
|
11
|
+
self.software_version = self.get_soft_version(base_url, repo_type)
|
|
12
|
+
self.software_id = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_repo_base_url(self, repo_url, repo_type):
|
|
16
|
+
parsed_url = urllib.parse.urlparse(repo_url)
|
|
17
|
+
path_parts = parsed_url.path.strip("/").split("/")
|
|
18
|
+
if len(path_parts) < 2:
|
|
19
|
+
raise ValueError("Error when getting repository API URL")
|
|
20
|
+
|
|
21
|
+
owner, repo = path_parts[-2], path_parts[-1]
|
|
22
|
+
|
|
23
|
+
if repo_type == 'GITHUB':
|
|
24
|
+
url = f"https://api.github.com/repos/{owner}/{repo}"
|
|
25
|
+
elif repo_type == "GITLAB":
|
|
26
|
+
project_path = urllib.parse.quote(f"{owner}/{repo}", safe="")
|
|
27
|
+
url = f"https://gitlab.com/api/v4/projects/{project_path}"
|
|
28
|
+
else:
|
|
29
|
+
raise ValueError("URL not within supported types (Github and Gitlab)")
|
|
30
|
+
|
|
31
|
+
return url
|
|
32
|
+
|
|
33
|
+
'''def get_base_url(self, repo_url, repo_type):
|
|
34
|
+
parsed_url = urllib.parse.urlparse(repo_url)
|
|
35
|
+
path_parts = parsed_url.path.strip("/").split("/")
|
|
36
|
+
if len(path_parts) < 2:
|
|
37
|
+
raise ValueError("Error when getting Github API URL")
|
|
38
|
+
owner, repo = path_parts[-2], path_parts[-1]
|
|
39
|
+
|
|
40
|
+
url = f"https://api.github.com/repos/{owner}/{repo}"
|
|
41
|
+
|
|
42
|
+
return url'''
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_soft_name(self, base_url):
|
|
46
|
+
name = base_url.rstrip("/").split("/")[-1]
|
|
47
|
+
return name
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_soft_version(self, url, repo_type):
|
|
51
|
+
try:
|
|
52
|
+
releases_url = f"{url}/releases"
|
|
53
|
+
|
|
54
|
+
response = requests.get(releases_url)
|
|
55
|
+
response.raise_for_status()
|
|
56
|
+
releases = response.json()
|
|
57
|
+
|
|
58
|
+
latest_release = None
|
|
59
|
+
latest_date = None
|
|
60
|
+
|
|
61
|
+
for release in releases:
|
|
62
|
+
if repo_type == "GITHUB":
|
|
63
|
+
date_str = release.get("published_at")
|
|
64
|
+
tag = release.get("tag_name")
|
|
65
|
+
elif repo_type == "GITLAB":
|
|
66
|
+
date_str = release.get("released_at")
|
|
67
|
+
tag = release.get("tag_name")
|
|
68
|
+
else:
|
|
69
|
+
raise ValueError("Unsupported repository type")
|
|
70
|
+
|
|
71
|
+
if date_str and tag:
|
|
72
|
+
try:
|
|
73
|
+
dt = datetime.fromisoformat(date_str.rstrip("Z"))
|
|
74
|
+
except ValueError:
|
|
75
|
+
continue
|
|
76
|
+
|
|
77
|
+
if latest_release is None or dt > latest_date:
|
|
78
|
+
latest_release = tag
|
|
79
|
+
latest_date = dt
|
|
80
|
+
|
|
81
|
+
return latest_release
|
|
82
|
+
|
|
83
|
+
except Exception as e:
|
|
84
|
+
print(f"Error fetching releases from {repo_type} at {releases_url}: {e}")
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
'''def get_soft_version(self, url):
|
|
90
|
+
try:
|
|
91
|
+
releases_url = f"{url}/releases"
|
|
92
|
+
response = requests.get(releases_url)
|
|
93
|
+
response.raise_for_status()
|
|
94
|
+
releases = response.json()
|
|
95
|
+
|
|
96
|
+
latest_release = None
|
|
97
|
+
latest_date = None
|
|
98
|
+
for release in releases:
|
|
99
|
+
date_str = release.get("published_at")
|
|
100
|
+
tag = release.get("tag_name")
|
|
101
|
+
if date_str and tag:
|
|
102
|
+
try:
|
|
103
|
+
dt = datetime.fromisoformat(date_str.rstrip("Z"))
|
|
104
|
+
except ValueError:
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
if latest_release is None or dt > latest_date:
|
|
108
|
+
latest_release = tag
|
|
109
|
+
latest_date = dt
|
|
110
|
+
|
|
111
|
+
return latest_release
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
print(f"Error fetching releases from GitHub: {e}")
|
|
115
|
+
return None'''
|
|
116
|
+
|
|
117
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from rsfc.utils import constants
|
|
2
|
+
|
|
3
|
+
class Check:
|
|
4
|
+
def __init__(self, indicator_id, process, output, evidence):
|
|
5
|
+
self.checkers_info = constants.CHECKERS_DICT
|
|
6
|
+
|
|
7
|
+
self.indicator_id = indicator_id
|
|
8
|
+
self.process = process
|
|
9
|
+
self.output = output
|
|
10
|
+
self.evidence = evidence
|
|
11
|
+
|
|
12
|
+
def convert(self):
|
|
13
|
+
return {
|
|
14
|
+
"@type": "CheckResult",
|
|
15
|
+
"assessesIndicator": {
|
|
16
|
+
"@id": self.indicator_id
|
|
17
|
+
},
|
|
18
|
+
"checkingSoftware": {
|
|
19
|
+
"@type": "schema:SoftwareApplication",
|
|
20
|
+
"name": self.checkers_info['rsfc']['name'],
|
|
21
|
+
"@id": self.checkers_info['rsfc']['id'],
|
|
22
|
+
"softwareVersion": self.checkers_info['rsfc']['version']
|
|
23
|
+
},
|
|
24
|
+
"process": self.process,
|
|
25
|
+
"status": { "@id": "schema:CompletedActionStatus" },
|
|
26
|
+
"output": self.output,
|
|
27
|
+
"evidence": self.evidence
|
|
28
|
+
}
|