diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index 42ac0ab..0000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Build and push image to Dockerhub - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -on: - release: - types: [trigger-workflow-dockerhub] - -jobs: - main: - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v2 - with: - ref: ${{ github.event.client_payload.sha }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - push: true - tags: radonconsortium/repo-scorer:latest - - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2258bdf..f99f2cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## [0.4.0] +- Added attributes to calculate as parameters of the main method. +- Updated test cases + ## [0.3.5] - Improved licensing and continuous_integration. - Added sequential workflow to upload on Dockerhub only after the upload to PyPI succeed" diff --git a/README.md b/README.md index 2f4370a..2de6c31 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,15 @@ from reposcorer.scorer import score_repository report = score_repository(path_to_repo='path/to/cloned/repo', full_name_or_id='repo_owner/repo_name', # e.g., radon-h2020/radon-repository-scorer - host='github') # or gitlab + host='github', # or gitlab + calculate_comments_ratio= True, + calculate_commit_frequency=True, + calculate_core_contributors=True, + calculate_has_ci=True, + calculate_has_license=True, + calculate_iac_ratio=True, + calculate_issue_frequency=True, + calculate_repository_size=True) ``` **Output** @@ -79,25 +87,4 @@ report = score_repository(path_to_repo='path/to/cloned/repo', ``` -## How to build the Docker image - -`docker build -t repo-scorer:latest .` - -## How to pull from Dockerhub - -`docker pull radonconsortium/repo-scorer:latest` - -## How to use Docker image - -`docker run -e GIT(HU|LA)B_ACCESS_TOKEN=$TOKEN repo-scorer:latest ` - -**Example** - -`docker run -e GITHUB_ACCESS_TOKEN=$GITHUB_ACCESS_TOKEN repo-scorer:latest github UoW-CPC/COLARepo /tmp/` - -*Output:* - -`{"has_ci": false, "percent_comment": 0.0389, "commit_frequency": 4.56, "core_contributors": 3, "iac_ratio": 0.96, "issue_frequency": 0.0, "has_license": false, "repository_size": 2224}` - - See [CHANGELOG](CHANGELOG.md) for logs detail about releases. diff --git a/reposcorer/scorer.py b/reposcorer/scorer.py index 514e4cf..a5e617a 100644 --- a/reposcorer/scorer.py +++ b/reposcorer/scorer.py @@ -14,47 +14,76 @@ def score_repository(host: str, full_name: Union[str, int], - clone_to: str): + clone_to: str, + calculate_comments_ratio: bool = False, + calculate_commit_frequency: bool = False, + calculate_core_contributors: bool = False, + calculate_has_ci: bool = False, + calculate_has_license: bool = False, + calculate_iac_ratio: bool = False, + calculate_issue_frequency: bool = False, + calculate_repository_size: bool = False): """ Score a repository to identify well-engineered projects. :param host: the SVM hosting platform. That is, github or gitlab :param full_name: the full name of a repository (e.g., radon-h2020/radon-repository-scorer) :param clone_to: directory to clone the repository + :param comments_ratio: if calculate this attribute + :param commit_frequency: if calculate this attribute + :param core_contributors: if calculate this attribute + :param has_ci: if calculate this attribute + :param has_license: if calculate this attribute + :param iac_ratio: if calculate this attribute + :param issue_frequency: if calculate this attribute + :param repository_size: if calculate this attribute :return: a dictionary with a score for every indicator """ - issues = 0 - if host == 'github': - issues = github_issue_event_frequency(full_name) + scores = {} + path_to_repo = os.path.join(clone_to, full_name.split('/')[-1]) - if not os.path.isdir(full_name): - git.Git(clone_to).clone(f'https://github.com/{full_name}.git') + if calculate_issue_frequency: - elif host == 'gitlab': - issues = gitlab_issue_event_frequency(full_name) - if not os.path.isdir(full_name): - git.Git(clone_to).clone(f'https://github.com/{full_name}.git') - else: - raise ValueError(f'{host} not supported. Please select github or gitlab') + issues = 0 + if host == 'github': + issues = github_issue_event_frequency(full_name) - path_to_repo = os.path.join(clone_to, full_name.split('/')[-1]) + if not os.path.isdir(full_name): + git.Git(clone_to).clone(f'https://github.com/{full_name}.git') + + elif host == 'gitlab': + issues = gitlab_issue_event_frequency(full_name) + if not os.path.isdir(full_name): + git.Git(clone_to).clone(f'https://github.com/{full_name}.git') + else: + raise ValueError(f'{host} not supported. Please select github or gitlab') + + scores.update({'issue_frequency': round(issues, 2)}) + + if calculate_commit_frequency: + scores.update({'commit_frequency': round(commit_frequency(path_to_repo), 2)}) + + if calculate_core_contributors: + scores.update({'core_contributors': core_contributors(path_to_repo)}) + + if calculate_has_ci: + scores.update({'has_ci': has_continuous_integration(path_to_repo)}) + + if calculate_has_license: + scores.update({'has_license': has_license(path_to_repo)}) + + if calculate_iac_ratio: + scores.update({'iac_ratio': round(iac_ratio(path_to_repo), 4)}) + + if calculate_comments_ratio or calculate_repository_size: + cloc, sloc = loc_info(path_to_repo) + ratio_comments = cloc / (cloc + sloc) if (cloc + sloc) != 0 else 0 + + if calculate_comments_ratio: + scores.update({'comments_ratio': round(ratio_comments, 4)}) + + if calculate_repository_size: + scores.update({'repository_size': sloc}) - history = commit_frequency(path_to_repo) - community = core_contributors(path_to_repo) - ci = has_continuous_integration(path_to_repo) - license_ = has_license(path_to_repo) - cloc, sloc = loc_info(path_to_repo) - ratio_comments = cloc / (cloc + sloc) if (cloc + sloc) != 0 else 0 - ratio_iac = iac_ratio(path_to_repo) - - return { - 'has_ci': ci, - 'comments_ratio': round(ratio_comments, 4), - 'commit_frequency': round(history, 2), - 'core_contributors': community, - 'iac_ratio': round(ratio_iac, 4), - 'issue_frequency': round(issues, 2), - 'has_license': license_, - 'repository_size': sloc - } + return scores diff --git a/setup.py b/setup.py index 6a1a1ac..60f4dbe 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='repository-scorer', - version="0.3.5", + version="0.4.0", description='A python package to compute a repository best engineering practices indicators', long_description=long_description, long_description_content_type="text/markdown", diff --git a/tests/attributes/test_attributes.py b/tests/attributes/test_attributes.py index 9d28ec0..b588f01 100644 --- a/tests/attributes/test_attributes.py +++ b/tests/attributes/test_attributes.py @@ -50,19 +50,21 @@ def test_iac_ratio(): @staticmethod def test_github_issue_event_frequency(): - issue_frequency = github_issue_event_frequency(full_name_or_id='ANXS/postgresql', - since=None, - until=datetime(year=2020, month=10, day=20)) + if os.getenv('GITHUB_ACCESS_TOKEN'): + issue_frequency = github_issue_event_frequency(full_name_or_id='ANXS/postgresql', + since=None, + until=datetime(year=2020, month=10, day=20)) - assert round(issue_frequency, 1) == 5.0 + assert round(issue_frequency, 1) == 4.3 @staticmethod def test_gitlab_issue_event_frequency(): - issue_frequency = gitlab_issue_event_frequency(full_name_or_id='commonshost/ansible', - since=None, - until=datetime(year=2020, month=10, day=20)) + if os.getenv('GITLAB_ACCESS_TOKEN'): + issue_frequency = gitlab_issue_event_frequency(full_name_or_id='commonshost/ansible', + since=None, + until=datetime(year=2020, month=10, day=20)) - assert round(issue_frequency, 1) == 2.1 + assert round(issue_frequency, 1) == 2.1 @staticmethod def test_has_license(): @@ -72,11 +74,11 @@ def test_has_license(): def test_loc_info(): cloc, sloc = loc_info(PATH_TO_REPO) assert cloc == 343 - assert sloc == 1345 + assert sloc == 1349 @staticmethod def test_comments_ratio(): - assert comments_ratio(PATH_TO_REPO) == 343 / (343 + 1345) + assert comments_ratio(PATH_TO_REPO) == 343 / (343 + 1349) if __name__ == '__main__': diff --git a/tests/test_scorer.py b/tests/test_scorer.py index 6d558ff..59d0a65 100644 --- a/tests/test_scorer.py +++ b/tests/test_scorer.py @@ -19,7 +19,19 @@ def tearDownClass(cls): shutil.rmtree(cls.tmp_dir) def test_score_repository(self): - scores = score_repository(host='github', full_name='UoW-CPC/COLARepo', clone_to=self.tmp_dir) + scores = score_repository( + host='github', + full_name='UoW-CPC/COLARepo', + clone_to=self.tmp_dir, + calculate_comments_ratio= True, + calculate_commit_frequency=True, + calculate_core_contributors = True, + calculate_has_ci=True, + calculate_has_license = True, + calculate_iac_ratio=True, + calculate_issue_frequency=True, + calculate_repository_size=True + ) self.assertAlmostEqual(scores['commit_frequency'], 4.5, 0) self.assertEqual(scores['issue_frequency'], 0)