main.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5package main
 6
 7import (
 8	"context"
 9	"os"
10	"runtime/debug"
11
12	"github.com/charmbracelet/fang"
13	"github.com/spf13/cobra"
14)
15
16var (
17	commitType     string
18	message        string
19	trailers       []string
20	body           string
21	scope          string
22	breakingChange bool
23)
24
25var rootCmd = &cobra.Command{
26	Use:   "formatted-commit",
27	Short: "Create conventionally formatted Git commits",
28	Long: `formatted-commit helps you create well-formatted Git commits that follow
29the Conventional Commits specification with proper subject length validation,
30body wrapping, and trailer formatting.`,
31	Example: `
32# With co-author
33formatted-commit -t feat -m "do a thing" -T "Crush <crush@charm.land>"
34
35# Breaking change with longer body
36formatted-commit -t feat -m "do a thing that borks a thing" -B "$(cat <<'EOF'
37Multi-line
38- Body
39- Here
40
41This is what borked because of new shiny, this is how migrate
42EOF
43)"
44
45# Including scope for more precise changes
46formatted-commit -t refactor -s "web/git-bug" -m "fancy shmancy" \
47  -b "Had to do a weird thing because..."
48`,
49	RunE: func(cmd *cobra.Command, args []string) error {
50		// TODO: Implement commit formatting logic here
51		// 1. Validate subject length (type(scope): message <= 50 chars)
52		// 2. Format body as Markdown wrapped to 72 columns
53		// 3. Validate and format trailers
54		// 4. Pipe result to `git commit -F -`
55
56		return nil
57	},
58}
59
60func init() {
61	rootCmd.Flags().StringVarP(&commitType, "type", "t", "", "commit type (required)")
62	rootCmd.Flags().StringVarP(&message, "message", "m", "", "commit message (required)")
63	rootCmd.Flags().StringSliceVarP(&trailers, "trailer", "T", []string{}, "trailer in 'Sentence-case-key: value' format (optional, repeatable)")
64	rootCmd.Flags().StringVarP(&body, "body", "b", "", "commit body (optional)")
65	rootCmd.Flags().StringVarP(&scope, "scope", "s", "", "commit scope (optional)")
66	rootCmd.Flags().BoolVarP(&breakingChange, "breaking", "B", false, "mark as breaking change (optional)")
67
68	if err := rootCmd.MarkFlagRequired("type"); err != nil {
69		panic(err)
70	}
71	if err := rootCmd.MarkFlagRequired("message"); err != nil {
72		panic(err)
73	}
74}
75
76func main() {
77	ctx := context.Background()
78
79	var version string
80	if info, ok := debug.ReadBuildInfo(); ok {
81		version = info.Main.Version
82	}
83	if version == "" || version == "(devel)" {
84		version = "dev"
85	}
86
87	if err := fang.Execute(ctx, rootCmd,
88		fang.WithVersion(version),
89		fang.WithoutCompletions(),
90	); err != nil {
91		os.Exit(1)
92	}
93}