Skip to content

Commit c2032df

Browse files
committed
chore: wip
1 parent b834650 commit c2032df

File tree

12 files changed

+695
-56
lines changed

12 files changed

+695
-56
lines changed

.github/workflows/release.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ jobs:
4343
uses: softprops/action-gh-release@v2
4444
with:
4545
files: |
46-
bin/bin-name-linux-x64
47-
bin/bin-name-linux-arm64
48-
bin/bin-name-windows-x64.exe
49-
bin/bin-name-darwin-x64
50-
bin/bin-name-darwin-arm64
46+
bin/gitlint-linux-x64
47+
bin/gitlint-linux-arm64
48+
bin/gitlint-windows-x64.exe
49+
bin/gitlint-darwin-x64
50+
bin/gitlint-darwin-arm64
5151
env:
5252
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ logs
1010
node_modules
1111
temp
1212
docs/.vitepress/cache
13+
bin/gitlint
14+
bin/gitlint*

README.md

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,123 @@
88

99
# bun-ts-starter
1010

11-
This is an opinionated TypeScript Starter kit to help kick-start development of your next Bun package.
11+
> Efficient Git Commit Message Linting and Formatting
1212
13-
## Features
13+
GitLint is a tool for enforcing consistent Git commit message conventions. It analyzes commit messages to ensure they follow the [Conventional Commits](https://www.conventionalcommits.org/) specification and other configurable rules.
1414

15-
This Starter Kit comes pre-configured with the following:
15+
## Installation
1616

17-
- 🛠️ [Powerful Build Process](https://github.com/oven-sh/bun) - via Bun
18-
- 💪🏽 [Fully Typed APIs](https://www.typescriptlang.org/) - via TypeScript
19-
- 📚 [Documentation-ready](https://vitepress.dev/) - via VitePress
20-
-[CLI & Binary](https://www.npmjs.com/package/bunx) - via Bun & CAC
21-
- 🧪 [Built With Testing In Mind](https://bun.sh/docs/cli/test) - pre-configured unit-testing powered by [Bun](https://bun.sh/docs/cli/test)
22-
- 🤖 [Renovate](https://renovatebot.com/) - optimized & automated PR dependency updates
23-
- 🎨 [ESLint](https://eslint.org/) - for code linting _(and formatting)_
24-
- 📦️ [pkg.pr.new](https://pkg.pr.new) - Continuous (Preview) Releases for your libraries
25-
- 🐙 [GitHub Actions](https://github.com/features/actions) - runs your CI _(fixes code style issues, tags releases & creates its changelogs, runs the test suite, etc.)_
17+
```bash
18+
# Install globally
19+
npm install -g gitlint
20+
21+
# Or using bun
22+
bun install -g gitlint
23+
```
24+
25+
## Usage
26+
27+
### CLI
28+
29+
```bash
30+
# Check a commit message from a file
31+
gitlint path/to/commit-message.txt
32+
33+
# Use with git commit message hook (common use case)
34+
gitlint --edit $1
35+
36+
# Show help
37+
gitlint --help
38+
```
39+
40+
### Git Hooks Integration
41+
42+
GitLint can automatically install Git hooks for your repository:
43+
44+
```bash
45+
# Install the commit-msg hook
46+
gitlint hooks --install
47+
48+
# Force overwrite if a hook already exists
49+
gitlint hooks --install --force
2650

27-
## Get Started
51+
# Uninstall the hooks
52+
gitlint hooks --uninstall
53+
```
2854

29-
It's rather simple to get your package development started:
55+
Or manually add to your `.git/hooks/commit-msg` file:
3056

3157
```bash
32-
# you may use this GitHub template or the following command:
33-
bunx degit stacksjs/ts-starter my-pkg
34-
cd my-pkg
58+
#!/bin/sh
59+
gitlint --edit "$1"
60+
```
3561

36-
bun i # install all deps
37-
bun run build # builds the library for production-ready use
62+
Or use with [husky](https://github.com/typicode/husky):
63+
64+
```json
65+
// package.json
66+
{
67+
"husky": {
68+
"hooks": {
69+
"commit-msg": "gitlint --edit $HUSKY_GIT_PARAMS"
70+
}
71+
}
72+
}
73+
```
3874

39-
# after you have successfully committed, you may create a "release"
40-
bun run release # automates git commits, versioning, and changelog generations
75+
## Configuration
76+
77+
Create a `gitlint.config.js` file in your project root:
78+
79+
```js
80+
// gitlint.config.js
81+
module.exports = {
82+
verbose: true,
83+
rules: {
84+
'conventional-commits': 2,
85+
'header-max-length': [2, { maxLength: 72 }],
86+
'body-max-line-length': [2, { maxLength: 100 }],
87+
'body-leading-blank': 2,
88+
'no-trailing-whitespace': 1
89+
},
90+
ignores: [
91+
'^Merge branch',
92+
'^Merge pull request'
93+
]
94+
}
4195
```
4296

43-
_Check out the package.json scripts for more commands._
97+
### Rule Levels
98+
99+
- `0` or `off`: Disable the rule
100+
- `1` or `warning`: Warning (doesn't cause exit code to be non-zero)
101+
- `2` or `error`: Error (causes exit code to be non-zero)
102+
103+
## Built-in Rules
104+
105+
- `conventional-commits`: Enforces conventional commit format (`<type>(scope): description`)
106+
- `header-max-length`: Enforces a maximum header length
107+
- `body-max-line-length`: Enforces a maximum body line length
108+
- `body-leading-blank`: Enforces a blank line between header and body
109+
- `no-trailing-whitespace`: Checks for trailing whitespace
110+
111+
## Programmatic Usage
112+
113+
```js
114+
import { lintCommitMessage, parseCommitMessage } from 'gitlint'
115+
116+
// Lint a commit message
117+
const result = lintCommitMessage('feat: add new feature')
118+
console.log(result.valid) // true or false
119+
console.log(result.errors) // array of error messages
120+
console.log(result.warnings) // array of warning messages
121+
122+
// Parse a commit message
123+
const parsed = parseCommitMessage('feat(scope): description\n\nBody text\n\nCloses #123')
124+
console.log(parsed.type) // 'feat'
125+
console.log(parsed.scope) // 'scope'
126+
console.log(parsed.references) // [{issue: '123', ...}]
127+
```
44128

45129
## Testing
46130

@@ -50,7 +134,7 @@ bun test
50134

51135
## Changelog
52136

53-
Please see our [releases](https://github.com/stackjs/bun-ts-starter/releases) page for more information on what has changed recently.
137+
Please see our [releases](https://github.com/stackjs/bun-gitlint/releases) page for more information on what has changed recently.
54138

55139
## Contributing
56140

@@ -60,7 +144,7 @@ Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.
60144

61145
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
62146

63-
[Discussions on GitHub](https://github.com/stacksjs/ts-starter/discussions)
147+
[Discussions on GitHub](https://github.com/stacksjs/gitlint/discussions)
64148

65149
For casual chit-chat with others using this package:
66150

@@ -86,10 +170,10 @@ The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.
86170
Made with 💙
87171

88172
<!-- Badges -->
89-
[npm-version-src]: https://img.shields.io/npm/v/bun-ts-starter?style=flat-square
90-
[npm-version-href]: https://npmjs.com/package/bun-ts-starter
91-
[github-actions-src]: https://img.shields.io/github/actions/workflow/status/stacksjs/ts-starter/ci.yml?style=flat-square&branch=main
92-
[github-actions-href]: https://github.com/stacksjs/ts-starter/actions?query=workflow%3Aci
173+
[npm-version-src]: https://img.shields.io/npm/v/bun-gitlint?style=flat-square
174+
[npm-version-href]: https://npmjs.com/package/bun-gitlint
175+
[github-actions-src]: https://img.shields.io/github/actions/workflow/status/stacksjs/gitlint/ci.yml?style=flat-square&branch=main
176+
[github-actions-href]: https://github.com/stacksjs/gitlint/actions?query=workflow%3Aci
93177

94-
<!-- [codecov-src]: https://img.shields.io/codecov/c/gh/stacksjs/ts-starter/main?style=flat-square
95-
[codecov-href]: https://codecov.io/gh/stacksjs/ts-starter -->
178+
<!-- [codecov-src]: https://img.shields.io/codecov/c/gh/stacksjs/gitlint/main?style=flat-square
179+
[codecov-href]: https://codecov.io/gh/stacksjs/gitlint -->

bin/cli.ts

Lines changed: 121 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,138 @@
1+
import { Buffer } from 'node:buffer'
2+
import fs from 'node:fs'
3+
import path from 'node:path'
4+
import process from 'node:process'
15
import { CAC } from 'cac'
26
import { version } from '../package.json'
37

4-
const cli = new CAC('my-cli')
8+
// Create a default config in case the import fails
9+
const defaultConfig = {
10+
verbose: false,
11+
rules: {
12+
'conventional-commits': 2,
13+
'header-max-length': [2, { maxLength: 72 }],
14+
'body-max-line-length': [2, { maxLength: 100 }],
15+
'body-leading-blank': 2,
16+
'no-trailing-whitespace': 1,
17+
},
18+
defaultIgnores: [
19+
'^Merge branch',
20+
'^Merge pull request',
21+
'^Merged PR',
22+
'^Revert ',
23+
'^Release ',
24+
],
25+
ignores: [],
26+
}
27+
28+
const cli = new CAC('gitlint')
529

6-
interface CliOption {
7-
from: string
8-
verbose: boolean
30+
// Helper function to read commit message from file
31+
function readCommitMessageFromFile(filePath: string): string {
32+
try {
33+
return fs.readFileSync(path.resolve(process.cwd(), filePath), 'utf8')
34+
}
35+
catch (error: unknown) {
36+
console.error(`Error reading commit message file: ${filePath}`)
37+
console.error(error)
38+
process.exit(1)
39+
return '' // Unreachable but needed for TypeScript
40+
}
941
}
1042

43+
// Main lint command
1144
cli
12-
.command('start', 'Start the Reverse Proxy Server')
13-
.option('--from <from>', 'The URL to proxy from')
14-
.option('--verbose', 'Enable verbose logging')
15-
.example('reverse-proxy start --from localhost:5173 --to my-project.localhost')
16-
.action(async (options?: CliOption) => {
17-
if (!options?.from) {
18-
console.error('Missing --from option')
45+
.command('[...files]', 'Lint commit message')
46+
.option('--edit <file>', 'Path to .git/COMMIT_EDITMSG file')
47+
.option('--verbose', 'Enable verbose output', { default: defaultConfig.verbose })
48+
.option('--config <file>', 'Path to config file')
49+
.action(async (files: string[], options) => {
50+
let commitMessage = ''
51+
52+
// Get commit message from file if --edit flag is used
53+
if (options.edit) {
54+
commitMessage = readCommitMessageFromFile(options.edit)
55+
}
56+
// Or from files passed as arguments
57+
else if (files.length > 0) {
58+
commitMessage = readCommitMessageFromFile(files[0])
59+
}
60+
// Or from stdin if piped
61+
else if (!process.stdin.isTTY) {
62+
const chunks: Buffer[] = []
63+
for await (const chunk of process.stdin)
64+
chunks.push(Buffer.from(chunk))
65+
commitMessage = Buffer.concat(chunks).toString('utf8')
1966
}
2067
else {
21-
console.log('Options:', options)
68+
cli.outputHelp()
69+
process.exit(1)
70+
}
71+
72+
try {
73+
// Import rules dynamically
74+
const { lintCommitMessage } = await import('../src')
75+
const result = lintCommitMessage(commitMessage, options.verbose)
76+
77+
if (!result.valid) {
78+
console.error('Commit message validation failed:')
79+
result.errors.forEach((error: string) => {
80+
console.error(`- ${error}`)
81+
})
82+
process.exit(1)
83+
}
84+
85+
if (options.verbose) {
86+
console.log('Commit message validation passed! ✅')
87+
}
88+
}
89+
catch (error: unknown) {
90+
console.error('Error during commit message linting:')
91+
console.error(error)
92+
process.exit(1)
93+
}
94+
95+
process.exit(0)
96+
})
97+
98+
// Install git hooks command
99+
cli
100+
.command('hooks', 'Manage git hooks')
101+
.option('--install', 'Install git hooks')
102+
.option('--uninstall', 'Uninstall git hooks')
103+
.option('--force', 'Force overwrite existing hooks')
104+
.action(async (options) => {
105+
try {
106+
const { installGitHooks, uninstallGitHooks } = await import('../src')
107+
108+
if (options.install) {
109+
const success = installGitHooks(options.force)
110+
process.exit(success ? 0 : 1)
111+
}
112+
else if (options.uninstall) {
113+
const success = uninstallGitHooks()
114+
process.exit(success ? 0 : 1)
115+
}
116+
else {
117+
console.error('Please specify --install or --uninstall')
118+
process.exit(1)
119+
}
120+
}
121+
catch (error: unknown) {
122+
console.error('Error managing git hooks:')
123+
console.error(error)
124+
process.exit(1)
22125
}
23126
})
24127

25-
cli.command('version', 'Show the version of the CLI').action(() => {
128+
// Version command
129+
cli.command('version', 'Show the version of gitlint').action(() => {
26130
console.log(version)
27131
})
28132

29-
cli.version(version)
133+
// Set up help and version
30134
cli.help()
135+
cli.version(version)
136+
137+
// Parse CLI args
31138
cli.parse()

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@
3737
"module": "./dist/index.js",
3838
"types": "./dist/index.d.ts",
3939
"bin": {
40-
"bin-name": "./dist/bin/cli.js"
40+
"gitlint": "./dist/bin/cli.js"
4141
},
4242
"files": ["README.md", "dist"],
4343
"scripts": {
4444
"build": "bun --bun build.ts && bun run compile",
45-
"compile": "bun build ./bin/cli.ts --compile --minify --outfile bin/bin-name",
45+
"compile": "bun build ./bin/cli.ts --compile --minify --outfile bin/gitlint",
4646
"compile:all": "bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:windows-x64 && bun run compile:darwin-x64 && bun run compile:darwin-arm64",
47-
"compile:linux-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-x64 --outfile bin/bin-name-linux-x64",
48-
"compile:linux-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-arm64 --outfile bin/bin-name-linux-arm64",
49-
"compile:windows-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-windows-x64 --outfile bin/bin-name-windows-x64.exe",
50-
"compile:darwin-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-x64 --outfile bin/bin-name-darwin-x64",
51-
"compile:darwin-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-arm64 --outfile bin/bin-name-darwin-arm64",
47+
"compile:linux-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-x64 --outfile bin/gitlint-linux-x64",
48+
"compile:linux-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-arm64 --outfile bin/gitlint-linux-arm64",
49+
"compile:windows-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-windows-x64 --outfile bin/gitlint-windows-x64.exe",
50+
"compile:darwin-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-x64 --outfile bin/gitlint-darwin-x64",
51+
"compile:darwin-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-arm64 --outfile bin/gitlint-darwin-arm64",
5252
"lint": "bunx --bun eslint .",
5353
"lint:fix": "bunx --bun eslint . --fix",
5454
"fresh": "bunx rimraf node_modules/ bun.lock && bun i",

0 commit comments

Comments
 (0)