mirror of
https://github.com/jesseduffield/lazynpm.git
synced 2026-01-09 06:21:11 +08:00
WIP
This commit is contained in:
parent
8525b7618c
commit
251d760579
@ -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
|
||||
|
||||
6
pkg/commands/dependency.go
Normal file
6
pkg/commands/dependency.go
Normal file
@ -0,0 +1,6 @@
|
||||
package commands
|
||||
|
||||
type Dependency struct {
|
||||
Name string
|
||||
Version string
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
6
pkg/commands/script.go
Normal file
@ -0,0 +1,6 @@
|
||||
package commands
|
||||
|
||||
type Script struct {
|
||||
Name string
|
||||
Command string
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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 {
|
||||
|
||||
19
pkg/gui/presentation/dependencies.go
Normal file
19
pkg/gui/presentation/dependencies.go
Normal 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}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
19
pkg/gui/presentation/scripts.go
Normal file
19
pkg/gui/presentation/scripts.go
Normal 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}
|
||||
}
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user