diff --git a/pkg/commands/dependency.go b/pkg/commands/dependency.go index 35de695..6be109d 100644 --- a/pkg/commands/dependency.go +++ b/pkg/commands/dependency.go @@ -1,13 +1,20 @@ package commands +import "path/filepath" + type Dependency struct { Name string Version string LinkPath string Present bool PackageConfig *PackageConfig + Path string } func (d *Dependency) Linked() bool { return d.LinkPath != "" } + +func (d *Dependency) ConfigPath() string { + return filepath.Join(d.Path, "package.json") +} diff --git a/pkg/commands/npm_manager.go b/pkg/commands/npm_manager.go index 51a66f6..7ddcbac 100644 --- a/pkg/commands/npm_manager.go +++ b/pkg/commands/npm_manager.go @@ -1,10 +1,12 @@ package commands import ( + "io/ioutil" "os" "path/filepath" "strings" + "github.com/buger/jsonparser" "github.com/jesseduffield/lazynpm/pkg/config" "github.com/jesseduffield/lazynpm/pkg/i18n" "github.com/sirupsen/logrus" @@ -122,8 +124,9 @@ func (m *NpmManager) GetDeps(currentPkg *Package) ([]*Dependency, error) { deps := currentPkg.SortedDependencies() for _, dep := range deps { - nodeModulesPath := filepath.Join(currentPkg.Path, "node_modules", dep.Name) - fileInfo, err := os.Lstat(nodeModulesPath) + depPath := filepath.Join(currentPkg.Path, "node_modules", dep.Name) + dep.Path = depPath + fileInfo, err := os.Lstat(depPath) if err != nil { // must not be present in node modules m.Log.Error(err) @@ -132,7 +135,7 @@ func (m *NpmManager) GetDeps(currentPkg *Package) ([]*Dependency, error) { dep.Present = true // get the actual version of the package in node modules - packageConfigPath := filepath.Join(nodeModulesPath, "package.json") + packageConfigPath := filepath.Join(depPath, "package.json") file, err := os.OpenFile(packageConfigPath, os.O_RDONLY, 0644) if err != nil { m.Log.Error(err) @@ -151,7 +154,7 @@ func (m *NpmManager) GetDeps(currentPkg *Package) ([]*Dependency, error) { continue } - linkPath, err := filepath.EvalSymlinks(nodeModulesPath) + linkPath, err := filepath.EvalSymlinks(depPath) if err != nil { return nil, err } @@ -160,3 +163,14 @@ func (m *NpmManager) GetDeps(currentPkg *Package) ([]*Dependency, error) { return deps, nil } + +func (m *NpmManager) RemoveScript(scriptName string, packageJsonPath string) error { + config, err := ioutil.ReadFile(packageJsonPath) + if err != nil { + return err + } + + updatedConfig := jsonparser.Delete(config, "scripts", scriptName) + + return ioutil.WriteFile(packageJsonPath, updatedConfig, 0644) +} diff --git a/pkg/commands/package.go b/pkg/commands/package.go index 5db2c67..5707675 100644 --- a/pkg/commands/package.go +++ b/pkg/commands/package.go @@ -2,6 +2,7 @@ package commands import ( "fmt" + "path/filepath" "sort" "strings" ) @@ -111,3 +112,7 @@ func (p *Package) SortedScripts() []*Script { sort.Slice(scripts, func(i, j int) bool { return strings.Compare(scripts[i].Name, scripts[j].Name) < 0 }) return scripts } + +func (p *Package) ConfigPath() string { + return filepath.Join(p.Path, "package.json") +} diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index fb1ac41..c6ea963 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -184,5 +184,9 @@ func (gui *Gui) createErrorPanel(message string) error { } func (gui *Gui) surfaceError(err error) error { + if err == nil { + return nil + } + return gui.createErrorPanel(err.Error()) } diff --git a/pkg/gui/dependencies_panel.go b/pkg/gui/dependencies_panel.go index 6d7be89..d1f2875 100644 --- a/pkg/gui/dependencies_panel.go +++ b/pkg/gui/dependencies_panel.go @@ -2,7 +2,6 @@ package gui import ( "fmt" - "path/filepath" "github.com/fatih/color" "github.com/go-errors/errors" @@ -88,5 +87,5 @@ func (gui *Gui) handleOpenDepPackageConfig() error { return gui.surfaceError(errors.New("dependency not in node_modules")) } - return gui.openFile(filepath.Join("node_modules", selectedDep.Name, "package.json")) + return gui.openFile(selectedDep.ConfigPath()) } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 1aab4ed..44bd31e 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -489,6 +489,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.wrappedHandler(gui.handleRunScript), Description: "`npm run` script", }, + { + ViewName: "scripts", + Key: gui.getKey("universal.remove"), + Modifier: gocui.ModNone, + Handler: gui.wrappedHandler(gui.handleRemoveScript), + Description: "remove script from package.json", + }, { ViewName: "deps", Key: gui.getKey("universal.install"), diff --git a/pkg/gui/packages_panel.go b/pkg/gui/packages_panel.go index a39a762..8e57dbb 100644 --- a/pkg/gui/packages_panel.go +++ b/pkg/gui/packages_panel.go @@ -2,7 +2,6 @@ package gui import ( "fmt" - "path/filepath" "github.com/fatih/color" "github.com/go-errors/errors" @@ -111,13 +110,8 @@ func (gui *Gui) handleLinkPackage() error { return nil } - currentPkg := gui.currentPackage() - if currentPkg == nil { - return nil - } - var cmdStr string - if selectedPkg == currentPkg { + if selectedPkg == gui.currentPackage() { return gui.surfaceError(errors.New("Cannot link a package to itself")) } @@ -145,12 +139,7 @@ func (gui *Gui) handleGlobalLinkPackage() error { return nil } - currentPkg := gui.currentPackage() - if currentPkg == nil { - return nil - } - - if selectedPkg != currentPkg { + if selectedPkg != gui.currentPackage() { return gui.surfaceError(errors.New("You can only globally link the current package. Hit space on this package to make it the current package.")) } @@ -175,13 +164,8 @@ func (gui *Gui) handleInstall() error { return nil } - currentPkg := gui.currentPackage() - if currentPkg == nil { - return nil - } - var cmdStr string - if selectedPkg == currentPkg { + if selectedPkg == gui.currentPackage() { cmdStr = "npm install" } else { cmdStr = "npm install --prefix " + selectedPkg.Path @@ -200,13 +184,8 @@ func (gui *Gui) handleBuild() error { return nil } - currentPkg := gui.currentPackage() - if currentPkg == nil { - return nil - } - var cmdStr string - if selectedPkg == currentPkg { + if selectedPkg == gui.currentPackage() { cmdStr = "npm run build" } else { cmdStr = "npm run build --prefix " + selectedPkg.Path @@ -225,7 +204,7 @@ func (gui *Gui) handleOpenPackageConfig() error { return nil } - return gui.openFile(filepath.Join(selectedPkg.Path, "package.json")) + return gui.openFile(selectedPkg.ConfigPath()) } func (gui *Gui) handleRemovePackage() error { diff --git a/pkg/gui/scripts_panel.go b/pkg/gui/scripts_panel.go index a0339ec..5beaf44 100644 --- a/pkg/gui/scripts_panel.go +++ b/pkg/gui/scripts_panel.go @@ -22,12 +22,7 @@ func (gui *Gui) getSelectedScript() *commands.Script { } func (gui *Gui) getScripts() []*commands.Script { - currentPackage := gui.currentPackage() - if currentPackage == nil { - return nil - } - - return currentPackage.SortedScripts() + return gui.currentPackage().SortedScripts() } func (gui *Gui) handleScriptSelect(g *gocui.Gui, v *gocui.View) error { @@ -52,3 +47,13 @@ func (gui *Gui) handleRunScript() error { return nil }) } + +func (gui *Gui) handleRemoveScript() error { + script := gui.getSelectedScript() + + return gui.createConfirmationPanel(gui.getScriptsView(), true, "Remove script", fmt.Sprintf("are you sure you want to remove script `%s`?", script.Name), func(g *gocui.Gui, v *gocui.View) error { + return gui.surfaceError( + gui.NpmManager.RemoveScript(script.Name, gui.currentPackage().ConfigPath()), + ) + }, nil) +}