Compare commits

..

No commits in common. "main" and "v0.4.0" have entirely different histories.
main ... v0.4.0

11 changed files with 116 additions and 230 deletions

View File

@ -5,16 +5,6 @@ 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).
# [0.5.0] - 2025-04-13
### Changed
- CLI component migrated to Cobra. This introduces the following changes:
- `list` is now a subcommand.
- `create` has been added as a subcommand, use it to create a new .gitignore file.
- Env var `GIGNORE_TEMPLATE_DIR` changed to `GIGNORE_TEMPLATE_ROOT`
- Env var `GIGNORE_LOGLEVEL` may now be used to set the logging level.
# [0.4.0] - 2025-04-05
### Changed

View File

@ -3,7 +3,7 @@
![macOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=macos&logoColor=F0F0F0)
# Gignore - Generate .gitignore files
# Gignore - Generate .gitinore files
## Install
@ -23,28 +23,23 @@ task install
## Usage
```bash
Usage:
gignore [flags]
gignore [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
create Create a new .gitignore file
help Help about any command
list List all .gitignore files in the root template repository
Usage of gignore:
gignore [flags] <template>
Flags:
-h, --help help for gignore
-l, --loglevel string Log level (trace, debug, info, warn, error, fatal, panic) (default "warn")
-r, --root string Root directory to search for .gitignore files (default "gitignoreio")
-dir string
directory containing .gitignore templates (default "gitignoreio")
-l int
log level (shorthand) (default 3)
-list
list available templates
-loglevel int
log level (default 3)
-ls
list available templates (shorthand)
Use "gignore [command] --help" for more information about a command.
```
For example:
```bash
gignore create go
Example:
gignore go
```
## Custom Templates
@ -54,10 +49,10 @@ It's possible to add your own custom templates, simply create a directory in `in
Then pass the dir name as a flag, for example:
```bash
gignore -root=custom create go
gignore -dir=custom go
```
You may set an environment variable `GIGNORE_TEMPLATE_ROOT` to avoid passing the `-root` flag each time.
You may set an environment variable `GIGNORE_TEMPLATE_DIR` to avoid passing the `-dir` flag each time.
If a template is requested but not found in the custom directory then the gitignoreio registry will act as a fallback.
@ -77,8 +72,8 @@ Acceptable values for this flag are:
For example, to set the log level to `debug`, you can use:
```bash
gignore -loglevel=debug create python
```
vbantxt -s=streamname -log-level=debug "bus[0].eq.on=1 bus[1].gain=-12.8"
```
The default log level is `warn` if the flag is not specified.

View File

@ -42,7 +42,7 @@ tasks:
cmds:
- go generate ./...
status:
- ls internal/registry/templates/gitignoreio/*.gitignore >/dev/null
- ls internal/registry/templates/gitignoreio/*.gitignore >/dev/null || exit 1
build-windows:
desc: Build the gignore project for Windows

View File

@ -1,22 +0,0 @@
// Package main provides the entry point for the gignore CLI tool,
// including commands like listing available .gitignore templates.
package main
import (
"context"
"github.com/onyx-and-iris/gignore"
log "github.com/sirupsen/logrus"
)
type contextKey string
const clientKey contextKey = "client"
func getClientFromContext(ctx context.Context) *gignore.Client {
client, ok := ctx.Value(clientKey).(*gignore.Client)
if !ok {
log.Fatal("Client not found in context")
}
return client
}

View File

@ -1,50 +0,0 @@
// Package main provides the entry point for the gignore CLI tool,
// including commands like listing available .gitignore templates.
package main
import (
"context"
"fmt"
"github.com/spf13/cobra"
)
// createCmd is the command to create a new .gitignore file.
var createCmd = &cobra.Command{
Use: "create",
Short: "Create a new .gitignore file",
Long: `Create a new .gitignore file in the current directory.
At least one template must be specified.
Multiple templates can be specified, and they will be combined into a single .gitignore file.
Example:
gignore create python
gignore create python go`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
for _, arg := range args {
err := createTemplate(cmd.Context(), arg)
cobra.CheckErr(err)
}
},
}
// init initialises the create command and adds it to the root command.
func init() {
rootCmd.AddCommand(createCmd)
}
// createTemplate creates a new .gitignore file using the specified template.
func createTemplate(ctx context.Context, template string) error {
client := getClientFromContext(ctx)
err := client.Create(template)
if err != nil {
return err
}
fmt.Printf("√ created %s .gitignore file\n", template)
return nil
}

View File

@ -1,49 +0,0 @@
// Package main provides the entry point for the gignore CLI tool,
// including commands like listing available .gitignore templates.
package main
import (
"context"
"fmt"
"strings"
"github.com/spf13/cobra"
)
// listCmd is the command to list all .gitignore templates.
var listCmd = &cobra.Command{
Use: "list",
Short: "List all .gitignore files in the root template repository",
Long: `List all .gitignore files in the root template repository.
This command will search the root template repository for .gitignore files and print their paths to the console.
The root template repository can be specified using the --root flag.
You can use this command to quickly find all available .gitignore templates.
Example:
gignore --root=<path> list`,
Run: func(cmd *cobra.Command, _ []string) {
err := listTemplates(cmd.Context())
cobra.CheckErr(err)
},
}
// init initialises the list command and adds it to the root command.
func init() {
rootCmd.AddCommand(listCmd)
}
// listTemplates retrieves and prints all .gitignore templates available from the gignore client.
func listTemplates(ctx context.Context) error {
client := getClientFromContext(ctx)
templates, err := client.List()
if err != nil {
return err
}
var output strings.Builder
for _, template := range templates {
output.WriteString(template + "\n")
}
fmt.Print(output.String())
return nil
}

View File

@ -1,65 +1,93 @@
// Package main provides the entry point for the gignore CLI tool,
// including commands like listing available .gitignore templates.
// Package main provides the entry point for the gignore command-line tool,
// which generates .gitignore files based on specified templates.
package main
import (
"context"
"flag"
"fmt"
"os"
"github.com/onyx-and-iris/gignore"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
// rootCmd is the root command for the gignore CLI tool.
var rootCmd = &cobra.Command{
Use: "gignore",
Short: "A command line tool to manage .gitignore files",
Long: `gignore is a command line tool that helps you manage your .gitignore files.
You can use it to list available templates and create new .gitignore files.
It supports various programming languages.
Example:
gignore list
gignore create python`,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
// Initialise the logger
loglevel, err := log.ParseLevel(cmd.Flag("loglevel").Value.String())
cobra.CheckErr(err)
log.SetLevel(loglevel)
// Initialise the gignore client
client := gignore.New(
gignore.WithTemplateDirectory(cmd.Flag("root").Value.String()),
)
// Set the client in the context
// This allows us to access the client in the command handlers
ctx := context.WithValue(context.Background(), clientKey, client)
cmd.SetContext(ctx)
},
Run: func(cmd *cobra.Command, _ []string) {
cmd.Help()
},
}
// init initialises the root command and adds global flags.
func init() {
getEnv := func(key, defaultValue string) string {
value := os.Getenv(key)
if value == "" {
return defaultValue
}
return value
}
rootCmd.PersistentFlags().
StringP("root", "r", getEnv("GIGNORE_TEMPLATE_ROOT", gignore.DefaultTemplateDirectory), "Root directory to search for .gitignore files")
rootCmd.PersistentFlags().
StringP("loglevel", "l", getEnv("GIGNORE_LOGLEVEL", "warn"), "Log level (trace, debug, info, warn, error, fatal, panic)")
func exit(err error) {
_, _ = fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
func main() {
if err := rootCmd.Execute(); err != nil {
log.Fatal(err)
flag.Usage = func() {
w := flag.CommandLine.Output()
fmt.Fprint(w, "Usage of gignore:\n")
fmt.Fprint(w, " gignore [flags] <template>\n")
fmt.Fprint(w, "\n")
fmt.Fprint(w, "Flags:\n")
flag.PrintDefaults()
fmt.Fprint(w, "\n")
fmt.Fprint(w, "Example:\n")
fmt.Fprint(w, " gignore go\n")
}
var (
list bool
templateDir string
loglevel string
)
flag.BoolVar(&list, "list", false, "list available templates")
flag.BoolVar(&list, "ls", false, "list available templates (shorthand)")
flag.StringVar(
&templateDir,
"dir",
getEnv("GIGNORE_TEMPLATE_DIR", "gitignoreio"),
"directory containing .gitignore templates",
)
flag.StringVar(&loglevel, "loglevel", "warn", "log level")
flag.StringVar(&loglevel, "l", "warn", "log level (shorthand)")
flag.Parse()
level, err := log.ParseLevel(loglevel)
if err != nil {
exit(fmt.Errorf("invalid log level: %s", loglevel))
}
log.SetLevel(level)
client := gignore.New(gignore.WithTemplateDirectory(templateDir))
if list {
if err := listTemplates(client); err != nil {
exit(fmt.Errorf("failed to list templates: %v", err))
}
return
}
args := flag.Args()
if len(args) == 0 {
flag.Usage()
return
}
for _, arg := range args {
err := client.Create(arg)
if err != nil {
exit(fmt.Errorf("failed to create .gitignore file: %v", err))
}
fmt.Printf("√ created %s .gitignore file\n", arg)
}
}
func listTemplates(client *gignore.Client) error {
templates, err := client.List()
if err != nil {
return err
}
for _, template := range templates {
fmt.Println(template)
}
return nil
}

11
cmd/gignore/util.go Normal file
View File

@ -0,0 +1,11 @@
package main
import "os"
func getEnv(key, defaultValue string) string {
value := os.Getenv(key)
if value == "" {
return defaultValue
}
return value
}

View File

@ -10,9 +10,6 @@ import (
//go:generate go run cmd/gen/main.go
// DefaultTemplateDirectory is the default directory for .gitignore templates.
const DefaultTemplateDirectory = "gitignoreio"
// Client is a client for managing .gitignore templates.
type Client struct {
registry *registry.TemplateRegistry
@ -46,11 +43,11 @@ func (c *Client) Create(template string) error {
}
if !ok {
templateNotFoundErr := &templateNotFoundError{template, []string{c.registry.Directory}}
if c.registry.Directory == DefaultTemplateDirectory {
if c.registry.Directory == "gitignoreio" {
return templateNotFoundErr
}
c.registry.Directory = DefaultTemplateDirectory
c.registry.Directory = "gitignoreio"
ok, err = c.registry.Contains(template)
if err != nil {
return err

7
go.mod
View File

@ -5,11 +5,6 @@ go 1.24.0
require (
github.com/cuonglm/gogi v1.0.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
)
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.6 // indirect
golang.org/x/sys v0.32.0 // indirect
)
require golang.org/x/sys v0.31.0 // indirect

15
go.sum
View File

@ -1,27 +1,18 @@
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/cuonglm/gogi v1.0.1 h1:Jotx6uAfFK6YHFOOek37R9y3Ae9qp/nUt/3mYGCl+44=
github.com/cuonglm/gogi v1.0.1/go.mod h1:ZLU5wl3d+FSSkiYYDpmPJI2dWdAGj8q28rFjpeWv1g4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=