Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new pathctl command #18

Merged
merged 1 commit into from
Dec 12, 2023
Merged

new pathctl command #18

merged 1 commit into from
Dec 12, 2023

Conversation

alessio
Copy link
Owner

@alessio alessio commented Dec 12, 2023

Summary by CodeRabbit

  • New Features

    • Introduced a new version-stamp build target for enhanced version tracking.
    • Added new build targets unixtools.pkg and unixtools.dmg for macOS packaging and disk image creation.
    • Implemented new command-line functions in pathctl for managing the PATH environment variable, including listing, prepending, appending, and dropping paths.
  • Bug Fixes

    • Adjusted build dependencies to ensure proper build sequence and code signing in the Makefile.
  • Documentation

    • Updated usage information to reflect new command-line options in pathctl.
  • Refactor

    • Streamlined PATH management with a new List interface and dirList type in the path package.
    • Removed redundant code and imports to improve maintainability.
  • Tests

    • Modified test cases to align with the updated logic in PATH management functions.

Copy link
Contributor

coderabbitai bot commented Dec 12, 2023

Walkthrough

Walkthrough

The project has undergone a significant update, with changes to the build process and enhancements to a Go program for managing the PATH environment variable. The Makefile now includes new dependencies and targets for building and signing packages. In the Go codebase, new functions for listing, appending, and removing paths have been added, along with a new interface and type for handling directory lists. Tests have been updated to reflect these changes, and some redundant code has been removed.

Changes

File(s) Summary
Makefile Added generate dependency to all and build targets; added version-stamp, unixtools.pkg, and unixtools.dmg targets; removed generate from $(BUILD_TARGETS) rule; updated macos-codesign rule.
cmd/.../main.go Added functions for PATH manipulation (list, prepend, drop, appendPath); modified main to handle new commands; added help and version functions.
internal/path/dirlist.go Introduced List interface with methods for directory list management.
internal/path/list.go Created dirList type with methods; added NewPathList function and ListSeparator variable.
internal/path/list_test.go Updated test cases for PathList methods to align with new logic.
internal/path/path.go Removed normalizePath function and "path" package import.

🐇✨
Changes abound, the code does hop,
Paths now twist and turn, nonstop.
Build and sign, with targets new,
A rabbit's touch, in every queue. 🌟📦

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on X ?


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

@codecov-commenter
Copy link

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (58b5732) 70.00% compared to head (b7ee070) 75.00%.

Files Patch % Lines
internal/path/list.go 92.85% 2 Missing and 1 partial ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #18      +/-   ##
==========================================
+ Coverage   70.00%   75.00%   +5.00%     
==========================================
  Files           3        4       +1     
  Lines         140      180      +40     
==========================================
+ Hits           98      135      +37     
- Misses         27       29       +2     
- Partials       15       16       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alessio alessio merged commit 5cceb45 into main Dec 12, 2023
2 checks passed
@alessio alessio deleted the alessio/buildpkg branch December 12, 2023 03:32
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 4

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 58b5732 and b7ee070.
Files ignored due to filter (2)
  • go.mod
  • go.sum
Files selected for processing (6)
  • Makefile (2 hunks)
  • cmd/pathctl/main.go (1 hunks)
  • internal/path/dirlist.go (1 hunks)
  • internal/path/list.go (1 hunks)
  • internal/path/list_test.go (1 hunks)
  • internal/path/path.go (2 hunks)
Files skipped from review due to trivial changes (1)
  • internal/path/path.go
Additional comments: 18
Makefile (6)
  • 34-34: The addition of generate as a prerequisite for the all target ensures that generated code is up to date before building or checking the code.

  • 38-38: The explicit dependency of build on generate is a good practice to ensure that the build process uses the latest generated code.

  • 73-74: The new version-stamp target is a good addition for handling versioning and correctly depends on generate.

  • 79-80: The update to the macos-codesign rule to sign all binaries in the $(BUILDDIR) directory is a security best practice for macOS applications.

  • 82-93: The addition of unixtools.pkg and unixtools.dmg targets for macOS packaging is well-structured, with appropriate dependencies on version-stamp and macos-codesign.

  • 71-71: The update to the clean target to remove generate-stamp and version-stamp ensures that all artifacts from code generation and versioning are cleaned up.

cmd/pathctl/main.go (7)
  • 78-81:
    The list function implementation is straightforward and correctly iterates over the paths to print them.

  • 84-88:
    The prepend function checks for the existence of the path before adding it, which is good practice to avoid duplicates.

  • 91-94:
    The drop function also checks for the existence of the path before attempting to remove it, which is a good safety measure.

  • 97-100:
    The appendPath function is consistent with the prepend and drop functions in terms of checking for the existence of the path.

  • 103-112:
    The handleHelpAndVersionModes function correctly handles the help and version modes, exiting the program after displaying the relevant information.

  • 115-137:
    The usage function provides clear and concise information about the commands and options available to the user.

  • 139-146:
    The exePath function retrieves the directory of the executable and handles errors appropriately by logging and exiting.

