diff --git a/howfairis/cli/cli.py b/howfairis/cli/cli.py index 474fc35..759f80f 100644 --- a/howfairis/cli/cli.py +++ b/howfairis/cli/cli.py @@ -4,6 +4,7 @@ from howfairis.__version__ import __version__ from howfairis.checker import DEFAULT_CONFIG_FILENAME from howfairis.checker import Checker +from howfairis.cli.print_call_to_action import automate_call_to_action from howfairis.cli.print_call_to_action import print_call_to_action from howfairis.cli.print_default_config import print_default_config from howfairis.cli.print_feedback_about_config_args import print_feedback_about_config_args @@ -12,8 +13,10 @@ from howfairis.repo import Repo -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-locals @click.command(context_settings=dict(help_option_names=["-h", "--help"])) +@click.option("-a", "--auto", default=False, is_flag=True, + help="Automatically update fair-software.eu badge in local README.") @click.option("-b", "--branch", default=None, type=click.STRING, help="Which git branch to use. Also accepts other git references like SHA or tag.") @click.option("-u", "--user-config-filename", default=None, type=click.Path(), @@ -37,7 +40,7 @@ @click.option("-v", "--version", default=False, is_flag=True, help="Show version and exit.") @click.argument("url", required=False) -def cli(url=None, branch=None, user_config_filename=None, repo_config_filename=None, path=None, +def cli(url=None, auto=False, branch=None, user_config_filename=None, repo_config_filename=None, path=None, show_trace=False, version=False, ignore_repo_config=False, show_default_config=False, quiet=False): """Determine compliance with recommendations from fair-software.eu for the repository at URL. The following @@ -70,7 +73,10 @@ def cli(url=None, branch=None, user_config_filename=None, repo_config_filename=N previous_compliance = checker.readme.get_compliance() current_compliance = checker.check_five_recommendations() - sys.exit(print_call_to_action(previous_compliance, current_compliance, checker, is_quiet=quiet)) + if not auto: + sys.exit(print_call_to_action(previous_compliance, current_compliance, checker, is_quiet=quiet)) + else: + sys.exit(automate_call_to_action(previous_compliance, current_compliance, checker, is_quiet=quiet)) if __name__ == "__main__": diff --git a/howfairis/cli/print_call_to_action.py b/howfairis/cli/print_call_to_action.py index 792ed0c..fa0a4cd 100644 --- a/howfairis/cli/print_call_to_action.py +++ b/howfairis/cli/print_call_to_action.py @@ -37,3 +37,38 @@ def print_call_to_action(previous_compliance, current_compliance, checker, is_qu github_caching_check(checker) return sys_exit_code + + +def automate_call_to_action(previous_compliance, current_compliance, checker, is_quiet=False): + """ Function to automate the process of updating the fair-software.eu badge """ + if checker.readme.text is None: + return 1 + + if previous_compliance is None: + badge = current_compliance.calc_badge(checker.readme.file_format) + message = "It seems you have not yet added the fair-software.eu badge to " + \ + f"your {checker.readme.filename}. You can do so by pasting the following snippet:\n\n{badge}" + sys_exit_code = 1 + + elif current_compliance == previous_compliance: + message = "Expected badge is equal to the actual badge. It's all good.\n" + sys_exit_code = 0 + + else: + message = "Repository has a fair-software.eu badge, but current compliance does not match the badge\n" + \ + f"Updating badge image URL in {checker.readme.filename}." + with open(checker.readme.filename, "r", encoding="utf8") as readme: + readme_contents = readme.read() + readme_contents = readme_contents.replace(previous_compliance.badge_image_url(), + current_compliance.badge_image_url()) + with open(checker.readme.filename, "w", encoding="utf8") as readme: + readme.write(readme_contents) + sys_exit_code = 0 + + if not is_quiet: + print("\nCalculated compliance: " + " ".join(current_compliance.as_unicode()) + "\n") + print(message) + if checker.repo.platform == Platform.GITHUB: + github_caching_check(checker) + + return sys_exit_code diff --git a/tests/test_cli.py b/tests/test_cli.py index 16c188a..e9a6e78 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,7 +1,9 @@ +import os from click.testing import CliRunner from requests_mock import Mocker +from howfairis import Compliance from howfairis.cli.cli import cli - +from howfairis.cli.print_call_to_action import automate_call_to_action def test_matching_badge(requests_mock: Mocker): owner = "fair-software" @@ -96,3 +98,43 @@ def test_missing_badge(requests_mock: Mocker): runner = CliRunner() response = runner.invoke(cli, [url]) assert response.exit_code == 1 + + +def test_automate_call_to_action(): + + test_filename = "test-automate-call-to-action--readme.md" + + # Mock the Checker + class Repo: + platform = "test" + class Readme: + filename = test_filename + text = 1 + class Checker: + readme = Readme + repo = Repo + + previous_compliance = Compliance(False, False, False, False, False) + current_compliance = Compliance(False, False, False, False, True) + + try: + test_README_string = previous_compliance.badge_image_url() + with open(test_filename, "w") as test_file: + test_file.write(test_README_string) + + automate_call_to_action(previous_compliance, current_compliance, Checker) + + with open(test_filename, "r") as test_file: + result = test_file.read() + assert result == current_compliance.badge_image_url() + + finally: + # cleanup the temporary file test_filename + try: + os.remove(test_filename) + except OSError as e: + # if the file does not exist, ignore the exception + if e.errno != errno.ENOENT: + raise e + +