def test_authors_file(self, mock_root_path): """Check if the property returns the authors file path""" mock_root_path.return_value = "/tmp/repo/" project = Project('/tmp/repo/') expected = "/tmp/repo/AUTHORS" self.assertEqual(project.authors_file, expected)
def test_news_file(self, mock_root_path): """Check if the property returns the news file path""" mock_root_path.return_value = "/tmp/repo/" project = Project('/tmp/repo/') expected = "/tmp/repo/NEWS" self.assertEqual(project.news_file, expected)
def test_unreleased_changes_path(self, mock_root_path): """Check if the property returns the path to the unreleased changes""" mock_root_path.return_value = "/tmp/repo/" project = Project('/tmp/repo/') expected = "/tmp/repo/releases/unreleased" self.assertEqual(project.unreleased_changes_path, expected)
def test_releases_path(self, mock_root_path): """Check if the property returns the releases path""" mock_root_path.return_value = "/tmp/repo/" project = Project('/tmp/repo/') expected = "/tmp/repo/releases" self.assertEqual(project.releases_path, expected)
def test_pyproject_file(self, mock_root_path, mock_find_file): """Check if the property returns the project toml file path""" mock_root_path.return_value = "/tmp/repo/" mock_find_file.return_value = "/tmp/repo/pyproject.toml" project = Project('/tmp/repo/') expected = "/tmp/repo/pyproject.toml" self.assertEqual(project.pyproject_file, expected) mock_find_file.assert_called_once_with('pyproject.toml')
def test_version_file(self, mock_root_path, mock_find_file): """Check if the property returns the version file path""" mock_root_path.return_value = "/tmp/repo/" mock_find_file.return_value = "/tmp/repo/_version.py" project = Project('/tmp/repo/') expected = "/tmp/repo/_version.py" self.assertEqual(project.version_file, expected) mock_find_file.assert_called_once_with('*_version.py')
def changelog(title, category, dry_run, overwrite, editor): """Interactive tool to create unreleased Changelog entries. This tool will help you to create valid Changelog entries for a Git repository. You will need to run this script inside that repository. It will guide you to create a new entry. At the end of the process, a text editor will open to let you review the entry and make the final changes. The editor will be the default defined in your system. You can skip some parts of the process providing information in advance such as the title ('-t') or the category ('-c') of the entry. New entries will be stored in "releases/unreleased" directory. This directory must be available under the Git root path. If you don't want to create a new entry and see only the final result, please active '--dry-run' flag. In the case an entry with the same title already exists, an error will be raised. Use '--overwrite' to force to replace the existing entry. You can also use this tool to create entries in a Git submodule. Just run the script under the submodule directory. """ click.echo() try: project = Project(os.getcwd()) except RepositoryError as e: raise click.ClickException(e) dirpath = check_changelog_entries_dir(project) content = create_changelog_entry_content(title, category, run_editor=editor) content = validate_changelog_entry(content) click.echo() if dry_run: click.echo(content) else: write_changelog_entry(dirpath, title, content, overwrite=overwrite)
def semverup(dry_run): """Increment version number following semver specification. This script will bump up the version number of a package in a Git repository using semantic versioning. You will need to run this script inside that repository. The version number must be stored in any directory, under the name of '_version.py'. It must also be tracked in the repository. New version will be written in the same file. To increase the number properly, the script will get the type of every unreleased change stored under 'releases/unreleased' directory. Additionally, 'pyproject' file will also be updated. Take into account this file must be tracked by the repository. WARNING: this script does not increases MAJOR version yet. If you don't want to create a new version and see only the final result, please active '--dry-run' flag. More info about semver specification can be found in the next link: https://semver.org/. """ try: project = Project(os.getcwd()) except RepositoryError as e: raise click.ClickException(e) # Get the current version number version_file = find_version_file(project) current_version = read_version_number(version_file) # Get the pyproject file pyproject_file = find_pyproject_file(project) # Determine the new version and produce the output new_version = determine_new_version_number(project, current_version) if not dry_run: write_version_number(version_file, new_version) write_version_number_pyproject(pyproject_file, new_version) click.echo(new_version)
def notes(name, version, dry_run, overwrite, news, authors): """Generate release notes. When you run this script, it will generate the release notes of the package tracked by the current Git repository. You will need to provide the 'NAME' of the package and the 'VERSION' of the new release. The script will generate a Markdown document under the 'releases' directory. Take into account the argument `NAME` is only used as the title of the document. If you also want to add the content of these release notes to the NEWS file, use the flag `--news`. If you want to add the contributor names of these release notes to the AUTHORS file, use the flag `--authors`. In the case a release notes file for the same version already exists, an error will be raised. Use '--overwrite' to force to replace the existing file. If you just want to see the final result of the notes but not generate a new file, please activate '--dry-run' flag. NAME: title of the package for the release notes. VERSION: version of the new release. """ try: project = Project(os.getcwd()) except RepositoryError as e: raise click.ClickException(e) entry_list = read_unreleased_changelog_entries(project) md = compose_release_notes(name, version, entry_list) if dry_run: click.echo(md) else: write_release_notes(project, version, md, overwrite=overwrite, news=news) if authors: au_content = compose_author_content(project, entry_list) write_authors_file(project, au_content)
def publish(version, author, remote, only_push): """Publish a new release. This script will generate a new release in the repository. This will consist on creating a commit and a tag with the new release notes and the updated version files. To run it, you will need to provide the version number and the author of the new release. By default the command does not push the commit release to a remote repository. To force it, use the parameter `--push` including the name of the remote where commits will be pushed. It is also possible to push only the commit release and its tag. To do so, set '--only-push' together with '--push' option. VERSION: version of the new release. AUTHOR: author of the new release (e.g. John Smith <*****@*****.**>) """ if only_push and not remote: msg = "'--only-push' flag must be set together with '--push'" raise click.ClickException(msg) try: project = Project(os.getcwd()) except RepositoryError as e: raise click.ClickException(e) try: if not only_push: remove_unreleased_changelog_entries(project) add_release_files(project, version) commit(project, version, author) if remote: push(project, remote, version) except RepositoryError as e: raise click.ClickException(e)