### Example: Get Current Working Directory Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md Demonstrates how to use the OSGetwdOption function to retrieve and print the current working directory. Handles potential errors during retrieval. ```go cwd, err := helper.OSGetwdOption() if err != nil { log.Fatal(err) } fmt.Println("Current directory:", cwd) ``` -------------------------------- ### Install goimports-reviser with Snap Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Install the goimports-reviser tool using the Snap package manager. ```bash snap install goimports-reviser ``` -------------------------------- ### Complete Go Analysis Example Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md This example demonstrates how to create and run a Go analysis checker using goimports-reviser with specific configurations for removing unused imports and code formatting. ```go package main import ( "flag" "fmt" "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/singlechecker" "github.com/incu6us/goimports-reviser/v3/pkg/goanalysis" "github.com/incu6us/goimports-reviser/v3/reviser" ) func main() { // Create analyzer analyzer := goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "github.com/mycompany", reviser.WithRemovingUnusedImports, reviser.WithCodeFormatting, ) // Run as a single-checker linter singlechecker.Main(analyzer) } ``` -------------------------------- ### Example Files with Build Tags Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/astutil.md Illustrates Go files with different build tags, including modern `//go:build` and deprecated `//+build` syntax, for conditional compilation. ```go // File 1: Windows-only code //go:build windows // +build windows package main import "syscall" // File 2: Test-only code //go:build tools // +build tools package tools import "golang.org/x/tools/cmd/goimports" ``` -------------------------------- ### Install goimports-reviser with Go Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Install the goimports-reviser tool globally using the go install command. ```bash go install -v github.com/incu6us/goimports-reviser/v3@latest ``` -------------------------------- ### Install goimports-reviser with Brew Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Install the goimports-reviser tool using Homebrew by tapping the repository and then installing the package. ```bash brew tap incu6us/homebrew-tap brew install incu6us/homebrew-tap/goimports-reviser ``` -------------------------------- ### Go Code Formatting Example Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Shows the effect of the '-format' option, which performs additional code formatting beyond import management. ```go package main func test(){ } func additionalTest(){ } ``` ```go package main func test(){ } func additionalTest(){ } ``` -------------------------------- ### Go Analysis With Full Configuration Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md This example illustrates initializing the Go analysis checker with a comprehensive set of configurations, including multiple company prefixes and specific import handling options. ```go flagSet := flag.NewFlagSet("", flag.ContinueOnError) analyzer := goanalysis.NewAnalyzer( flagSet, "github.com/mycompany,github.com/myorg", reviser.WithRemovingUnusedImports, reviser.WithUsingAliasForVersionSuffix, reviser.WithCodeFormatting, reviser.WithSeparatedNamedImports, ) ``` -------------------------------- ### Go Library Workflow Example Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/INDEX.md Demonstrates a typical workflow for using the goimports-reviser library to fix a source file, including removing unused imports. ```go file := reviser.NewSourceFile(moduleName, filePath) formatted, _, changed, err := file.Fix(reviser.WithRemovingUnusedImports) if err != nil { /* handle error */ } ``` -------------------------------- ### Example: Determine Project Name from Stdin Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md Illustrates determining the project name when processing standard input. The filePath is set to '', and the option function is used to get the working directory. ```go // When processing stdin name, err := helper.DetermineProjectName( "", reviser.StandardInput, // "" helper.OSGetwdOption, ) // Option function is called to get current directory ``` -------------------------------- ### Example: Determine Project Name from File Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md Shows how to determine the project name for a given file path. It uses an empty projectName and the OSGetwdOption function to resolve the context. ```go // When processing a file name, err := helper.DetermineProjectName( "", "/home/user/myproject/main.go", helper.OSGetwdOption, ) ``` -------------------------------- ### Go Imports Formatting Example Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Demonstrates the effect of goimports-reviser on import statement order and grouping. Comments on imports are preserved. ```go package testdata import ( "log" "github.com/incu6us/goimports-reviser/testdata/innderpkg" "bytes" "golang.org/x/exp/slices" ) ``` ```go package testdata import ( "bytes" "log" "golang.org/x/exp/slices" "github.com/incu6us/goimports-reviser/testdata/innderpkg" ) ``` -------------------------------- ### CLI Configuration Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/README.md Documentation for CLI flags and command-line options, including usage examples, IDE integration, and CI/CD patterns. ```APIDOC ## CLI Configuration ### Description Details on command-line flags and options available for the goimports-reviser CLI tool. ### Flags - Boolean flags: 13 total, with examples. - String flags: 6 total, including default values. ### Arguments - Handling of target arguments. ### Usage Examples - Common scenarios and patterns. - IDE integration instructions. - CI/CD integration patterns. - Guide for migrating from deprecated flags. ``` -------------------------------- ### Example: ParseBuildTag Usage Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/astutil.md Demonstrates how to parse a build tag from a Go source string and then load package dependencies using the extracted tag. This is useful for build-tag-aware dependency analysis. ```go // File with build tag source := `//go:build windows package main ` fset := token.NewFileSet() f, _ := parser.ParseFile(fset, "main.go", source, parser.ParseComments) tag := astutil.ParseBuildTag(f) fmt.Println(tag) // Output: windows // Later, use with LoadPackageDependencies deps, _ := astutil.LoadPackageDependencies(".", tag) ``` -------------------------------- ### IDE Integration Example Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Configure your IDE's file watcher to automatically run goimports-reviser on file changes. Specify the program and arguments, including the current file path. ```bash # In IDE file watcher: # Program: goimports-reviser # Arguments: -rm-unused -set-alias -format $FilePath$ # Working Directory: $ProjectFileDir$ ``` -------------------------------- ### Handle Errors in module.Name Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Example error handling for module.Name, covering go.mod not found, malformed go.mod, and missing module directive. ```go name, err := module.Name(rootPath) if err != nil { if _, ok := err.(*module.UndefinedModuleError); ok { log.Fatal("go.mod exists but module is undefined") } if os.IsNotExist(err) { log.Fatal("go.mod not found") } log.Fatalf("Error reading go.mod: %v", err) } ``` -------------------------------- ### Handle PathIsNotSetError Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/module.md Example of checking for and handling a PathIsNotSetError when determining a project name. ```go name, err := module.DetermineProjectName("", "") if err != nil { if _, ok := err.(*module.PathIsNotSetError); ok { fmt.Println("Path must be provided") } } ``` -------------------------------- ### Default Behavior Example Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Demonstrates the default behavior when goimports-reviser is invoked with minimal flags on a single file. Shows default settings for import order, output, and other options. ```bash goimports-reviser ./file.go ``` -------------------------------- ### Goimports-reviser CLI Usage Examples Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/INDEX.md Shows common command-line invocations for goimports-reviser, including options for removing unused imports, setting aliases, formatting code, and listing differences. ```bash goimports-reviser -rm-unused -set-alias -format ./... ``` ```bash goimports-reviser -list-diff -set-exit-status ./... ``` -------------------------------- ### PackageImports Map Example Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/types.md Illustrates the structure of PackageImports, which maps import paths to their corresponding package names. Useful for managing and referencing package imports. ```go PackageImports{ "fmt": "fmt", "errors": "errors", "github.com/pkg/errors": "errors", "golang.org/x/exp/slices": "slices", } ``` -------------------------------- ### Example of -separate-named option Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Shows the transformation of import statements before and after applying the -separate-named option. This option helps in organizing imports by separating named imports. ```go package testdata // goimports-reviser/testdata import ( "fmt" "github.com/incu6us/goimports-reviser/pkg" extpkg "google.com/golang/pkg" "golang.org/x/exp/slices" extslice "github.com/PeterRK/slices" ) ``` ```go package testdata // goimports-reviser/testdata import ( "fmt" "github.com/incu6us/goimports-reviser/pkg" "golang.org/x/exp/slices" extpkg "google.com/golang/pkg" extslice "github.com/PeterRK/slices" ) ``` -------------------------------- ### Handle Go Syntax Parsing Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md This example shows how to handle errors that occur when the Go parser encounters invalid syntax within a file during the Fix operation. ```go // File with invalid Go syntax func main() { x := 1 + // syntax error: no expression } // When processing: _, _, _, err := file.Fix() // err will contain: expected 'expression', found 'EOF' ``` -------------------------------- ### Error Handling Patterns for DetermineProjectName Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md Provides examples of how to handle errors returned by DetermineProjectName. It outlines potential error causes such as issues with os.Getwd() or go.mod file problems. ```go func handleDetermineProjectNameErrors(filePath string) { _, err := helper.DetermineProjectName( "", filePath, helper.OSGetwdOption, ) if err != nil { fmt.Printf("Failed to determine project name: %v\n", err) // Possible errors: // - os.Getwd() failed (can't determine working dir) // - go.mod not found in directory hierarchy // - go.mod exists but module is not defined } } ``` -------------------------------- ### Handle Invalid Import Order String Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md This example shows how to catch errors when converting an import order string to a usable format. It specifically handles the 'unknown order group type' error. ```go orders, err := reviser.StringToImportsOrders("std,general,invalid") if err != nil { log.Fatalf("Invalid import order: %v", err) // Output: fmt.Errorf: unknown order group type: "invalid" } ``` -------------------------------- ### Create and Configure SourceFile with Functional Options Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/README.md Demonstrates how to create a SourceFile and apply various configuration options using the functional options pattern. This is useful for flexible and composable configuration of import fixing behavior. ```go file := reviser.NewSourceFile(projectName, filePath) formatted, _, changed, err := file.Fix( reviser.WithRemovingUnusedImports, reviser.WithCodeFormatting, reviser.WithCompanyPackagePrefixes("github.com/mycompany"), ) ``` -------------------------------- ### Create SourceFile Instance Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/reviser.md Instantiate a SourceFile processor for a single Go file. Provide the project name and the file path. Use '' for stdin. ```go package main import "github.com/incu6us/goimports-reviser/v3/reviser" func main() { file := reviser.NewSourceFile( "github.com/mycompany/myproject", "./main.go", ) formatted, original, changed, err := file.Fix( reviser.WithRemovingUnusedImports, reviser.WithCodeFormatting, ) if err != nil { panic(err) } println("File changed:", changed) } ``` -------------------------------- ### Creating Imports Order Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/types.md Demonstrates two methods for creating an import order: using predefined constants and parsing a comma-separated string. ```go // Using constants orders := []reviser.ImportsOrder{ reviser.StdImportsOrder, reviser.GeneralImportsOrder, reviser.CompanyImportsOrder, reviser.ProjectImportsOrder, } ``` ```go // Using string parsing orders, _ := reviser.StringToImportsOrders( "std,general,company,project,blanked,dotted", ) ``` -------------------------------- ### Go Imports Formatting with Comments Example Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Shows that goimports-reviser preserves comments associated with import statements. ```go package testdata import ( "fmt" // comments to the package here ) ``` -------------------------------- ### Complete Import Analysis Workflow Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/astutil.md Demonstrates a full workflow for analyzing Go imports in a file. It parses the file, loads all package dependencies, and identifies unused imports. ```go package main import ( "fmt" "go/parser" "go/token" "log" "github.com/incu6us/goimports-reviser/v3/pkg/astutil" ) func analyzeImports(filePath string) { // Parse the file fset := token.NewFileSet() f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments) if err != nil { log.Fatal(err) } // Load all package dependencies packageImports, err := astutil.LoadPackageDependencies(".", "") if err != nil { log.Fatal(err) } // Check which imports are unused for _, imp := range f.Imports { importPath := imp.Path.Value[1 : len(imp.Path.Value)-1] // remove quotes if !astutil.UsesImport(f, packageImports, importPath) { fmt.Printf("Unused import: %s\n", importPath) } } } ``` -------------------------------- ### Get Current Working Directory Option Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md A function that returns the current working directory using os.Getwd. It implements the Option interface. ```go func OSGetwdOption() (string, error) ``` -------------------------------- ### Basic Project Name Determination from File Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md Demonstrates determining the Go module name for a local file using DetermineProjectName. It sets up the necessary imports and handles potential errors. ```go package main import ( "fmt" "log" "github.com/incu6us/goimports-reviser/v3/helper" ) func main() { // From a file name, err := helper.DetermineProjectName( "", "./main.go", helper.OSGetwdOption, ) if err != nil { log.Fatal(err) } fmt.Printf("Module name: %s\n", name) } ``` -------------------------------- ### Create SourceDir Instance Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/reviser.md Instantiate a SourceDir processor to handle Go files within a directory. Configure recursion, and specify exclude patterns for files or directories. ```go dir := reviser.NewSourceDir( "github.com/mycompany/myproject", "./pkg", true, // recursive ".git/,vendor/", // exclude patterns ) ``` -------------------------------- ### Go Analysis Without Configuration Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md This snippet shows how to initialize the Go analysis checker with default settings, using an empty string for company prefixes and relying on default import ordering. ```go analyzer := goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "", ) // Uses default import order: std, general, company, project // No company prefixes defined ``` -------------------------------- ### Using a Custom Option Function for Project Name Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/helper.md Demonstrates how to provide a custom function to DetermineProjectName instead of the default OSGetwdOption. This allows for custom logic in determining the project path. ```go func customOption() (string, error) { // Custom logic to determine directory return "/specific/project/path", nil } func main() { name, err := helper.DetermineProjectName( "", reviser.StandardInput, customOption, // Use custom function instead of os.Getwd ) if err != nil { log.Fatal(err) } fmt.Printf("Module: %s\n", name) } ``` -------------------------------- ### Using PackageImports and astutil.UsesImport Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/types.md Shows how to create a PackageImports map and use the astutil.UsesImport function to check if a specific import is present in a file. ```go imports := astutil.PackageImports{ "fmt": "fmt", "os": "os", "github.com/pkg/errors": "errors", } used := astutil.UsesImport(file, imports, "fmt") ``` -------------------------------- ### Display Detailed Version Information Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Use the -version flag to display comprehensive version details, including build information, Git tag, commit hash, and source repository. ```bash goimports-reviser -version ``` -------------------------------- ### Read Module Name from go.mod Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/module.md Reads the module name from a go.mod file in the specified directory. Use this when you need to programmatically get the module name defined in the go.mod file. ```go moduleName, err := module.Name("/home/user/myproject") if err != nil { log.Fatal(err) } fmt.Println(moduleName) // Output: github.com/mycompany/myproject ``` -------------------------------- ### Go Imports Ordering with Custom Groups Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Demonstrates custom import ordering using the '-imports-order' option, including standard, general, company, project, blanked, and dotted imports. ```go package testdata // goimports-reviser/testdata import ( _ "github.com/pkg1" . "github.com/pkg2" "fmt" //fmt package "golang.org/x/exp/slices" //custom package "github.com/incu6us/goimports-reviser/pkg" // this is a company package which is not a part of the project, but is a part of your organization "goimports-reviser/pkg" ) ``` ```go package testdata // goimports-reviser/testdata import ( "fmt" // fmt package "golang.org/x/exp/slices" // custom package "github.com/incu6us/goimports-reviser/pkg" // this is a company package which is not a part of the project, but is a part of your organization "goimports-reviser/pkg" _ "github.com/pkg1" . "github.com/pkg2" ) ``` -------------------------------- ### WithUsingAliasForVersionSuffix Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/file-options.md Automatically adds explicit package name aliases for versioned imports. For example, `github.com/go-pg/pg/v9` becomes `pg "github.com/go-pg/pg/v9"`, allowing cleaner references to versioned packages. ```APIDOC ## WithUsingAliasForVersionSuffix ### Description Automatically adds explicit package name aliases for versioned imports. For example, `github.com/go-pg/pg/v9` becomes `pg "github.com/go-pg/pg/v9"`. ### Effect: - Detects package imports with version suffixes - Sets explicit aliases to the base package name (last path segment) - Skips imports that already have explicit names - Allows clean references to versioned packages without version numbers in code ### Example: ```go // Before: import "github.com/go-pg/pg/v9" // After with this option: import pg "github.com/go-pg/pg/v9" // Usage in code: pkg := pg.NewDB() ``` ``` -------------------------------- ### Enable Code Formatting Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/file-options.md Use this option to apply additional Go code formatting, including blank lines between functions and normalized comment formatting. This is similar to running `gofmt`. ```go file := reviser.NewSourceFile("myproject", "./main.go") formatted, _, _, err := file.Fix(reviser.WithCodeFormatting) // Input: // func test(){ // } // func additionalTest(){ // } // Output: // func test(){ // } // // func additionalTest(){ // } ``` -------------------------------- ### Handle Errors in SourceDir.Fix Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Illustrates error handling for SourceDir.Fix, including path not being a directory, file processing errors, and write permission issues. ```go dir := reviser.NewSourceDir("myproject", "./pkg", true, "") err := dir.Fix(reviser.WithRemovingUnusedImports) if err != nil { if err == reviser.ErrPathIsNotDir { log.Fatal("Path is not a directory") } log.Fatalf("Failed to fix directory: %v", err) } ``` -------------------------------- ### Add Aliases for Versioned Imports Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/file-options.md Use this option to automatically add explicit package name aliases for versioned imports, simplifying references in code. For example, `github.com/go-pg/pg/v9` becomes `pg \"github.com/go-pg/pg/v9\". ```go // Before: import "github.com/go-pg/pg/v9" // After with this option: import pg "github.com/go-pg/pg/v9" // Usage in code: pkg := pg.NewDB() ``` -------------------------------- ### Handle Errors in SourceFile.Fix Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Demonstrates error handling for SourceFile.Fix, covering file not found, syntax errors, option errors, and analysis failures. ```go file := reviser.NewSourceFile("myproject", "./broken.go") _, _, _, err := file.Fix() if err != nil { if os.IsNotExist(err) { log.Fatal("File not found") } // Could be parsing error, option error, or analysis error log.Fatalf("Failed to fix: %v", err) } ``` -------------------------------- ### module.GoModRootPath Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/module.md Locates the root directory of a Go module by searching for the go.mod file, starting from the given path and walking up the directory tree. Returns the absolute path to the directory containing go.mod or an empty string if not found. ```APIDOC ## GoModRootPath ### Description Locates the root directory of a Go module by searching for the `go.mod` file, starting from the given path and walking up the directory tree. ### Function Signature ```go func GoModRootPath(path string) (string, error) ``` ### Parameters #### Path Parameters - **path** (string) - Required - A file or directory path within the Go project (or the project root itself). ### Returns - **string**: The absolute path to the directory containing `go.mod`. - **error**: Always `nil`; returns empty string if not found. ### Behavior - Starts from the given path - Walks up parent directories until `go.mod` is found - Returns the directory containing `go.mod` - Returns empty string if `go.mod` is not found anywhere in the hierarchy - Cleans paths and handles symlinks correctly ### Special Cases - If `path` is empty, returns empty string - If `path` is a file, searches from its parent directory - If `path` is a directory, searches from that directory ### Example ```go // Finding go.mod for a specific file rootPath, _ := module.GoModRootPath("/home/user/myproject/pkg/handler.go") fmt.Println(rootPath) // Output: /home/user/myproject // Finding go.mod for a directory rootPath, _ := module.GoModRootPath("/home/user/myproject/pkg") fmt.Println(rootPath) // Output: /home/user/myproject // Not found case rootPath, _ := module.GoModRootPath("/tmp/no-go-mod-here") fmt.Println(rootPath) // Output: (empty string) ``` ``` -------------------------------- ### Determine Project Name from Explicit or Auto-detection Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/module.md Determines the Go module name, prioritizing an explicitly provided name. If no name is given, it auto-detects from the go.mod file located via the file path. Use this to get the module name when it might be explicitly set or needs to be found. ```go // With explicit project name name, _ := module.DetermineProjectName("github.com/mycompany/myproject", "./main.go") fmt.Println(name) // Output: github.com/mycompany/myproject // Auto-detect from file path name, err := module.DetermineProjectName("", "/home/user/myproject/pkg/handler.go") if err != nil { log.Fatal(err) } fmt.Println(name) // Output: (reads from /home/user/myproject/go.mod) // Auto-detect from directory name, _ := module.DetermineProjectName("", "/home/user/myproject") fmt.Println(name) // Output: (reads from /home/user/myproject/go.mod) ``` -------------------------------- ### Handle Invalid Import Order Configuration Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Demonstrates handling configuration errors related to invalid import order strings, such as using unknown group names. ```go // Invalid import order orders, err := reviser.StringToImportsOrders("unknown,groups") // err: fmt.Errorf: unknown order group type: "unknown" ``` -------------------------------- ### Format Code and Organize Imports Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Apply code formatting and organize imports simultaneously. ```bash # Format code and organize imports goimports-reviser -format ./main.go ``` -------------------------------- ### Process Single File Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md To format a single Go file, provide its path as a target argument. ```bash # Single file goimports-reviser ./main.go ``` -------------------------------- ### Functional Options Pattern for SourceFile Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/types.md Demonstrates the functional options pattern for configuring SourceFile operations, such as removing unused imports and applying code formatting. ```go var opts reviser.SourceFileOptions opts = append(opts, reviser.WithRemovingUnusedImports) opts = append(opts, reviser.WithCodeFormatting) file := reviser.NewSourceFile("myproject", "./main.go") file.Fix(opts...) ``` -------------------------------- ### Go Imports Formatting with Company Prefixes Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md Illustrates how the '-company-prefixes' option affects the ordering of company-specific packages within imports. ```go package testdata // goimports-reviser/testdata import ( "fmt" //fmt package "golang.org/x/exp/slices" //custom package "github.com/incu6us/goimports-reviser/pkg" // this is a company package which is not a part of the project, but is a part of your organization "goimports-reviser/pkg" ) ``` ```go package testdata // goimports-reviser/testdata import ( "fmt" // fmt package "golang.org/x/exp/slices" // custom package "github.com/incu6us/goimports-reviser/pkg" // this is a company package which is not a part of the project, but is a part of your organization "goimports-reviser/pkg" ) ``` -------------------------------- ### Build Tag Aware Import Analysis Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/astutil.md Shows how to perform import analysis while considering build tags. It first extracts the build tag from the file, then loads dependencies specific to that tag, and finally checks import usage. ```go func analyzeWithBuildTag(filePath string) { fset := token.NewFileSet() f, _ := parser.ParseFile(fset, filePath, nil, parser.ParseComments) // Extract build tag from file buildTag := astutil.ParseBuildTag(f) // Load dependencies with the same build tag deps, err := astutil.LoadPackageDependencies(".", buildTag) if err != nil { // Handle error } // Analyze imports with build-tag-aware dependencies for _, imp := range f.Imports { importPath := imp.Path.Value[1 : len(imp.Path.Value)-1] used := astutil.UsesImport(f, deps, importPath) _ = used } } ``` -------------------------------- ### Load Package Dependencies Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/astutil.md Loads all package dependencies from a directory using `go list`. Supports optional build tags for conditional compilation. ```go // Load all dependencies for the current directory packageImports, err := astutil.LoadPackageDependencies(".", "") if err != nil { log.Fatal(err) } // Load with a build tag packageImports, err = astutil.LoadPackageDependencies(".", "windows") // Use with UsesImport for importPath := range packageImports { used := astutil.UsesImport(file, packageImports, importPath) if !used { fmt.Printf("Unused import: %s\n", importPath) } } ``` -------------------------------- ### Reuse Default File Options Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/file-options.md Applies a predefined set of default options to multiple Go source files. This pattern is useful for maintaining consistent formatting and import rules across different files. ```go var defaultOptions reviser.SourceFileOptions defaultOptions = append(defaultOptions, reviser.WithRemovingUnusedImports, reviser.WithCodeFormatting, ) file1 := reviser.NewSourceFile("project", "./file1.go") file1.Fix(defaultOptions...) file2 := reviser.NewSourceFile("project", "./file2.go") file2.Fix(defaultOptions...) ``` -------------------------------- ### Process Entire Project with Multiple Options Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Recursively process the entire project, removing unused imports, setting aliases, and formatting code. ```bash # Process entire project goimports-reviser -recursive -rm-unused -set-alias -format ./ ``` -------------------------------- ### File Options Configuration Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/README.md Details the configuration options available for `SourceFile`, allowing customization of import sorting and formatting behavior, such as removing unused imports and setting aliases. ```APIDOC ## File Options Configuration ### Description Configuration options for `SourceFile` to customize import processing behavior. ### Types - `SourceFileOption`: Represents a single configuration option. - `SourceFileOptions`: A collection of `SourceFileOption`s. ### Options - `WithRemovingUnusedImports`: Remove unused imports from the file. - `WithUsingAliasForVersionSuffix`: Set explicit aliases for version suffixes in imports. - `WithCodeFormatting`: Apply general code formatting to the file structure. - `WithCompanyPackagePrefixes`: Define specific groups for company-related import paths. - `WithImportsOrder`: Specify a custom ordering for import groups. - `WithSkipGeneratedFile`: Instruct the tool to skip processing auto-generated files. - `WithSeparatedNamedImports`: Separate named imports for better readability. ``` -------------------------------- ### Basic Import Sorting Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Perform a simple sort of imports in a Go file. ```bash # Simple import sorting goimports-reviser ./main.go ``` -------------------------------- ### Build goimports-reviser Linters Source: https://github.com/incu6us/goimports-reviser/blob/master/pkg/goanalysis/README.md Builds all available linters for the goimports-reviser project. Use the generated binaries from the `./bin` directory for your specific OS and architecture. ```shell make build-all-lint ``` -------------------------------- ### Process Multiple Files Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md You can specify multiple Go files to be processed by listing their paths. ```bash # Multiple files goimports-reviser ./main.go ./handler.go ./util.go ``` -------------------------------- ### Handle Insufficient Import Groups Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md This snippet demonstrates handling the error when a required minimum number of import groups are not provided in the configuration string. ```go orders, err := reviser.StringToImportsOrders("std,general") if err != nil { log.Fatalf("Invalid import order: %v", err) // Output: fmt.Errorf: use default at least 4 parameters... } ``` -------------------------------- ### Handle Package Dependency Loading Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Demonstrates error handling for astutil.LoadPackageDependencies. This function can fail if the directory is invalid or if there are package analysis errors. ```go deps, err := astutil.LoadPackageDependencies(".", "") if err != nil { log.Fatalf("Failed to load package dependencies: %v", err) } ``` -------------------------------- ### Handle Option Function Configuration Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Shows potential errors or panics that can occur when configuring options, such as passing nil to WithImportsOrder. ```go // Option function error err := reviser.WithImportsOrder(nil)(file) // May panic or return validation error ``` -------------------------------- ### Run goimports-reviser with go vet Source: https://github.com/incu6us/goimports-reviser/blob/master/pkg/goanalysis/README.md Executes the goimports-reviser linter using `go vet` with the specified binary path. Analyzes all Go packages in the current directory (`./...`). ```shell go vet -vettool=bin/macos-amd64/goimportsreviserlint ./... ``` -------------------------------- ### Handle Missing Go Module Directive Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Demonstrates errors that occur when a go.mod file exists but is missing the required 'module' directive. ```go // Missing module directive _, err := module.DetermineProjectName("", "/path/to/file") // go.mod exists but: UndefinedModuleError ``` -------------------------------- ### Analyzer Creation with Company Prefixes Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md Creates an analyzer that groups imports based on specified company or organization prefixes. ```go analyzer := goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "github.com/mycompany,github.com/myorg", // Creates separate group for company imports ) ``` -------------------------------- ### Handle Errors in module.DetermineProjectName Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Demonstrates error handling for module.DetermineProjectName, including cases for missing path, undefined module, and unreadable go.mod. ```go name, err := module.DetermineProjectName("", filePath) if err != nil { switch err.(type) { case *module.PathIsNotSetError: log.Fatal("File path is required") case *module.UndefinedModuleError: log.Fatal("Module is not defined in go.mod") default: log.Fatalf("Error: %v", err) } } ``` -------------------------------- ### Display Version Only Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md The -version-only flag provides a concise output, displaying only the version number without any additional build details. ```bash goimports-reviser -version-only # Output: 3.6.4 ``` -------------------------------- ### NewSourceFile Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/reviser.md Creates a new SourceFile instance for processing a single Go source file. It takes the project name and the file path as arguments. ```APIDOC ## NewSourceFile ### Description Creates a new `SourceFile` instance for processing a single Go source file. It takes the project name and the file path as arguments. ### Method ```go func NewSourceFile(projectName string, filePath string) *SourceFile ``` ### Parameters #### Path Parameters - **projectName** (string) - Required - Name of the Go module (e.g. `github.com/incu6us/goimports-reviser/v3`). Used to identify project-local imports. - **filePath** (string) - Required - Path to the Go source file to process. Use `` constant to read from stdin. ### Returns - **`*SourceFile`** - A configured file processor ready to accept options and be fixed. ### Example ```go package main import "github.com/incu6us/goimports-reviser/v3/reviser" func main() { file := reviser.NewSourceFile( "github.com/mycompany/myproject", "./main.go", ) formatted, original, changed, err := file.Fix( reviser.WithRemovingUnusedImports, reviser.WithCodeFormatting, ) if err != nil { panic(err) } println("File changed:", changed) } ``` ``` -------------------------------- ### Go Module Utilities Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/README.md Utilities for interacting with Go modules, including reading module names, finding the project root, and determining the project name. ```APIDOC ## Go Module Utilities ### Description Utilities for working with Go module files (`go.mod`) to identify project structure and names. ### Functions - `Name()`: Read the module name directly from the `go.mod` file. - `GoModRootPath()`: Find the root directory of the Go module project. - `DetermineProjectName()`: Auto-detect or verify the project's module name. ### Error Types - `UndefinedModuleError`: Indicates that a module could not be identified. - `PathIsNotSetError`: Signifies that a required path is not set. ``` -------------------------------- ### Process Project Using ./... Pattern Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Utilize the ./... pattern for recursive processing of the project, combined with options to remove unused imports, set aliases, and format code. ```bash # Using ./... pattern (recursive by default) goimports-reviser -rm-unused -set-alias -format ./... ``` -------------------------------- ### Read from Standard Input Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Pipe Go code into goimports-reviser to format it. The output will be printed to standard output. ```bash # Read from stdin echo "package main; import \"fmt\"" | goimports-reviser - # The tool will print formatted output to stdout ``` -------------------------------- ### Basic Module Detection Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/module.md Detects the Go module name from the current directory. Ensure you are in the project directory. ```go package main import ( "fmt" "log" "github.com/incu6us/goimports-reviser/v3/pkg/module" ) func main() { // Detect module name from current directory name, err := module.DetermineProjectName("", ".") if err != nil { log.Fatal(err) } fmt.Printf("Module: %s\n", name) } ``` -------------------------------- ### Handle File Not Found Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Illustrates how to handle 'file not found' errors when using NewSourceFile and Fix. Ensure the file path is correct and the file exists. ```go // Most common: file not found file := reviser.NewSourceFile("project", "./nonexistent.go") _, _, _, err := file.Fix() // err will be: open ./nonexistent.go: no such file or directory ``` -------------------------------- ### Testing Analyzer with Analysistest Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md Sets up and runs the goimports-reviser analyzer using the standard Go analysistest package for testing purposes. ```go import ( "testing" "golang.org/x/tools/go/analysis/analysistest" "github.com/incu6us/goimports-reviser/v3/pkg/goanalysis" ) func TestAnalyzer(t *testing.T) { analyzer := goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "", ) testdata := analysistest.TestData() analysistest.Run(t, testdata, analyzer, "test_package") } ``` -------------------------------- ### Company Imports with Custom Prefixes Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Configure custom company prefixes for import separation and process the project recursively. ```bash # With company package separation goimports-reviser -company-prefixes github.com/mycompany,mycompany.com -recursive ./... ``` -------------------------------- ### Apply Multiple File Options Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/file-options.md Applies a combination of file processing options, including removing unused imports, using aliases for version suffixes, code formatting, company package prefixes, and separating named imports. ```go file := reviser.NewSourceFile("github.com/mycompany/myproject", "./main.go") formatted, _, changed, err := file.Fix( reviser.WithRemovingUnusedImports, reviser.WithUsingAliasForVersionSuffix, reviser.WithCodeFormatting, reviser.WithCompanyPackagePrefixes("github.com/mycompany"), reviser.WithSeparatedNamedImports, ) ``` -------------------------------- ### Create Go Analysis Analyzer Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md Creates a new Go static analysis analyzer for goimports-reviser. Configure it with a flag set, company package prefixes, and optional reviser options. ```go package main import ( "flag" "golang.org/x/tools/go/analysis/analysistest" "github.com/incu6us/goimports-reviser/v3/pkg/goanalysis" "github.com/incu6us/goimports-reviser/v3/reviser" ) func main() { analyzer := goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "github.com/mycompany", reviser.WithRemovingUnusedImports, reviser.WithCodeFormatting, ) // Use with analysistest testdata := analysistest.TestData() analysistest.Run(t, testdata, analyzer, "a") } ``` -------------------------------- ### Stdin Processing with Project Name Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md When using standard input with the current directory, specify the project name using the -project-name flag or ensure a go.mod file is present. ```bash # When using stdin with current directory goimports-reviser -project-name github.com/myproject - < input.go # Or rely on go.mod detection cd /path/to/project echo "package main" | goimports-reviser - ``` -------------------------------- ### Use -company-prefixes flag Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md The recommended way to specify local import prefixes using the -company-prefixes flag. ```bash goimports-reviser -company-prefixes github.com/mycompany ``` -------------------------------- ### Run goimports-reviser on a file Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Basic command to run goimports-reviser on a specific Go file. ```bash goimports-reviser ./main.go ``` -------------------------------- ### Run goimports-reviser with options Source: https://github.com/incu6us/goimports-reviser/blob/master/README.md This command applies the goimports-reviser tool with options to remove unused imports, set aliases, and format the code for a specific file. ```bash goimports-reviser -rm-unused -set-alias -format ./reviser/reviser.go ``` -------------------------------- ### Custom Import Order with Company Imports Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Define a specific order for imports, including standard, general, company, project, blanked, and dotted imports, while specifying company prefixes. ```bash # Custom import order with company imports goimports-reviser -company-prefixes github.com/mycompany \ -imports-order std,general,company,project,blanked,dotted \ ./... ``` -------------------------------- ### AST Utilities Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/README.md Provides utilities for Abstract Syntax Tree (AST) analysis, including detecting import usage, loading package dependencies, and parsing build tags. ```APIDOC ## AST Utilities ### Description Utilities for Abstract Syntax Tree (AST) analysis to understand Go code structure and dependencies. ### Types - `PackageImports`: A type for mapping package dependencies. ### Functions - `UsesImport()`: Detect if a specific import path is used within the code. - `LoadPackageDependencies()`: Load all package dependencies using `go list`. - `ParseBuildTag()`: Extract build constraints (build tags) from source files. ### Examples Complete AST traversal examples are available. ``` -------------------------------- ### Basic Analyzer Creation Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md Creates a basic goimports-reviser analyzer without any specific company prefixes or additional options. ```go import ( "flag" "github.com/incu6us/goimports-reviser/v3/pkg/goanalysis" ) func createAnalyzer() *analysis.Analyzer { return goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "", // no additional options ) } ``` -------------------------------- ### Group Company Packages with Prefix Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/file-options.md Use this option to specify company package prefixes, which will be grouped separately between third-party and project-local imports. Provide a comma-separated string of prefixes. ```go // Before: import ( "fmt" "golang.org/x/exp/slices" "github.com/incu6us/goimports-reviser/pkg" "myproject/internal/lib" ) // After with WithCompanyPackagePrefixes("github.com/incu6us"): import ( "fmt" "golang.org/x/exp/slices" "github.com/incu6us/goimports-reviser/pkg" "myproject/internal/lib" ) ``` -------------------------------- ### Handle File Outside Go Module Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md Illustrates errors when trying to determine the project name for a file that is not part of any Go module. ```go // File outside any Go module _, err := module.DetermineProjectName("", "/tmp/random/file.go") // err: module not found (empty string returned from GoModRootPath) ``` -------------------------------- ### Handle Project Name Determination Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/errors.md This snippet shows how to handle errors when determining the project name using helper.DetermineProjectName. Ensure necessary options like OSGetwdOption are correctly passed. ```go name, err := helper.DetermineProjectName( projectNameFlag, filePath, helper.OSGetwdOption, ) if err != nil { log.Fatalf("Could not determine project name: %v", err) } ``` -------------------------------- ### Golangci-lint Plugin Creation Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/goanalysis.md Creates a golangci-lint compatible linter plugin using the goimports-reviser analyzer. Includes basic configuration for removing unused imports. ```go package main import ( "flag" "golang.org/x/tools/go/analysis" "github.com/incu6us/goimports-reviser/v3/pkg/goanalysis" "github.com/incu6us/goimports-reviser/v3/reviser" ) // NewPlugin creates a golangci-lint compatible linter plugin func New(conf any) ([]*analysis.Analyzer, error) { analyzer := goanalysis.NewAnalyzer( flag.NewFlagSet("", flag.ContinueOnError), "", reviser.WithRemovingUnusedImports, ) return []*analysis.Analyzer{analyzer}, nil } ``` -------------------------------- ### Enable Additional Go Code Formatting Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/configuration.md Use the -format flag to apply extra Go code formatting beyond import sorting. This includes adding blank lines between functions, normalizing comments, and applying standard Go formatting rules, similar to running `gofmt`. ```bash goimports-reviser -format ./main.go ``` -------------------------------- ### Handling Module Errors Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/types.md Illustrates how to handle potential errors returned by module.DetermineProjectName, specifically checking for PathIsNotSetError and UndefinedModuleError. ```go _, err := module.DetermineProjectName("", "") switch err.(type) { case *module.PathIsNotSetError: fmt.Println("Path is required") case *module.UndefinedModuleError: fmt.Println("Module is not defined in go.mod") default: fmt.Printf("Other error: %v\n", err) } ``` -------------------------------- ### Finding Project Root and Module Name Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/module.md Finds the Go module root path and then reads the module name from the go.mod file. Handles cases where the path is not part of a Go project. ```go func findProjectRoot(anyPathInProject string) string { rootPath, _ := module.GoModRootPath(anyPathInProject) if rootPath == "" { fmt.Println("Not a Go project") return "" } // Now read the module name moduleName, err := module.Name(rootPath) if err != nil { fmt.Println("Failed to read module name:", err) return "" } fmt.Printf("Project root: %s, Module: %s\n", rootPath, moduleName) return rootPath } ``` -------------------------------- ### SourceFile.Fix Source: https://github.com/incu6us/goimports-reviser/blob/master/_autodocs/api-reference/reviser.md Parses a Go file, applies configured options, sorts imports into groups, and returns the formatted content along with change status. ```APIDOC ## Fix ### Description Parses the file, applies all configured options, sorts imports into groups, and returns the formatted content. ### Method ```go func (f *SourceFile) Fix(options ...SourceFileOption) ([]byte, []byte, bool, error) ``` ### Parameters #### Path Parameters - **options** (...SourceFileOption) - Optional - Variadic slice of option functions that configure the file processor. ### Returns - **`[]byte`** - The formatted Go source code with properly sorted imports - **`[]byte`** - The original file content (unchanged) - **`bool`** - `true` if the formatted content differs from the original - **`error`** - Non-nil if parsing or processing fails ### Errors Raised - File parsing errors if the Go source is invalid - File I/O errors if reading from disk or stdin fails - Option application errors if an option function fails ### Example ```go file := reviser.NewSourceFile("myproject", "./pkg/handler.go") formatted, original, hasChanged, err := file.Fix( reviser.WithRemovingUnusedImports, reviser.WithUsingAliasForVersionSuffix, reviser.WithCodeFormatting, reviser.WithCompanyPackagePrefixes("mycompany.com"), reviser.WithImportsOrder([]reviser.ImportsOrder{ reviser.StdImportsOrder, reviser.GeneralImportsOrder, reviser.CompanyImportsOrder, reviser.ProjectImportsOrder, }), ) if err != nil { log.Fatalf("Failed to fix imports: %v", err) } if hasChanged { fmt.Printf("Imports were reformatted\n") // formatted now contains the sorted imports } ``` ```