From 7627916672c628e511647041a8ceedb0b85ec810 Mon Sep 17 00:00:00 2001 From: Zach Borboa Date: Sat, 1 Jul 2023 08:18:01 -0700 Subject: [PATCH 1/4] Add black code formatter pre-commit hook --- .pre-commit-config.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a4f9b19..10cb674 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,12 @@ # 2. Install hooks # $ pre-commit install repos: +- repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black + name: black + entry: black --skip-string-normalization - repo: local hooks: - id: composer-validate From 6c49609b9f54bdc8f54a872aaeefeb476a689874 Mon Sep 17 00:00:00 2001 From: Zach Borboa Date: Sat, 1 Jul 2023 08:18:42 -0700 Subject: [PATCH 2/4] Format python files --- scripts/make_release.py | 49 ++++++++++++++++++++++++++--------------- tests/generate_urls.py | 8 +++++-- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/scripts/make_release.py b/scripts/make_release.py index 28f38ad..771cd44 100644 --- a/scripts/make_release.py +++ b/scripts/make_release.py @@ -35,7 +35,9 @@ def main(): # git tag --list | sort --reverse --version-sort tags = sorted( local_repo.tags, - key=lambda tag: list(map(int, tag.name.split('.'))), reverse=True) + key=lambda tag: list(map(int, tag.name.split('.'))), + reverse=True, + ) most_recent_tag = tags[0] print('most_recent_tag: {}'.format(most_recent_tag)) @@ -82,9 +84,7 @@ def main(): # print(pull.html_url) continue - pull_labels = { - label.name for label in pull.labels - } + pull_labels = {label.name for label in pull.labels} if 'major-incompatible-changes' in pull_labels: group_name = 'major' elif 'minor-backwards-compatible-added-functionality' in pull_labels: @@ -120,9 +120,12 @@ def main(): if pulls_missing_semver_label: error_message = ( 'Merged pull request(s) found without semantic version label:\n' - '{}'.format('\n'.join( - ' {}'.format(pull.html_url) - for pull in pulls_missing_semver_label))) + '{}'.format( + '\n'.join( + ' {}'.format(pull.html_url) for pull in pulls_missing_semver_label + ) + ) + ) raise Exception(error_message) # pprint.pprint(pull_request_by_type) @@ -143,7 +146,9 @@ def main(): # Bump version and get next semantic version. command = ['php', php_file_path] print('running command: {}'.format(command)) - proc = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE) + proc = subprocess.Popen( + command, shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE + ) stdout, stderr = proc.communicate() print('stdout: {}'.format(stdout)) print('stderr: {}'.format(stderr)) @@ -160,10 +165,12 @@ def main(): release_title = '{} - {}'.format(release_version, release_date) print('release_title: {}'.format(release_title)) - release_content = ( - '## {}\n' - '\n' - '{}' + release_content = ''.join( + [ + '## {}\n', + '\n', + '{}', + ] ).format(release_title, '\n'.join(pull_request_changes)) old_content = CHANGELOG_PATH.read_text() @@ -191,17 +198,21 @@ def main(): message=result['message'], author='{} <{}>'.format( local_repo.git.config('--get', 'user.name'), - local_repo.git.config('--get', 'user.email'))) + local_repo.git.config('--get', 'user.email'), + ), + ) print('diff after commit:') # git log --max-count=1 --patch --color=always print(local_repo.git.log(max_count='1', patch=True, color='always')) # Push local changes. - server = 'https://{}@github.com/{}.git'.format( - GITHUB_TOKEN, GITHUB_REPOSITORY) - print('pushing changes to branch "{}" of repository "{}"'.format( - GITHUB_REF_NAME, GITHUB_REPOSITORY)) + server = 'https://{}@github.com/{}.git'.format(GITHUB_TOKEN, GITHUB_REPOSITORY) + print( + 'pushing changes to branch "{}" of repository "{}"'.format( + GITHUB_REF_NAME, GITHUB_REPOSITORY + ) + ) local_repo.git.push(server, GITHUB_REF_NAME) # Create tag and release. @@ -213,7 +224,9 @@ def main(): '\n' 'https://github.com/php-curl-class/php-curl-class/compare/{}...{}'.format( result['old_version'], - result['new_version'])) + result['new_version'], + ) + ) commit_sha = local_repo.head.commit.hexsha print('tag: {}'.format(tag)) print('tag_message: "{}"'.format(tag_message)) diff --git a/tests/generate_urls.py b/tests/generate_urls.py index ac4dc5d..8876b93 100644 --- a/tests/generate_urls.py +++ b/tests/generate_urls.py @@ -136,7 +136,11 @@ with open('urls.csv', 'wt') as f: first_url = first_domain + first_path + first_query + first_fragment if second_domain and not second_path.startswith('/'): second_path = '/' + second_path - second_url = second_domain + second_path + second_query + second_fragment + second_url = ( + second_domain + second_path + second_query + second_fragment + ) if first_url != second_url: - expected_url = remove_dot_segments(urljoin(first_url, second_url)) + expected_url = remove_dot_segments( + urljoin(first_url, second_url) + ) csvwriter.writerow([first_url, second_url, expected_url]) From efe4f6968388c78d573797ba3c98920361a9c6ee Mon Sep 17 00:00:00 2001 From: Zach Borboa Date: Sat, 1 Jul 2023 08:20:50 -0700 Subject: [PATCH 3/4] Normalize strings --- .pre-commit-config.yaml | 2 +- scripts/make_release.py | 162 ++++++++++++++++++++-------------------- tests/generate_urls.py | 124 +++++++++++++++--------------- 3 files changed, 144 insertions(+), 144 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 10cb674..f86a092 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: hooks: - id: black name: black - entry: black --skip-string-normalization + entry: black - repo: local hooks: - id: composer-validate diff --git a/scripts/make_release.py b/scripts/make_release.py index 771cd44..79b3041 100644 --- a/scripts/make_release.py +++ b/scripts/make_release.py @@ -11,15 +11,15 @@ from github import Github # The owner and repository name. For example, octocat/Hello-World. -GITHUB_REPOSITORY = os.getenv('GITHUB_REPOSITORY') +GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY") -GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') -GITHUB_REF_NAME = os.getenv('GITHUB_REF_NAME') +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") +GITHUB_REF_NAME = os.getenv("GITHUB_REF_NAME") CURRENT_FILE = Path(__file__) ROOT = CURRENT_FILE.parents[1] -CHANGELOG_PATH = ROOT / 'CHANGELOG.md' -LIBRARY_FILE_PATH = ROOT / 'src/Curl/Curl.php' +CHANGELOG_PATH = ROOT / "CHANGELOG.md" +LIBRARY_FILE_PATH = ROOT / "src/Curl/Curl.php" # TODO: Adjust number of recent pull requests to include likely number of # pull requests since the last release. @@ -35,32 +35,32 @@ def main(): # git tag --list | sort --reverse --version-sort tags = sorted( local_repo.tags, - key=lambda tag: list(map(int, tag.name.split('.'))), + key=lambda tag: list(map(int, tag.name.split("."))), reverse=True, ) most_recent_tag = tags[0] - print('most_recent_tag: {}'.format(most_recent_tag)) + print("most_recent_tag: {}".format(most_recent_tag)) most_recent_tag_datetime = most_recent_tag.commit.committed_datetime - print('most_recent_tag_datetime: {}'.format(most_recent_tag_datetime)) + print("most_recent_tag_datetime: {}".format(most_recent_tag_datetime)) # Find merged pull requests since the most recent tag. github_repo = Github(login_or_token=GITHUB_TOKEN).get_repo(GITHUB_REPOSITORY) recent_pulls = github_repo.get_pulls( - state='closed', - sort='updated', - direction='desc', + state="closed", + sort="updated", + direction="desc", )[:RECENT_PULL_REQUEST_LIMIT] pull_request_changes = [] # Group pull requests by semantic version change type. pull_request_by_type = { - 'major': [], - 'minor': [], - 'patch': [], - 'cleanup': [], - 'unspecified': [], + "major": [], + "minor": [], + "patch": [], + "cleanup": [], + "unspecified": [], } # Track if any pull request is missing a semantic version change type. @@ -85,16 +85,16 @@ def main(): continue pull_labels = {label.name for label in pull.labels} - if 'major-incompatible-changes' in pull_labels: - group_name = 'major' - elif 'minor-backwards-compatible-added-functionality' in pull_labels: - group_name = 'minor' - elif 'patch-backwards-compatible-bug-fixes' in pull_labels: - group_name = 'patch' - elif 'cleanup-no-release-required' in pull_labels: - group_name = 'cleanup' + if "major-incompatible-changes" in pull_labels: + group_name = "major" + elif "minor-backwards-compatible-added-functionality" in pull_labels: + group_name = "minor" + elif "patch-backwards-compatible-bug-fixes" in pull_labels: + group_name = "patch" + elif "cleanup-no-release-required" in pull_labels: + group_name = "cleanup" else: - group_name = 'unspecified' + group_name = "unspecified" pulls_missing_semver_label.append(pull) pull_request_by_type[group_name].append(pull) @@ -103,9 +103,9 @@ def main(): # pprint.pprint('merged at: {}'.format(pull.merged_at)) # print(pull.html_url) - if group_name in ['major', 'minor', 'patch']: + if group_name in ["major", "minor", "patch"]: pull_request_changes.append( - '- {} ([#{}]({}))'.format(pull.title, pull.number, pull.html_url) + "- {} ([#{}]({}))".format(pull.title, pull.number, pull.html_url) ) # print('-' * 10) @@ -113,70 +113,70 @@ def main(): # pprint.pprint(pull_request_changes) if not pull_request_changes: - print('No merged pull requests since the most recent tag release were found') + print("No merged pull requests since the most recent tag release were found") return # Raise error if any pull request is missing a semantic version change type. if pulls_missing_semver_label: error_message = ( - 'Merged pull request(s) found without semantic version label:\n' - '{}'.format( - '\n'.join( - ' {}'.format(pull.html_url) for pull in pulls_missing_semver_label + "Merged pull request(s) found without semantic version label:\n" + "{}".format( + "\n".join( + " {}".format(pull.html_url) for pull in pulls_missing_semver_label ) ) ) raise Exception(error_message) # pprint.pprint(pull_request_by_type) - if pull_request_by_type.get('major'): - highest_semantic_version = 'major' - php_file_path = 'scripts/bump_major_version.php' - elif pull_request_by_type.get('minor'): - highest_semantic_version = 'minor' - php_file_path = 'scripts/bump_minor_version.php' - elif pull_request_by_type.get('patch'): - highest_semantic_version = 'patch' - php_file_path = 'scripts/bump_patch_version.php' + if pull_request_by_type.get("major"): + highest_semantic_version = "major" + php_file_path = "scripts/bump_major_version.php" + elif pull_request_by_type.get("minor"): + highest_semantic_version = "minor" + php_file_path = "scripts/bump_minor_version.php" + elif pull_request_by_type.get("patch"): + highest_semantic_version = "patch" + php_file_path = "scripts/bump_patch_version.php" else: highest_semantic_version = None - php_file_path = '' - print('highest_semantic_version: {}'.format(highest_semantic_version)) + php_file_path = "" + print("highest_semantic_version: {}".format(highest_semantic_version)) # Bump version and get next semantic version. - command = ['php', php_file_path] - print('running command: {}'.format(command)) + command = ["php", php_file_path] + print("running command: {}".format(command)) proc = subprocess.Popen( command, shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE ) stdout, stderr = proc.communicate() - print('stdout: {}'.format(stdout)) - print('stderr: {}'.format(stderr)) + print("stdout: {}".format(stdout)) + print("stderr: {}".format(stderr)) result = json.loads(stdout) pprint.pprint(result) - release_version = result['new_version'] + release_version = result["new_version"] today = datetime.today() - print('today: {} (tzinfo={})'.format(today, today.tzinfo)) + print("today: {} (tzinfo={})".format(today, today.tzinfo)) today = today.replace(tzinfo=timezone.utc) - print('today: {} (tzinfo={})'.format(today, today.tzinfo)) - release_date = today.strftime('%Y-%m-%d') - print('release_date: {}'.format(release_date)) - release_title = '{} - {}'.format(release_version, release_date) - print('release_title: {}'.format(release_title)) + print("today: {} (tzinfo={})".format(today, today.tzinfo)) + release_date = today.strftime("%Y-%m-%d") + print("release_date: {}".format(release_date)) + release_title = "{} - {}".format(release_version, release_date) + print("release_title: {}".format(release_title)) - release_content = ''.join( + release_content = "".join( [ - '## {}\n', - '\n', - '{}', + "## {}\n", + "\n", + "{}", ] - ).format(release_title, '\n'.join(pull_request_changes)) + ).format(release_title, "\n".join(pull_request_changes)) old_content = CHANGELOG_PATH.read_text() new_content = old_content.replace( - '', - '\n\n{}'.format(release_content), + "", + "\n\n{}".format(release_content), ) # print(new_content[:800]) CHANGELOG_PATH.write_text(new_content) @@ -195,19 +195,19 @@ def main(): # print(local_repo.git.diff(cached=True, color='always')) local_repo.git.commit( - message=result['message'], - author='{} <{}>'.format( - local_repo.git.config('--get', 'user.name'), - local_repo.git.config('--get', 'user.email'), + message=result["message"], + author="{} <{}>".format( + local_repo.git.config("--get", "user.name"), + local_repo.git.config("--get", "user.email"), ), ) - print('diff after commit:') + print("diff after commit:") # git log --max-count=1 --patch --color=always - print(local_repo.git.log(max_count='1', patch=True, color='always')) + print(local_repo.git.log(max_count="1", patch=True, color="always")) # Push local changes. - server = 'https://{}@github.com/{}.git'.format(GITHUB_TOKEN, GITHUB_REPOSITORY) + server = "https://{}@github.com/{}.git".format(GITHUB_TOKEN, GITHUB_REPOSITORY) print( 'pushing changes to branch "{}" of repository "{}"'.format( GITHUB_REF_NAME, GITHUB_REPOSITORY @@ -216,23 +216,23 @@ def main(): local_repo.git.push(server, GITHUB_REF_NAME) # Create tag and release. - tag = result['new_version'] - tag_message = result['message'] - release_name = 'Release {}'.format(release_version) + tag = result["new_version"] + tag_message = result["message"] + release_name = "Release {}".format(release_version) release_message = ( - 'See [change log](https://github.com/php-curl-class/php-curl-class/blob/master/CHANGELOG.md) for changes.\n' - '\n' - 'https://github.com/php-curl-class/php-curl-class/compare/{}...{}'.format( - result['old_version'], - result['new_version'], + "See [change log](https://github.com/php-curl-class/php-curl-class/blob/master/CHANGELOG.md) for changes.\n" + "\n" + "https://github.com/php-curl-class/php-curl-class/compare/{}...{}".format( + result["old_version"], + result["new_version"], ) ) commit_sha = local_repo.head.commit.hexsha - print('tag: {}'.format(tag)) + print("tag: {}".format(tag)) print('tag_message: "{}"'.format(tag_message)) print('release_name: "{}"'.format(release_name)) print('release_message: "{}"'.format(release_message)) - print('commit_sha: {}'.format(commit_sha)) + print("commit_sha: {}".format(commit_sha)) github_repo.create_git_tag_and_release( tag=tag, @@ -240,11 +240,11 @@ def main(): release_name=release_name, release_message=release_message, object=commit_sha, - type='commit', + type="commit", draft=False, ) - print('created tag and release') + print("created tag and release") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/tests/generate_urls.py b/tests/generate_urls.py index 8876b93..0c5dcab 100644 --- a/tests/generate_urls.py +++ b/tests/generate_urls.py @@ -24,118 +24,118 @@ def remove_dot_segments(url): parsed = urlparse(url) new_path = posixpath.normpath(parsed.path) - if parsed.path.endswith('/'): + if parsed.path.endswith("/"): # Fix missing trailing slash. # https://bugs.python.org/issue1707768 - new_path += '/' - if new_path.startswith('//'): + new_path += "/" + if new_path.startswith("//"): new_path = new_path[1:] cleaned = parsed._replace(path=new_path) return cleaned.geturl() first_authorities = [ - 'http://example.com@user:pass:7152', - 'https://example.com', + "http://example.com@user:pass:7152", + "https://example.com", ] second_authorities = [ - '', - 'https://www.example.org', - 'http://example.com@user:pass:1111', - 'file://example.com', - 'file://', + "", + "https://www.example.org", + "http://example.com@user:pass:1111", + "file://example.com", + "file://", ] first_paths = [ - '', - '/', - '/foobar/bazz', - 'foobar/bazz/', + "", + "/", + "/foobar/bazz", + "foobar/bazz/", ] second_paths = [ - '', - '/', - '/foo/bar', - 'foo/bar/', - './foo/../bar', - 'foo/./.././bar', + "", + "/", + "/foo/bar", + "foo/bar/", + "./foo/../bar", + "foo/./.././bar", ] -first_queries = ['', '?a=1', '?a=647&b=s564'] -second_queries = ['', '?a=sdf', '?a=cvb&b=987'] -fragments = ['', '#foo', '#bar'] +first_queries = ["", "?a=1", "?a=647&b=s564"] +second_queries = ["", "?a=sdf", "?a=cvb&b=987"] +fragments = ["", "#foo", "#bar"] additional_tests = [ { - 'args': [ - 'http://www.example.com/', - '', + "args": [ + "http://www.example.com/", + "", ], - 'expected': 'http://www.example.com/', + "expected": "http://www.example.com/", }, { - 'args': [ - 'http://www.example.com/', - 'foo', + "args": [ + "http://www.example.com/", + "foo", ], - 'expected': 'http://www.example.com/foo', + "expected": "http://www.example.com/foo", }, { - 'args': [ - 'http://www.example.com/', - '/foo', + "args": [ + "http://www.example.com/", + "/foo", ], - 'expected': 'http://www.example.com/foo', + "expected": "http://www.example.com/foo", }, { - 'args': [ - 'http://www.example.com/', - '/foo/', + "args": [ + "http://www.example.com/", + "/foo/", ], - 'expected': 'http://www.example.com/foo/', + "expected": "http://www.example.com/foo/", }, { - 'args': [ - 'http://www.example.com/', - '/dir/page.html', + "args": [ + "http://www.example.com/", + "/dir/page.html", ], - 'expected': 'http://www.example.com/dir/page.html', + "expected": "http://www.example.com/dir/page.html", }, { - 'args': [ - 'http://www.example.com/dir1/page2.html', - '/dir/page.html', + "args": [ + "http://www.example.com/dir1/page2.html", + "/dir/page.html", ], - 'expected': 'http://www.example.com/dir/page.html', + "expected": "http://www.example.com/dir/page.html", }, { - 'args': [ - 'http://www.example.com/dir1/page2.html', - 'dir/page.html', + "args": [ + "http://www.example.com/dir1/page2.html", + "dir/page.html", ], - 'expected': 'http://www.example.com/dir1/dir/page.html', + "expected": "http://www.example.com/dir1/dir/page.html", }, { - 'args': [ - 'http://www.example.com/dir1/dir3/page.html', - '../dir/page.html', + "args": [ + "http://www.example.com/dir1/dir3/page.html", + "../dir/page.html", ], - 'expected': 'http://www.example.com/dir1/dir/page.html', + "expected": "http://www.example.com/dir1/dir/page.html", }, ] -with open('urls.csv', 'wt') as f: +with open("urls.csv", "wt") as f: csvwriter = csv.writer(f, quotechar='"', quoting=csv.QUOTE_ALL) - csvwriter.writerow(['first_url', 'second_url', 'expected']) + csvwriter.writerow(["first_url", "second_url", "expected"]) for test in additional_tests: - csvwriter.writerow([test['args'][0], test['args'][1], test['expected']]) + csvwriter.writerow([test["args"][0], test["args"][1], test["expected"]]) for first_domain, second_domain in product(first_authorities, second_authorities): for first_path, second_path in product(first_paths, second_paths): for first_query, second_query in product(first_queries, second_queries): for first_fragment, second_fragment in product(fragments, fragments): - if not first_path.startswith('/'): - first_path = '/' + first_path + if not first_path.startswith("/"): + first_path = "/" + first_path first_url = first_domain + first_path + first_query + first_fragment - if second_domain and not second_path.startswith('/'): - second_path = '/' + second_path + if second_domain and not second_path.startswith("/"): + second_path = "/" + second_path second_url = ( second_domain + second_path + second_query + second_fragment ) From 75673eed4378aa9d50f342c4c12c6e989300f5aa Mon Sep 17 00:00:00 2001 From: Zach Borboa Date: Sat, 1 Jul 2023 10:10:38 -0700 Subject: [PATCH 4/4] Add black code formatter to continuous integration --- .github/workflows/black.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/black.yml diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml new file mode 100644 index 0000000..11d0bd2 --- /dev/null +++ b/.github/workflows/black.yml @@ -0,0 +1,23 @@ +name: Black code formatter + +on: + pull_request: + +jobs: + black: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install black + run: pip install black + + - name: Get changed python files + id: changed-files + uses: tj-actions/changed-files@v37 + with: + files: "**/*.py" + + - name: Check changed files + if: steps.changed-files.outputs.any_changed == 'true' + run: black --check --color --diff --quiet ${{ steps.changed-files.outputs.all_changed_files }}