This commit is contained in:
Jesse Duffield 2020-04-10 15:18:30 +10:00
parent 8525b7618c
commit 251d760579
13 changed files with 154 additions and 67 deletions

View File

@ -1,7 +1,6 @@
package app
import (
"errors"
"io"
"io/ioutil"
"os"
@ -105,10 +104,6 @@ func NewApp(config config.AppConfigurer) (*App, error) {
return app, err
}
if err := app.setupPackage(); err != nil {
return app, err
}
app.NpmManager, err = commands.NewNpmManager(app.Log, app.OSCommand, app.Tr, app.Config)
if err != nil {
return app, err
@ -121,33 +116,6 @@ func NewApp(config config.AppConfigurer) (*App, error) {
return app, nil
}
func (app *App) setupPackage() error {
// ensure we have a package.json file here or in an ancestor directory
// if there's not, pick the first one from state or return an error
dir, err := os.Getwd()
if err != nil {
return err
}
for {
if commands.FileExists("package.json") {
return nil
}
if err := os.Chdir(".."); err != nil {
return err
}
newDir, err := os.Getwd()
if err != nil {
return err
}
if newDir == dir {
return errors.New("must start lazynpm in an npm package")
}
dir = newDir
}
}
func (app *App) Run() error {
err := app.Gui.RunWithSubprocesses()
return err

View File

@ -0,0 +1,6 @@
package commands
type Dependency struct {
Name string
Version string
}

View File

@ -146,3 +146,28 @@ func (m *NpmManager) GetPackages(paths []string) ([]*Package, error) {
}
return pkgs, nil
}
func (m *NpmManager) ChdirToPackageRoot() (bool, error) {
dir, err := os.Getwd()
if err != nil {
return false, err
}
for {
if FileExists("package.json") {
return true, nil
}
if err := os.Chdir(".."); err != nil {
return false, err
}
newDir, err := os.Getwd()
if err != nil {
return false, err
}
if newDir == dir {
return false, nil
}
dir = newDir
}
}

View File

@ -1,8 +1,10 @@
package commands
import "encoding/json"
// golang doesn't support union types, but fields like 'author' and 'repository' can actually be strings or objects so we'll need to keep that in mind when parsing
import (
"encoding/json"
"sort"
"strings"
)
type PackageConfigInput struct {
Name string `json:"name"`
@ -88,3 +90,21 @@ type PackageConfig struct {
OptionalDependencies map[string]string
BundleDependencies bool
}
func (p *Package) SortedDeps() []*Dependency {
deps := make([]*Dependency, 0, len(p.Config.Dependencies))
for name, version := range p.Config.Dependencies {
deps = append(deps, &Dependency{Name: name, Version: version})
}
sort.Slice(deps, func(i, j int) bool { return strings.Compare(deps[i].Name, deps[j].Name) > 0 })
return deps
}
func (p *Package) SortedScripts() []*Script {
scripts := make([]*Script, 0, len(p.Config.Scripts))
for name, command := range p.Config.Scripts {
scripts = append(scripts, &Script{Name: name, Command: command})
}
sort.Slice(scripts, func(i, j int) bool { return strings.Compare(scripts[i].Name, scripts[j].Name) > 0 })
return scripts
}

6
pkg/commands/script.go Normal file
View File

@ -0,0 +1,6 @@
package commands
type Script struct {
Name string
Command string
}

View File

@ -40,8 +40,8 @@ type AppConfigurer interface {
WriteToUserConfig(string, interface{}) error
SaveAppState() error
LoadAppState() error
SetIsNewRepo(bool)
GetIsNewRepo() bool
SetIsNewPackage(bool)
GetIsNewPackage() bool
}
// NewAppConfig makes a new app config
@ -75,13 +75,13 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg
return appConfig, nil
}
// GetIsNewRepo returns known repo boolean
func (c *AppConfig) GetIsNewRepo() bool {
// GetIsNewPackage returns known repo boolean
func (c *AppConfig) GetIsNewPackage() bool {
return c.IsNewPackage
}
// SetIsNewRepo set if the current repo is known
func (c *AppConfig) SetIsNewRepo(isNew bool) {
// SetIsNewPackage set if the current repo is known
func (c *AppConfig) SetIsNewPackage(isNew bool) {
c.IsNewPackage = isNew
}

View File

@ -134,6 +134,7 @@ type guiState struct {
PrevMainHeight int
OldInformation string
StartupStage int // one of INITIAL and COMPLETE. Allows us to not load everything at once
CurrentPackageIdx int
}
func (gui *Gui) resetState() {
@ -306,16 +307,28 @@ func (gui *Gui) loadNewRepo() error {
// so that appears in the packages view next time we open the program in another package
func (gui *Gui) updateRecentRepoList() error {
recentPackages := gui.Config.GetAppState().RecentPackages
currentRepo, err := os.Getwd()
ok, err := gui.NpmManager.ChdirToPackageRoot()
if err != nil {
return err
}
isNew, recentPackages := newRecentPackagesList(recentPackages, currentRepo)
gui.Config.SetIsNewRepo(isNew)
if ok {
currentPackagePath, err := os.Getwd()
if err != nil {
return err
}
isNew, recentPackages := newRecentPackagesList(recentPackages, currentPackagePath)
gui.Config.SetIsNewPackage(isNew)
gui.Config.GetAppState().RecentPackages = recentPackages
return gui.Config.SaveAppState()
}
if len(recentPackages) > 0 {
// TODO: ensure this actually contains a package.json file (meaning it won't be filtered out)
return os.Chdir(recentPackages[0])
}
return errors.New("Must open lazynpm in an npm package")
}
// newRecentPackagesList returns a new repo list with a new entry but only when it doesn't exist yet
func newRecentPackagesList(recentPackages []string, currentPackage string) (bool, []string) {
isNew := true

View File

@ -27,18 +27,23 @@ func (lv *listView) handleLineChange(change int) error {
return nil
}
view, err := lv.gui.g.View(lv.viewName)
if err != nil {
return err
}
lv.gui.changeSelectedLine(lv.getSelectedLineIdxPtr(), lv.getItemsLength(), change)
view.FocusPoint(0, *lv.getSelectedLineIdxPtr())
if lv.rendersToMainView {
if err := lv.gui.resetOrigin(lv.gui.getMainView()); err != nil {
return err
}
}
view, err := lv.gui.g.View(lv.viewName)
if err != nil {
if err := lv.gui.resetOrigin(lv.gui.getSecondaryView()); err != nil {
return err
}
}
return lv.handleItemSelect(lv.gui.g, view)
}
@ -95,6 +100,9 @@ func (lv *listView) handleClick(g *gocui.Gui, v *gocui.View) error {
if err := lv.gui.resetOrigin(lv.gui.getMainView()); err != nil {
return err
}
if err := lv.gui.resetOrigin(lv.gui.getSecondaryView()); err != nil {
return err
}
}
prevViewName := lv.gui.currentViewName()

View File

@ -16,25 +16,11 @@ func (gui *Gui) getSelectedPackage() *commands.Package {
}
func (gui *Gui) handlePackageSelect(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (gui *Gui) selectPackage() error {
gui.getPackagesView().FocusPoint(0, gui.State.Panels.Packages.SelectedLine)
pkg := gui.getSelectedPackage()
if pkg == nil {
gui.getMainView().Title = ""
return gui.newStringTask("main", gui.Tr.SLocalize("NoChangedPackages"))
}
if err := gui.resetOrigin(gui.getMainView()); err != nil {
return err
}
if err := gui.resetOrigin(gui.getSecondaryView()); err != nil {
return err
}
return nil
}
@ -51,12 +37,25 @@ func (gui *Gui) refreshPackages() error {
gui.g.Update(func(g *gocui.Gui) error {
displayStrings := presentation.GetPackageListDisplayStrings(gui.State.Packages)
gui.renderDisplayStrings(packagesView, displayStrings)
displayStrings = presentation.GetDependencyListDisplayStrings(gui.currentPackage().SortedDeps())
gui.renderDisplayStrings(gui.getDepsView(), displayStrings)
displayStrings = presentation.GetScriptListDisplayStrings(gui.currentPackage().SortedScripts())
gui.renderDisplayStrings(gui.getScriptsView(), displayStrings)
return nil
})
return nil
}
func (gui *Gui) currentPackage() *commands.Package {
if len(gui.State.Packages) == 0 {
panic("need at least one package")
}
return gui.State.Packages[0]
}
// specific functions
func (gui *Gui) refreshStatePackages() error {

View File

@ -0,0 +1,19 @@
package presentation
import (
"github.com/jesseduffield/lazynpm/pkg/commands"
)
func GetDependencyListDisplayStrings(dependencies []*commands.Dependency) [][]string {
lines := make([][]string, len(dependencies))
for i := range dependencies {
lines[i] = getDepDisplayStrings(dependencies[i])
}
return lines
}
func getDepDisplayStrings(p *commands.Dependency) []string {
return []string{p.Name, p.Version}
}

View File

@ -11,13 +11,13 @@ func GetPackageListDisplayStrings(packages []*commands.Package) [][]string {
lines := make([][]string, len(packages))
for i := range packages {
lines[i] = getFileDisplayStrings(packages[i])
lines[i] = getPackageDisplayStrings(packages[i])
}
return lines
}
func getFileDisplayStrings(p *commands.Package) []string {
func getPackageDisplayStrings(p *commands.Package) []string {
line := utils.ColoredString(p.Config.Name, theme.DefaultTextColor)
if p.Linked {
line += utils.ColoredString(" (linked)", color.FgCyan)

View File

@ -0,0 +1,19 @@
package presentation
import (
"github.com/jesseduffield/lazynpm/pkg/commands"
)
func GetScriptListDisplayStrings(scripts []*commands.Script) [][]string {
lines := make([][]string, len(scripts))
for i := range scripts {
lines[i] = getScriptDisplayStrings(scripts[i])
}
return lines
}
func getScriptDisplayStrings(p *commands.Script) []string {
return []string{p.Name, p.Command}
}

View File

@ -10,7 +10,7 @@ import (
"github.com/spkg/bom"
)
var cyclableViews = []string{"status", "packages", "depdencies", "scripts"}
var cyclableViews = []string{"status", "packages", "deps", "scripts"}
func intArrToMap(arr []int) map[int]bool {
output := map[int]bool{}
@ -97,6 +97,10 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
return gui.handleStatusSelect(g, v)
case "packages":
return gui.handlePackageSelect(g, v)
case "deps":
return gui.handlePackageSelect(g, v)
case "scripts":
return gui.handlePackageSelect(g, v)
case "main":
v.Highlight = false
return nil