Skip to content
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

feat!: add option to customize types/scopes to exclude #103

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/commands/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
getGitDiff,
getCurrentGitStatus,
parseCommits,
filterParsedCommits,
bumpVersion,
generateMarkDown,
BumpVersionOptions,
Expand All @@ -24,6 +25,12 @@
from: args.from,
to: args.to,
output: args.output,
exclude:
typeof args.exclude === "string"
? args.exclude.split(",")
: args.exclude === 0 // eslint-disable-line unicorn/no-nested-ternary
? [""]
: undefined,

Check warning on line 33 in src/commands/default.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/default.ts#L28-L33

Added lines #L28 - L33 were not covered by tests
newVersion: typeof args.r === "string" ? args.r : undefined,
});

Expand All @@ -41,11 +48,7 @@
const rawCommits = await getGitDiff(config.from, config.to);

// Parse commits as conventional commits
const commits = parseCommits(rawCommits, config).filter(
(c) =>
config.types[c.type] &&
!(c.type === "chore" && c.scope === "deps" && !c.isBreaking)
);
const commits = filterParsedCommits(parseCommits(rawCommits, config), config);

Check warning on line 51 in src/commands/default.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/default.ts#L51

Added line #L51 was not covered by tests

// Shortcut for canary releases
if (args.canary) {
Expand Down
2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface ChangelogConfig {
from: string;
to: string;
newVersion?: string;
exclude?: string[];
signTags?: boolean;
output: string | boolean;
publish: {
Expand Down Expand Up @@ -53,6 +54,7 @@ const getDefaultConfig = () =>
cwd: null,
from: "",
to: "",
exclude: [""],
output: defaultOutput,
scopeMap: {},
tokens: {
Expand Down
29 changes: 26 additions & 3 deletions src/git.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ChangelogConfig } from "./config";
import type { ResolvedChangelogConfig } from "./config";
import { execCommand } from "./exec";

export interface GitCommitAuthor {
Expand Down Expand Up @@ -90,13 +90,36 @@

export function parseCommits(
commits: RawGitCommit[],
config: ChangelogConfig
config: ResolvedChangelogConfig
): GitCommit[] {
return commits
.map((commit) => parseGitCommit(commit, config))
.filter(Boolean);
}

export function filterParsedCommits(
commits: GitCommit[],
config: ResolvedChangelogConfig
): GitCommit[] {
// parsing the exclude parameter ('chore(deps)' => ['chore(deps)','chore','(deps)','deps'])
const excludes: RegExpMatchArray[] = config.exclude
? config.exclude.map((excludeString) =>
excludeString.match(/(\*|[a-z]+)(\((.+)\))?/)
)
: [];

Check warning on line 109 in src/git.ts

View check run for this annotation

Codecov / codecov/patch

src/git.ts#L109

Added line #L109 was not covered by tests
return commits.filter(
(c) =>
config.types[c.type] &&
!excludes.some(
(e) =>
e &&
(e[1] === "*" || c.type === e[1]) &&
(c.scope === e[3] || !e[3]) &&
!c.isBreaking
)
);
}

// https://www.conventionalcommits.org/en/v1.0.0/
// https://regex101.com/r/FSfNvA/1
const ConventionalCommitRegex =
Expand All @@ -107,7 +130,7 @@

export function parseGitCommit(
commit: RawGitCommit,
config: ChangelogConfig
config: ResolvedChangelogConfig
): GitCommit | null {
const match = commit.message.match(ConventionalCommitRegex);
if (!match) {
Expand Down
184 changes: 182 additions & 2 deletions test/git.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getGitDiff,
loadChangelogConfig,
parseCommits,
filterParsedCommits,
getRepoConfig,
formatReference,
} from "../src";
Expand Down Expand Up @@ -104,7 +105,7 @@ describe("git", () => {
]);
});

test("parse", async () => {
test("parse with default config", async () => {
const COMMIT_FROM = "1cb15d5dd93302ebd5ff912079ed584efcc6703b";
const COMMIT_TO = "3828bda8c45933396ddfa869d671473231ce3c95";

Expand Down Expand Up @@ -200,7 +201,7 @@ describe("git", () => {
from: COMMIT_FROM,
to: COMMIT_TO,
});
const parsed = parseCommits(commits, config);
const parsed = filterParsedCommits(parseCommits(commits, config), config);

expect(parsed.map(({ body: _, author: __, authors: ___, ...rest }) => rest))
.toMatchInlineSnapshot(`
Expand Down Expand Up @@ -400,6 +401,185 @@ describe("git", () => {
`);
});

test("parse with excluded types and scopes", async () => {
const COMMIT_FROM = "1cb15d5dd93302ebd5ff912079ed584efcc6703b";
const COMMIT_TO = "3828bda8c45933396ddfa869d671473231ce3c95";

const commits = await getGitDiff(COMMIT_FROM, COMMIT_TO);
commits[1].message =
"fix(scope)!: breaking change example, close #123 (#134)";

const config = await loadChangelogConfig(process.cwd(), {
from: COMMIT_FROM,
to: COMMIT_TO,
exclude: ["fix", "chore(deps)"],
});
const parsed = filterParsedCommits(parseCommits(commits, config), config);

expect(parsed.map(({ body: _, author: __, authors: ___, ...rest }) => rest))
.toMatchInlineSnapshot(`
[
{
"description": "v0.3.5",
"isBreaking": false,
"message": "chore(release): v0.3.5",
"references": [
{
"type": "hash",
"value": "3828bda",
},
],
"scope": "release",
"shortHash": "3828bda",
"type": "chore",
},
{
"description": "breaking change example, close #123",
"isBreaking": true,
"message": "fix(scope)!: breaking change example, close #123 (#134)",
"references": [
{
"type": "pull-request",
"value": "#134",
},
{
"type": "issue",
"value": "#123",
},
{
"type": "hash",
"value": "20e622e",
},
],
"scope": "scope",
"shortHash": "20e622e",
"type": "fix",
},
{
"description": "v0.3.4",
"isBreaking": false,
"message": "chore(release): v0.3.4",
"references": [
{
"type": "hash",
"value": "6fc5087",
},
],
"scope": "release",
"shortHash": "6fc5087",
"type": "chore",
},
{
"description": "infer github config from package.json",
"isBreaking": false,
"message": "feat: infer github config from package.json (resolves #37)",
"references": [
{
"type": "pull-request",
"value": "#37",
},
{
"type": "hash",
"value": "c0febf1",
},
],
"scope": "",
"shortHash": "c0febf1",
"type": "feat",
},
{
"description": "v0.3.3",
"isBreaking": false,
"message": "chore(release): v0.3.3",
"references": [
{
"type": "hash",
"value": "f4f42a3",
},
],
"scope": "release",
"shortHash": "f4f42a3",
"type": "chore",
},
{
"description": "expose \`determineSemverChange\` and \`bumpVersion\`",
"isBreaking": false,
"message": "feat: expose \`determineSemverChange\` and \`bumpVersion\`",
"references": [
{
"type": "hash",
"value": "5451f18",
},
],
"scope": "",
"shortHash": "5451f18",
"type": "feat",
},
{
"description": "fix typecheck",
"isBreaking": false,
"message": "chore: fix typecheck",
"references": [
{
"type": "hash",
"value": "8796cf1",
},
],
"scope": "",
"shortHash": "8796cf1",
"type": "chore",
},
{
"description": "update dependencies",
"isBreaking": false,
"message": "chore: update dependencies",
"references": [
{
"type": "hash",
"value": "c210976",
},
],
"scope": "",
"shortHash": "c210976",
"type": "chore",
},
]
`);

const md = await generateMarkDown(parsed, config);

expect(md).toMatchInlineSnapshot(`
"## 1cb15d5dd93302ebd5ff912079ed584efcc6703b...3828bda8c45933396ddfa869d671473231ce3c95

[compare changes](https://github.com/unjs/changelogen/compare/1cb15d5dd93302ebd5ff912079ed584efcc6703b...3828bda8c45933396ddfa869d671473231ce3c95)

### 🚀 Enhancements

- Expose \`determineSemverChange\` and \`bumpVersion\` ([5451f18](https://github.com/unjs/changelogen/commit/5451f18))
- Infer github config from package.json ([#37](https://github.com/unjs/changelogen/pull/37))

### 🩹 Fixes

- **scope:** ⚠️ Breaking change example, close #123 ([#134](https://github.com/unjs/changelogen/pull/134), [#123](https://github.com/unjs/changelogen/issues/123))

### 🏡 Chore

- Update dependencies ([c210976](https://github.com/unjs/changelogen/commit/c210976))
- Fix typecheck ([8796cf1](https://github.com/unjs/changelogen/commit/8796cf1))
- **release:** V0.3.3 ([f4f42a3](https://github.com/unjs/changelogen/commit/f4f42a3))
- **release:** V0.3.4 ([6fc5087](https://github.com/unjs/changelogen/commit/6fc5087))
- **release:** V0.3.5 ([3828bda](https://github.com/unjs/changelogen/commit/3828bda))

#### ⚠️ Breaking Changes

- **scope:** ⚠️ Breaking change example, close #123 ([#134](https://github.com/unjs/changelogen/pull/134), [#123](https://github.com/unjs/changelogen/issues/123))

### ❤️ Contributors

- Pooya Parsa ([@pi0](http://github.com/pi0))"
`);
});

test("parse host config", () => {
expect(getRepoConfig(undefined)).toMatchObject({});
expect(getRepoConfig("")).toMatchObject({});
Expand Down