generated from MetaMask/metamask-module-template
-
-
Notifications
You must be signed in to change notification settings - Fork 4
Auto categorize CLI flag #212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
933dd06
feat: categorize conventional commits
jake-perkins ebc0ace
feat: testing conv commit feat
jake-perkins a7b610b
fix: testing conv commit
jake-perkins 84002cf
testing
jake-perkins 91146dc
remove logs
jake-perkins 130f807
fix: format
jake-perkins f073675
update changelog
jake-perkins d03de77
newline
jake-perkins d60a767
formoat changelog
jake-perkins 2195646
format changelog
jake-perkins b8f20d8
readme
jake-perkins b50bcfb
reset changelog
jake-perkins c1dad45
Update src/cli.ts
jake-perkins de24e91
Update README.md
jake-perkins 65ef5a1
code review fixes
jake-perkins 04564c8
unit tests for new code
jake-perkins 02ed50d
lint
jake-perkins bc49099
testing pipeline unit test failures
jake-perkins 3ae6459
debug tests
jake-perkins ed7282e
debug for unit tests
jake-perkins cfecb8e
testing
jake-perkins 23eff89
updated tests
jake-perkins 61e961a
remove logging statements
jake-perkins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| import { strict as assert } from 'assert'; | ||
| import execa from 'execa'; | ||
|
|
||
| export type AddNewCommitsOptions = { | ||
| mostRecentTag: string | null; | ||
| repoUrl: string; | ||
| loggedPrNumbers: string[]; | ||
| projectRootDirectory?: string; | ||
| }; | ||
|
|
||
| /** | ||
| * Get all commit hashes included in the given commit range. | ||
| * | ||
| * @param commitRange - The commit range. | ||
| * @param rootDirectory - The project root directory. | ||
| * @returns A list of commit hashes for the given range. | ||
| */ | ||
| async function getCommitHashesInRange( | ||
| commitRange: string, | ||
| rootDirectory?: string, | ||
| ) { | ||
| const revListArgs = ['rev-list', commitRange]; | ||
| if (rootDirectory) { | ||
| revListArgs.push(rootDirectory); | ||
| } | ||
| return await runCommand('git', revListArgs); | ||
| } | ||
|
|
||
| /** | ||
| * Get commit details for each given commit hash. | ||
| * | ||
| * @param commitHashes - The list of commit hashes. | ||
| * @returns Commit details for each commit, including description and PR number (if present). | ||
| */ | ||
| async function getCommits(commitHashes: string[]) { | ||
| const commits: { prNumber?: string; description: string }[] = []; | ||
| for (const commitHash of commitHashes) { | ||
| const [subject] = await runCommand('git', [ | ||
| 'show', | ||
| '-s', | ||
| '--format=%s', | ||
| commitHash, | ||
| ]); | ||
| assert.ok( | ||
| Boolean(subject), | ||
| `"git show" returned empty subject for commit "${commitHash}".`, | ||
| ); | ||
|
|
||
| let matchResults = subject.match(/\(#(\d+)\)/u); | ||
| let prNumber: string | undefined; | ||
| let description = subject; | ||
|
|
||
| if (matchResults) { | ||
| // Squash & Merge: the commit subject is parsed as `<description> (#<PR ID>)` | ||
| prNumber = matchResults[1]; | ||
| description = subject.match(/^(.+)\s\(#\d+\)/u)?.[1] ?? ''; | ||
| } else { | ||
| // Merge: the PR ID is parsed from the git subject (which is of the form `Merge pull request | ||
| // #<PR ID> from <branch>`, and the description is assumed to be the first line of the body. | ||
| // If no body is found, the description is set to the commit subject | ||
| matchResults = subject.match(/#(\d+)\sfrom/u); | ||
| if (matchResults) { | ||
| prNumber = matchResults[1]; | ||
| const [firstLineOfBody] = await runCommand('git', [ | ||
| 'show', | ||
| '-s', | ||
| '--format=%b', | ||
| commitHash, | ||
| ]); | ||
| description = firstLineOfBody || subject; | ||
| } | ||
| } | ||
| // Otherwise: | ||
| // Normal commits: The commit subject is the description, and the PR ID is omitted. | ||
|
|
||
| commits.push({ prNumber, description }); | ||
| } | ||
| return commits; | ||
| } | ||
|
|
||
| /** | ||
| * Get the list of new change entries to add to a changelog. | ||
| * | ||
| * @param options - Options. | ||
| * @param options.mostRecentTag - The most recent tag. | ||
| * @param options.repoUrl - The GitHub repository URL for the current project. | ||
| * @param options.loggedPrNumbers - A list of all pull request numbers included in the relevant parsed changelog. | ||
| * @param options.projectRootDirectory - The root project directory, used to | ||
| * filter results from various git commands. This path is assumed to be either | ||
| * absolute, or relative to the current directory. Defaults to the root of the | ||
| * current git repository. | ||
| * @returns A list of new change entries to add to the changelog, based on commits made since the last release. | ||
| */ | ||
| export async function getNewChangeEntries({ | ||
| mostRecentTag, | ||
| repoUrl, | ||
| loggedPrNumbers, | ||
| projectRootDirectory, | ||
| }: AddNewCommitsOptions) { | ||
| const commitRange = | ||
| mostRecentTag === null ? 'HEAD' : `${mostRecentTag}..HEAD`; | ||
| const commitsHashesSinceLastRelease = await getCommitHashesInRange( | ||
| commitRange, | ||
| projectRootDirectory, | ||
| ); | ||
| const commits = await getCommits(commitsHashesSinceLastRelease); | ||
|
|
||
| const newCommits = commits.filter( | ||
| ({ prNumber }) => !prNumber || !loggedPrNumbers.includes(prNumber), | ||
| ); | ||
|
|
||
| return newCommits.map(({ prNumber, description }) => { | ||
| if (prNumber) { | ||
| const suffix = `([#${prNumber}](${repoUrl}/pull/${prNumber}))`; | ||
| return `${description} ${suffix}`; | ||
| } | ||
| return description; | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Executes a shell command in a child process and returns what it wrote to | ||
| * stdout, or rejects if the process exited with an error. | ||
| * | ||
| * @param command - The command to run, e.g. "git". | ||
| * @param args - The arguments to the command. | ||
| * @returns An array of the non-empty lines returned by the command. | ||
| */ | ||
| async function runCommand(command: string, args: string[]): Promise<string[]> { | ||
| return (await execa(command, [...args])).stdout | ||
| .trim() | ||
| .split('\n') | ||
| .filter((line) => line !== ''); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import * as ChangeLogUtils from './get-new-changes'; | ||
| import * as ChangeLogManager from './update-changelog'; | ||
|
|
||
| const emptyChangelog = `# Changelog | ||
| All notable changes to this project will be documented in this file. | ||
|
|
||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
|
||
| ## [Unreleased] | ||
|
|
||
| [Unreleased]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/ | ||
| `; | ||
|
|
||
| describe('updateChangelog', () => { | ||
| it('should contain conventional support mappings categorization when autoCategorize is true', async () => { | ||
| // Set up the spy and mock the implementation if needed | ||
| jest | ||
| .spyOn(ChangeLogUtils, 'getNewChangeEntries') | ||
| .mockResolvedValue([ | ||
| 'fix: Fixed a critical bug', | ||
| 'feat: Added new feature [PR#123](https://github.com/ExampleUsernameOrOrganization/ExampleRepository/pull/123)', | ||
| ]); | ||
|
|
||
| const result = await ChangeLogManager.updateChangelog({ | ||
| changelogContent: emptyChangelog, | ||
| currentVersion: '1.0.0', | ||
| repoUrl: | ||
| 'https://github.com/ExampleUsernameOrOrganization/ExampleRepository', | ||
| isReleaseCandidate: true, | ||
| autoCategorize: true, | ||
| }); | ||
|
|
||
| expect(result).toContain('### Fixed'); | ||
| expect(result).toContain('### Added'); | ||
| expect(result).not.toContain('### Uncategorized'); | ||
| }); | ||
|
|
||
| it('should not contain conventional support mappings categorization when autoCategorize is false', async () => { | ||
| // Set up the spy and mock the implementation if needed | ||
| jest | ||
| .spyOn(ChangeLogUtils, 'getNewChangeEntries') | ||
| .mockResolvedValue([ | ||
| 'fix: Fixed a critical bug', | ||
| 'feat: Added new feature [PR#123](https://github.com/ExampleUsernameOrOrganization/ExampleRepository/pull/123)', | ||
| ]); | ||
|
|
||
| const result = await ChangeLogManager.updateChangelog({ | ||
| changelogContent: emptyChangelog, | ||
| currentVersion: '1.0.0', | ||
| repoUrl: | ||
| 'https://github.com/ExampleUsernameOrOrganization/ExampleRepository', | ||
| isReleaseCandidate: true, | ||
| autoCategorize: false, | ||
| }); | ||
|
|
||
| expect(result).toContain('### Uncategorized'); | ||
| expect(result).not.toContain('### Fixed'); | ||
| expect(result).not.toContain('### Added'); | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.