def test_via_Repo_class( temp_repo, capsys, file_regression: FileRegressionFixture, data_regression: DataRegressionFixture, monkeypatch, example_config, ): with in_directory(temp_repo.path): (temp_repo.path / "repo_helper.yml").write_text(example_config) (temp_repo.path / "requirements.txt").touch() (temp_repo.path / "tests").maybe_make() (temp_repo.path / "tests" / "requirements.txt").touch() (temp_repo.path / "README.rst").touch() (temp_repo.path / "doc-source").mkdir() (temp_repo.path / "doc-source" / "index.rst").touch() (temp_repo.path / ".pre-commit-config.yaml").touch() rh = RepoHelper(temp_repo.path) rh.load_settings() managed_files = rh.run() data_regression.check(sorted(managed_files)) assert capsys.readouterr().out == '' assert capsys.readouterr().err == ''
def run_repo_helper( path, force: bool, initialise: bool, commit: Optional[bool], message: str, enable_pre_commit: bool = True, ) -> int: """ Run repo_helper. :param path: The repository path. :param force: Whether to force the operation if the repository is not clean. :param initialise: Whether to initialise the repository. :param commit: Whether to commit unchanged files. :param message: The commit message. :param enable_pre_commit: Whether to install and configure pre-commit. Default :py:obj`True`. """ # this package from repo_helper.cli.commands.init import init_repo from repo_helper.core import RepoHelper from repo_helper.utils import easter_egg try: rh = RepoHelper(path) rh.load_settings() except FileNotFoundError as e: error_block = textwrap.indent(str(e), '\t') raise abort( f"Unable to run 'repo_helper'.\nThe error was:\n{error_block}") if not assert_clean(rh.target_repo, allow_config=("repo_helper.yml", "git_helper.yml")): if force: click.echo(Fore.RED("Proceeding anyway"), err=True) else: return 1 if initialise: r = Repo(rh.target_repo) for filename in init_repo(rh.target_repo, rh.templates): r.stage(os.path.normpath(filename)) managed_files = rh.run() try: commit_changed_files( repo_path=rh.target_repo, managed_files=managed_files, commit=commit, message=message.encode("UTF-8"), enable_pre_commit=enable_pre_commit, ) except CommitError as e: indented_error = '\n'.join(f"\t{line}" for line in textwrap.wrap(str(e))) click.echo( f"Unable to commit changes. The error was:\n\n{indented_error}", err=True) return 1 easter_egg() return 0
def update_repository(repository: Dict, recreate: bool = False) -> int: """ Run the updater for the given repository. :param repository: :param recreate: """ # TODO: rebase # TODO: if branch already exists and PR has been merged, abort db_repository: Repository = get_db_repository( repo_id=repository["id"], owner=repository["owner"]["login"], name=repository["name"], ) last_pr_date = datetime.fromtimestamp(db_repository.last_pr or 200) now = datetime.now() if not recreate and last_pr_date.day == now.day and last_pr_date.month == now.month: print( f"A PR for {db_repository.fullname} has already been created today. Skipping." ) return 1 owner = repository["owner"]["login"] repository_name = repository["name"] # Log in as the app context_switcher.login_as_app() # Log in as installation installation_id = context_switcher.login_as_repo_installation( owner=owner, repository=repository_name) github_repo: GitHubRepository = client.repository(owner, repository_name) # Ensure 'repo_helper.yml' exists try: github_repo.file_contents("repo_helper.yml") except NotFoundError: print( f"repo_helper.yml not found in the repository {repository['owner']['login']}/{repository['name']}" ) return 1 with TemporaryDirectory() as tmpdir: # Clone to tmpdir repo = clone(repository["html_url"], tmpdir) if recreate: # Delete any existing branch and create again from master recreate_branch(repo) elif f"refs/remotes/origin/{BRANCH_NAME}".encode("UTF-8") in dict( repo.refs): checkout_branch(repo) else: # Switch to new branch create_branch(repo) # Update files try: rh = RepoHelper(tmpdir) rh.load_settings() except FileNotFoundError as e: error_block = indent(str(e), '\t') print( f"Unable to run 'repo_helper'.\nThe error was:\n{error_block}") managed_files = rh.run() staged_files = stage_changes(repo.path, managed_files) if not staged_files and recreate: # Everything is up to date, close PR. close_pr(owner, repository_name) return 0 try: if not commit_changed_files( repo_path=rh.target_repo, managed_files=managed_files, commit=True, message=b"Updated files with 'repo_helper'.", enable_pre_commit=False, ): sys.stdout.flush() sys.stderr.flush() print("Failure!") return 1 sys.stdout.flush() sys.stderr.flush() except CommitError as e: indented_error = '\n'.join(f"\t{line}" for line in wrap(str(e))) print( f"Unable to commit changes. The error was:\n\n{indented_error}" ) print("Failure!") return 1 # Push dulwich.porcelain.push( repo, repository["html_url"], BRANCH_NAME.encode("UTF-8"), username="******", password=get_installation_access_token(github_repo, installation_id), force=recreate, ) sys.stdout.flush() sys.stderr.flush() # Create PR base = github_repo.default_branch head = f"{owner}:{BRANCH_NAME}" if not list( github_repo.pull_requests(state="open", base=base, head=head)): created_pr = github_repo.create_pull( title="[repo-helper] Configuration Update", base=base, head=head, body=make_pr_details(), ) if created_pr is not None: db_repository.add_pr(int(created_pr.number)) db_repository.last_pr = datetime.now().timestamp() db.session.commit() print("Success!") return 0