mirror of
https://github.com/onyx-and-iris/exclude.git
synced 2026-03-30 23:19:09 +00:00
exclude initial commit
This commit is contained in:
commit
f249cc2a4d
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Auto-generated .gitignore by gignore: github.com/onyx-and-iris/gignore
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
bin/
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
|
||||||
|
# End of gignore: github.com/onyx-and-iris/gignore
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright © 2025 onyx-and-iris <code@onyxandiris.online>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
41
cmd/add.go
Normal file
41
cmd/add.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// addCmd represents the add command
|
||||||
|
var addCmd = &cobra.Command{
|
||||||
|
Use: "add",
|
||||||
|
Short: "Add patterns to the exclude file",
|
||||||
|
Long: `The add command allows you to add one or more patterns to the .git/info/exclude file.
|
||||||
|
This is useful for excluding files or directories from version control without modifying the .gitignore file.`,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
f, ok := FileFromContext(cmd.Context())
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("no exclude file found in context")
|
||||||
|
}
|
||||||
|
return runAddCommand(f, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(addCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddCommand(f io.Writer, args []string) error {
|
||||||
|
for _, pattern := range args {
|
||||||
|
if _, err := fmt.Fprintln(f, pattern); err != nil {
|
||||||
|
return fmt.Errorf("error writing to exclude file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("Patterns added to .git/info/exclude file:")
|
||||||
|
for _, pattern := range args {
|
||||||
|
fmt.Println(" -", pattern)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
21
cmd/context.go
Normal file
21
cmd/context.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
|
const fileContextKey contextKey = "excludeFile"
|
||||||
|
|
||||||
|
// ContextWithFile returns a new context with the given file set.
|
||||||
|
func ContextWithFile(ctx context.Context, file *os.File) context.Context {
|
||||||
|
return context.WithValue(ctx, fileContextKey, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileFromContext retrieves the file from the context, if it exists.
|
||||||
|
func FileFromContext(ctx context.Context) (*os.File, bool) {
|
||||||
|
file, ok := ctx.Value(fileContextKey).(*os.File)
|
||||||
|
return file, ok
|
||||||
|
}
|
||||||
59
cmd/list.go
Normal file
59
cmd/list.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// listCmd represents the list command
|
||||||
|
var listCmd = &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "List all patterns in the exclude file",
|
||||||
|
Long: `The list command reads the .git/info/exclude file and prints all patterns
|
||||||
|
that are not empty and do not start with a comment (#).
|
||||||
|
This is useful for reviewing which files or directories are currently excluded from version control.`,
|
||||||
|
Args: cobra.NoArgs, // No arguments expected
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
f, ok := FileFromContext(cmd.Context())
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("no exclude file found in context")
|
||||||
|
}
|
||||||
|
return runListCommand(f, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(listCmd)
|
||||||
|
|
||||||
|
// Here you will define your flags and configuration settings.
|
||||||
|
|
||||||
|
// Cobra supports Persistent Flags which will work for this command
|
||||||
|
// and all subcommands, e.g.:
|
||||||
|
// listCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||||
|
|
||||||
|
// Cobra supports local flags which will only run when this command
|
||||||
|
// is called directly, e.g.:
|
||||||
|
// listCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
}
|
||||||
|
|
||||||
|
// runListCommand is the function that will be executed when the list command is called
|
||||||
|
func runListCommand(f io.Reader, _ []string) error {
|
||||||
|
// Read from the exclude file line by line
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if line != "" && !strings.HasPrefix(line, "#") {
|
||||||
|
fmt.Println(line) // Print each non-empty, non-comment line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return fmt.Errorf("error reading exclude file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can add more functionality as needed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
50
cmd/reset.go
Normal file
50
cmd/reset.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// resetCmd represents the reset command
|
||||||
|
var resetCmd = &cobra.Command{
|
||||||
|
Use: "reset",
|
||||||
|
Short: "Reset the exclude file",
|
||||||
|
Long: `The reset command clears all patterns from the .git/info/exclude file.
|
||||||
|
This is useful for starting fresh or removing all exclusions at once.`,
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
f, ok := FileFromContext(cmd.Context())
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("no exclude file found in context")
|
||||||
|
}
|
||||||
|
return runResetCommand(f)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(resetCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:embed template/exclude
|
||||||
|
var defaultExcludeFile string
|
||||||
|
|
||||||
|
// runResetCommand clears the exclude file
|
||||||
|
func runResetCommand(f *os.File) error {
|
||||||
|
// Clear the exclude file by truncating it
|
||||||
|
if err := f.Truncate(0); err != nil {
|
||||||
|
return fmt.Errorf("error truncating exclude file: %w", err)
|
||||||
|
}
|
||||||
|
// Reset the file pointer to the beginning
|
||||||
|
if _, err := f.Seek(0, 0); err != nil {
|
||||||
|
return fmt.Errorf("error seeking to the beginning of exclude file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the default exclude patterns to the file
|
||||||
|
if _, err := f.WriteString(defaultExcludeFile); err != nil {
|
||||||
|
return fmt.Errorf("error writing default exclude file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
65
cmd/root.go
Normal file
65
cmd/root.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// rootCmd represents the base command when called without any subcommands
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "exclude",
|
||||||
|
Short: "A command line tool to manage .git/info/exclude files",
|
||||||
|
Long: `Exclude is a command line tool designed to help you manage your .git/info/exclude files.
|
||||||
|
It allows you to add, list, and remove patterns from the exclude file easily.
|
||||||
|
This tool is particularly useful for developers who want to keep their repository clean
|
||||||
|
by excluding certain files or directories from version control.`,
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
// This function runs before any command is executed.
|
||||||
|
// You can use it to set up global configurations or checks.
|
||||||
|
// For example, you might want to check if the .git directory exists
|
||||||
|
if _, err := os.Stat(".git"); os.IsNotExist(err) {
|
||||||
|
cmd.Println("Error: This command must be run in a Git repository.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.OpenFile(".git/info/exclude", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
|
||||||
|
if err != nil {
|
||||||
|
cmd.Println("Error opening .git/info/exclude file:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.WithValue(context.Background(), fileContextKey, f)
|
||||||
|
cmd.SetContext(ctx)
|
||||||
|
},
|
||||||
|
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
if f, ok := FileFromContext(cmd.Context()); ok {
|
||||||
|
defer f.Close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Uncomment the following line if your bare application
|
||||||
|
// has an action associated with it:
|
||||||
|
// Run: func(cmd *cobra.Command, args []string) { },
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
|
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||||
|
func Execute() {
|
||||||
|
err := rootCmd.Execute()
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Here you will define your flags and configuration settings.
|
||||||
|
// Cobra supports persistent flags, which, if defined here,
|
||||||
|
// will be global for your application.
|
||||||
|
|
||||||
|
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.exclude.yaml)")
|
||||||
|
|
||||||
|
// Cobra also supports local flags, which will only run
|
||||||
|
// when this action is called directly.
|
||||||
|
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
}
|
||||||
6
cmd/template/exclude
Normal file
6
cmd/template/exclude
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
||||||
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module github.com/onyx-and-iris/exclude
|
||||||
|
|
||||||
|
go 1.24.3
|
||||||
|
|
||||||
|
require github.com/spf13/cobra v1.9.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
|
)
|
||||||
10
go.sum
Normal file
10
go.sum
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
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=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
Loading…
x
Reference in New Issue
Block a user