internal/path/list.go (4)
  • 12-79: The implementation of the dirList struct and its methods Prepend, Append, and Drop correctly handle the addition and removal of paths, including path normalization. The use of slices.Index ensures that duplicate paths are not added. The normalizePath function is used consistently to clean paths, which aligns with the removal of the old normalizePath function from path.go.

  • 62-79: The makePathList function correctly processes the PATH string into a clean list of paths, with each path being normalized by the normalizePath function.

  • 20-21: The NewPathList function properly retrieves the environment variable value using os.Getenv and creates a new dirList instance with the cleaned paths.

  • 10-10: The ListSeparator variable is correctly set to os.PathListSeparator, ensuring platform-independent path list separation.

internal/path/list_test.go (1)
  • 1-54: The tests for the Prepend, Append, and Drop methods in list_test.go are well-structured and cover a variety of cases, including idempotency and normalization. The use of t.Setenv to set environment variables for the tests is appropriate, and the generation of unique environment variable names using fmt.Sprintf("TEST_%s", t.Name()) is a good practice to avoid collisions. The tests thoroughly check both the string and slice representations of the path list, ensuring that the functionality is working as expected. Overall, the tests appear to be comprehensive and correctly implemented.


// List handles a list of directories in a predictable way.
type List interface {
String() interface{} //
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The String() method in the List interface should return a string type instead of interface{} for clarity and consistency with typical string conversion methods.

- String() interface{} //
+ String() string

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
String() interface{} //
String() string

Comment on lines +24 to +25
func (p *dirList) String() interface{} {
return strings.Join(p.lst, ListSeparator)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The String method of dirList should return a string type instead of interface{} to match its intended usage.

- func (p *dirList) String() interface{} {
+ func (p *dirList) String() string {

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (p *dirList) String() interface{} {
return strings.Join(p.lst, ListSeparator)
func (p *dirList) String() string {
return strings.Join(p.lst, ListSeparator)

Comment on lines +38 to +76
func main() {
log.SetFlags(0)
log.SetPrefix(fmt.Sprintf("%s: ", progName))
log.SetOutput(os.Stderr)
flag.Parse()

handleHelpAndVersionModes()

paths = path.NewPathList(envVar)

if flag.NArg() < 1 {
list()
os.Exit(0)
}

if flag.NArg() == 1 {
switch flag.Arg(0) {
case "list", "l":
list()
case "appendPathctlDir", "apd":
appendPath(exePath())
case "prependPathctlDir", "ppd":
prepend(exePath())
default:
log.Fatalf("unrecognized command: %s", flag.Arg(0))
}
} else {
switch flag.Arg(0) {
case "prepend", "p":
prepend(flag.Arg(1))
case "drop", "d":
drop(flag.Arg(1))
case "append", "a":
appendPath(flag.Arg(1))
}
}

fmt.Println(paths.String())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main function could be refactored to improve readability and maintainability. The current implementation has nested if and switch statements, which can be simplified by breaking down the command handling into separate functions or by using a map of functions indexed by command names.

// Example of a possible refactoring using a map of functions:
var commandHandlers = map[string]func(){
	"list": func() { list() },
	"appendPathctlDir": func() { appendPath(exePath()) },
	"prependPathctlDir": func() { prepend(exePath()) },
	"prepend": func() { prepend(flag.Arg(1)) },
	"drop": func() { drop(flag.Arg(1)) },
	"append": func() { appendPath(flag.Arg(1)) },
}

func main() {
	// ... existing code ...

	if handler, ok := commandHandlers[flag.Arg(0)]; ok {
		handler()
	} else {
		log.Fatalf("unrecognized command: %s", flag.Arg(0))
	}

	fmt.Println(paths.String())
}

This approach would make it easier to add or modify commands in the future and would make the main function more concise.


func prepend(p string) {
//oldPath := pathEnvvar
if ok := paths.Prepend(p); !ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error messages in the prepend, drop, and appendPath functions are all the same and could be more descriptive. It would be beneficial to include the command that failed and the path that was attempted to be modified for better user feedback.

- log.Println("the path already exists")
+ log.Printf("failed to %s: the path '%s' already exists", <command>, p)

Replace <command> with the appropriate operation (e.g., "prepend", "drop", "append") to provide more context in the error message.

Also applies to: 92-92, 98-98


Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
if ok := paths.Prepend(p); !ok {
if ok := paths.Prepend(p); !ok {
log.Printf("failed to prepend: the path '%s' already exists", p)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants