aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2018-05-29 01:42:24 +0700
committerShulhan <ms@kilabit.info>2018-05-29 01:42:24 +0700
commitaf81fd7b43cd05ba06730329d4ba9f5933f933b5 (patch)
tree6b0b87a4c686cee618f70227572e1d63d02d976d
parent4ab8be448308d9970e0df05a04a6db8c2ba5b87f (diff)
downloadbeku-af81fd7b43cd05ba06730329d4ba9f5933f933b5.tar.xz
Add operation to exclude package from database
-rw-r--r--.gitignore1
-rw-r--r--README.md23
-rw-r--r--beku.go3
-rw-r--r--beku_test.go2
-rw-r--r--cmd/beku/command.go45
-rw-r--r--cmd/beku/main.go23
-rw-r--r--cmd/beku/operation.go2
-rw-r--r--env.go201
-rw-r--r--env_test.go183
-rw-r--r--package.go24
-rw-r--r--package_test.go3
11 files changed, 449 insertions, 61 deletions
diff --git a/.gitignore b/.gitignore
index 2b19e93..d20d245 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/testdata/beku.db.exclude
/testdata/beku.db.save
/testdata/a/b/file
/beku.test
diff --git a/README.md b/README.md
index 94ccb97..ada0dcf 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,29 @@ directory. If no file found, it will try to open
package database, beku will scan entire "$GOPATH/src" and write the
package database into "$GOPATH/var/beku/beku.db".
+
+## Database Operation
+
+ -D, --database
+
+Modify the package database. This operation required one of the options
+below.
+
+### Options
+
+ -e, --exclude <pkg ...>
+
+Remove list of package by import path from database and add mark it as
+excluded package. Excluded package will be ignored on future operations.
+
+### Examples
+
+ $ beku -De github.com/shuLhan/beku
+
+Exclude package "github.com/shuLhan/beku" from future scanning,
+installation, or removal.
+
+
## Freeze Operation
-B, --freeze
diff --git a/beku.go b/beku.go
index 5650617..ca8bdc5 100644
--- a/beku.go
+++ b/beku.go
@@ -55,6 +55,7 @@ var (
errDBPackageName = "missing package name, line %d at %s"
errDirNotEmpty = "directory %s is not empty"
+ errExcluded = "Package '%s' is in excluded list\n"
)
var (
@@ -67,10 +68,12 @@ var (
defStdout = os.Stdout
defStderr = os.Stderr
+ sectionBeku = "beku"
sectionPackage = "package"
keyDeps = "deps"
keyDepsMissing = "missing"
+ keyExclude = "exclude"
keyRemoteName = "remote-name"
keyRemoteURL = "remote-url"
keyRequiredBy = "required-by"
diff --git a/beku_test.go b/beku_test.go
index a56395a..b8e46d9 100644
--- a/beku_test.go
+++ b/beku_test.go
@@ -10,6 +10,8 @@ import (
)
const (
+ testDBLoad = "testdata/beku.db"
+ testDBSaveExclude = "testdata/beku.db.exclude"
testGitRepo = "github.com/shuLhan/beku_test"
testGitRepoVersion = "c9f69fb"
testGitRepoShare = "github.com/shuLhan/share"
diff --git a/cmd/beku/command.go b/cmd/beku/command.go
index d64c688..700117c 100644
--- a/cmd/beku/command.go
+++ b/cmd/beku/command.go
@@ -17,11 +17,12 @@ var (
)
const (
- flagOperationHelp = "Show the short usage."
- flagOperationFreeze = "Install all packages on database."
- flagOperationQuery = "Query the package database."
- flagOperationRemove = "Remove package."
- flagOperationSync = "Synchronize package. If no package is given, it will do rescan."
+ flagOperationHelp = "Show the short usage."
+ flagOperationDatabase = "Operate on the package database."
+ flagOperationFreeze = "Install all packages on database."
+ flagOperationQuery = "Query the package database."
+ flagOperationRemove = "Remove package."
+ flagOperationSync = "Synchronize package. If no package is given, it will do rescan."
flagOptionRecursive = "Remove package including their dependencies."
flagOptionSyncInto = "Download package into `directory`."
@@ -45,6 +46,9 @@ operations:
beku {-B|--freeze}
` + flagOperationFreeze + `
+ beku {-D|--database}
+ ` + flagOperationDatabase + `
+
beku {-Q|--query} [pkg ...]
` + flagOperationQuery + `
@@ -70,6 +74,19 @@ operations:
fmt.Fprint(os.Stderr, help)
}
+func (cmd *command) parseDatabaseFlags(arg string) (operation, error) {
+ if len(arg) == 0 {
+ return opNone, nil
+ }
+
+ switch arg[0] {
+ case 'e':
+ return opExclude, nil
+ }
+
+ return opNone, errInvalidOptions
+}
+
func (cmd *command) parseSyncFlags(arg string) (operation, error) {
if len(arg) == 0 {
return opNone, nil
@@ -125,6 +142,12 @@ func (cmd *command) parseShortFlags(arg string) (operation, error) {
if len(arg) > 1 {
return opNone, errInvalidOptions
}
+ case 'D':
+ op, err = cmd.parseDatabaseFlags(arg[1:])
+ if err != nil {
+ return opNone, err
+ }
+ op |= opDatabase
case 'Q':
op = opQuery
if len(arg) > 1 {
@@ -158,6 +181,10 @@ func (cmd *command) parseLongFlags(arg string) (op operation, err error) {
switch arg {
case "help":
op = opHelp
+ case "database":
+ op = opDatabase
+ case "exclude":
+ op = opExclude
case "freeze":
op = opFreeze
case "into":
@@ -235,7 +262,8 @@ func (cmd *command) parseFlags(args []string) (err error) {
return
}
}
- if cmd.op == opRecursive || cmd.op == opSyncInto || cmd.op == opUpdate {
+ if cmd.op == opExclude || cmd.op == opRecursive ||
+ cmd.op == opSyncInto || cmd.op == opUpdate {
return errInvalidOptions
}
if cmd.op&opSyncInto == opSyncInto {
@@ -245,8 +273,9 @@ func (cmd *command) parseFlags(args []string) (err error) {
}
// (1)
- op = cmd.op & (opFreeze | opQuery | opRemove | opSync)
- if op != opFreeze && op != opQuery && op != opRemove && op != opSync {
+ op = cmd.op & (opDatabase | opFreeze | opQuery | opRemove | opSync)
+ if op != opDatabase && op != opFreeze && op != opQuery &&
+ op != opRemove && op != opSync {
return errMultiOperations
}
diff --git a/cmd/beku/main.go b/cmd/beku/main.go
index 2d0190c..bbf6a28 100644
--- a/cmd/beku/main.go
+++ b/cmd/beku/main.go
@@ -23,6 +23,27 @@
// version on GOPATH. Also, all packages that are not registered will be
// removed from GOPATH "src" and "pkg" directories.
//
+// ## Database Operation
+//
+// -D, --database
+//
+// Modify the package database. This operation required one of the options
+// below.
+//
+// ### Options
+//
+// -e, --exclude <pkg ...>
+//
+// Remove list of package by import path from database and add mark it as
+// excluded package. Excluded package will be ignored on future operations.
+//
+// ### Examples
+//
+// $ beku -De github.com/shuLhan/beku
+//
+// Exclude package "github.com/shuLhan/beku" from future scanning,
+// installation, or removal.
+//
//
// ## Query Operation
//
@@ -153,6 +174,8 @@ func main() {
case opHelp:
cmd.usage()
os.Exit(1)
+ case opDatabase | opExclude:
+ cmd.env.Exclude(cmd.pkgs)
case opFreeze:
err = cmd.env.Freeze()
case opQuery:
diff --git a/cmd/beku/operation.go b/cmd/beku/operation.go
index 5925166..dc74ee9 100644
--- a/cmd/beku/operation.go
+++ b/cmd/beku/operation.go
@@ -6,6 +6,8 @@ const opNone operation = 0
const (
opHelp operation = 1 << iota
+ opDatabase
+ opExclude
opFreeze
opQuery
opRecursive
diff --git a/env.go b/env.go
index c8c5958..0495faa 100644
--- a/env.go
+++ b/env.go
@@ -31,6 +31,7 @@ type Env struct {
dirRootSrc string
dirSrc string
pkgs []*Package
+ pkgsExclude []string
pkgsMissing []string
pkgsStd []string
pkgsUnused []*Package
@@ -75,6 +76,25 @@ func NewEnvironment() (env *Env, err error) {
return
}
+//
+// addExclude will add package to list of excluded packages. It will return
+// true if importPath is not already exist in list; otherwise it will return
+// false.
+//
+func (env *Env) addExclude(importPath string) bool {
+ if len(importPath) == 0 {
+ return false
+ }
+ for x := 0; x < len(env.pkgsExclude); x++ {
+ if env.pkgsExclude[x] == importPath {
+ return false
+ }
+ }
+
+ env.pkgsExclude = append(env.pkgsExclude, importPath)
+ return true
+}
+
func (env *Env) cleanUnused() {
for _, pkg := range env.pkgsUnused {
fmt.Println(">>> Removing source at", pkg.FullPath)
@@ -89,6 +109,30 @@ func (env *Env) cleanUnused() {
}
//
+// Exclude mark list of packages to be excluded from future operations.
+//
+func (env *Env) Exclude(importPaths []string) {
+ exPkg := new(Package)
+
+ for _, exImportPath := range importPaths {
+ ok := env.addExclude(exImportPath)
+ if ok {
+ env.dirty = true
+ }
+
+ pkgIdx, pkg := env.GetPackageFromDB(exImportPath, "")
+ if pkg != nil {
+ env.removePkgFromDBByIdx(pkgIdx)
+ }
+
+ exPkg.ImportPath = exImportPath
+ env.updateMissing(exPkg, false)
+
+ env.removeRequiredBy(exImportPath)
+ }
+}
+
+//
// Freeze all packages in GOPATH. Install all registered packages in database
// and remove non-registered from GOPATH "src" and "pkg" directories.
//
@@ -182,24 +226,25 @@ func (env *Env) GetPackage(importPath string) (pkg *Package, err error) {
}
//
-// GetPackageFromDB will return installed package registered on database.
-// If no package found, it will return nil.
+// GetPackageFromDB will return index and pointer to package in database.
+// If no package found, it will return -1 and nil.
//
-func (env *Env) GetPackageFromDB(importPath, remoteURL string) *Package {
+func (env *Env) GetPackageFromDB(importPath, remoteURL string) (int, *Package) {
for x := 0; x < len(env.pkgs); x++ {
if importPath == env.pkgs[x].ImportPath {
- return env.pkgs[x]
+ return x, env.pkgs[x]
}
if remoteURL == env.pkgs[x].RemoteURL {
- return env.pkgs[x]
+ return x, env.pkgs[x]
}
}
- return nil
+ return -1, nil
}
//
-// GetUnused will get all non-registered packages from GOPATH "src".
+// GetUnused will get all non-registered packages from GOPATH "src", without
+// including all excluded packages.
//
func (env *Env) GetUnused(srcPath string) (err error) {
fis, err := ioutil.ReadDir(srcPath)
@@ -235,7 +280,11 @@ func (env *Env) GetUnused(srcPath string) (err error) {
importPath := strings.TrimPrefix(fullPath, env.dirSrc+"/")
- pkg := env.GetPackageFromDB(importPath, "")
+ if env.IsExcluded(importPath) {
+ continue
+ }
+
+ _, pkg := env.GetPackageFromDB(importPath, "")
if pkg != nil {
continue
}
@@ -255,6 +304,22 @@ func (env *Env) GetUnused(srcPath string) (err error) {
}
//
+// IsExcluded will return true if import path is registered as one of excluded
+// package; otherwise it will return false.
+//
+func (env *Env) IsExcluded(importPath string) bool {
+ if len(importPath) == 0 {
+ return true
+ }
+ for x := 0; x < len(env.pkgsExclude); x++ {
+ if env.pkgsExclude[x] == importPath {
+ return true
+ }
+ }
+ return false
+}
+
+//
// Scan will gather all package information in user system to start `beku`-ing.
//
func (env *Env) Scan() (err error) {
@@ -376,6 +441,10 @@ func (env *Env) scanPackages(srcPath string) (err error) {
func (env *Env) newPackage(fullPath string, vcsMode VCSMode) (err error) {
pkgName := strings.TrimPrefix(fullPath, env.dirSrc+"/")
+ if env.IsExcluded(pkgName) {
+ return
+ }
+
pkg := NewPackage(pkgName, pkgName, vcsMode)
if Debug >= DebugL2 {
@@ -391,7 +460,7 @@ func (env *Env) newPackage(fullPath string, vcsMode VCSMode) (err error) {
return fmt.Errorf("%s: %s", pkgName, err)
}
- curPkg := env.GetPackageFromDB(pkg.ImportPath, pkg.RemoteURL)
+ _, curPkg := env.GetPackageFromDB(pkg.ImportPath, pkg.RemoteURL)
if curPkg == nil {
env.pkgs = append(env.pkgs, pkg)
env.countNew++
@@ -455,12 +524,35 @@ func (env *Env) Load(file string) (err error) {
return
}
+ env.loadBeku()
+ env.loadPackages()
+
+ return
+}
+
+func (env *Env) loadBeku() {
+ secBeku := env.db.GetSection(sectionBeku, "")
+ if secBeku == nil {
+ return
+ }
+
+ for _, v := range secBeku.Vars {
+ if v.KeyLower == keyExclude {
+ env.addExclude(v.Value)
+ }
+ }
+}
+
+func (env *Env) loadPackages() {
sections := env.db.GetSections(sectionPackage)
for _, sec := range sections {
if len(sec.Sub) == 0 {
fmt.Fprintln(os.Stderr, errDBPackageName, sec.LineNum, env.dbFile)
continue
}
+ if env.IsExcluded(sec.Sub) {
+ continue
+ }
pkg := &Package{
ImportPath: sec.Sub,
@@ -472,8 +564,6 @@ func (env *Env) Load(file string) (err error) {
env.addPackage(pkg)
}
-
- return
}
//
@@ -490,6 +580,10 @@ func (env *Env) Query(pkgs []string) {
continue
}
for y := 0; y < len(pkgs); y++ {
+ if env.IsExcluded(pkgs[y]) {
+ continue
+ }
+
if env.pkgs[x].ImportPath == pkgs[y] {
fmt.Fprintf(defStdout, format,
env.pkgs[x].ImportPath,
@@ -564,7 +658,7 @@ func (env *Env) Rescan() (ok bool, err error) {
continue
}
pkg.state = packageStateDirty
- env.updateMissing(pkg)
+ env.updateMissing(pkg, true)
}
}
env.dirty = true
@@ -577,7 +671,12 @@ func (env *Env) Rescan() (ok bool, err error) {
// dependencies, as long as they are not required by other package.
//
func (env *Env) Remove(rmPkg string, recursive bool) (err error) {
- pkg := env.GetPackageFromDB(rmPkg, "")
+ if env.IsExcluded(rmPkg) {
+ fmt.Printf(errExcluded, rmPkg)
+ return
+ }
+
+ _, pkg := env.GetPackageFromDB(rmPkg, "")
if pkg == nil {
fmt.Println("Package", rmPkg, "not installed")
return
@@ -658,7 +757,7 @@ func (env *Env) filterUnusedDeps(pkg *Package, tobeRemoved map[string]bool) {
}
for x := 0; x < len(pkg.Deps); x++ {
- dep = env.GetPackageFromDB(pkg.Deps[x], "")
+ _, dep = env.GetPackageFromDB(pkg.Deps[x], "")
if len(dep.Deps) > 0 {
env.filterUnusedDeps(dep, tobeRemoved)
@@ -688,7 +787,7 @@ func (env *Env) filterUnusedDeps(pkg *Package, tobeRemoved map[string]bool) {
// or binary). This also remove in other packages "RequiredBy" if exist.
//
func (env *Env) removePackage(importPath string) (err error) {
- pkg := env.GetPackageFromDB(importPath, "")
+ pkgIdx, pkg := env.GetPackageFromDB(importPath, "")
if pkg == nil {
return
}
@@ -698,19 +797,17 @@ func (env *Env) removePackage(importPath string) (err error) {
return
}
- idx := -1
- for x := 0; x < len(env.pkgs); x++ {
- if env.pkgs[x].ImportPath == importPath {
- idx = x
- continue
- }
+ env.removeRequiredBy(importPath)
+ env.removePkgFromDBByIdx(pkgIdx)
- ok := env.pkgs[x].RemoveRequiredBy(importPath)
- if ok {
- env.dirty = true
- }
- }
+ return
+}
+//
+// removePkgFromDBByIdx remove package from database by package index in the
+// list.
+//
+func (env *Env) removePkgFromDBByIdx(idx int) {
if idx < 0 {
return
}
@@ -722,8 +819,18 @@ func (env *Env) removePackage(importPath string) (err error) {
env.pkgs = env.pkgs[:lenpkgs-1]
env.dirty = true
+}
- return
+//
+// removeRequiredBy will remove import path in package required-by.
+//
+func (env *Env) removeRequiredBy(importPath string) {
+ for x := 0; x < len(env.pkgs); x++ {
+ ok := env.pkgs[x].RemoveRequiredBy(importPath)
+ if ok {
+ env.dirty = true
+ }
+ }
}
//
@@ -759,6 +866,26 @@ func (env *Env) Save(file string) (err error) {
env.db = &ini.Ini{}
+ env.saveBeku()
+ env.savePackages()
+
+ err = env.db.Save(file)
+
+ return
+}
+
+func (env *Env) saveBeku() {
+ secBeku := ini.NewSection(sectionBeku, "")
+
+ for _, exclude := range env.pkgsExclude {
+ secBeku.Add(keyExclude, exclude)
+ }
+
+ secBeku.AddNewLine()
+ env.db.AddSection(secBeku)
+}
+
+func (env *Env) savePackages() {
for _, pkg := range env.pkgs {
sec := ini.NewSection(sectionPackage, pkg.ImportPath)
@@ -785,10 +912,6 @@ func (env *Env) Save(file string) (err error) {
env.db.AddSection(sec)
}
-
- err = env.db.Save(file)
-
- return
}
//
@@ -887,9 +1010,10 @@ func (env *Env) update(curPkg, newPkg *Package) (ok bool, err error) {
//
// updateMissing will remove missing package if it's already provided by new
-// package and add it as one of package dependencies.
+// package. If "addAsDep" is true and the new package provide the missing one,
+// then it will be added as one of package dependencies.
//
-func (env *Env) updateMissing(newPkg *Package) {
+func (env *Env) updateMissing(newPkg *Package, addAsDep bool) {
var updated bool
if Debug >= DebugL1 {
@@ -897,7 +1021,7 @@ func (env *Env) updateMissing(newPkg *Package) {
}
for x := 0; x < len(env.pkgs); x++ {
- updated = env.pkgs[x].UpdateMissingDep(newPkg)
+ updated = env.pkgs[x].UpdateMissingDep(newPkg, addAsDep)
if updated {
env.dirty = true
}
@@ -933,6 +1057,11 @@ func (env *Env) Sync(pkgName, importPath string) (err error) {
if len(pkgName) == 0 {
return
}
+ if env.IsExcluded(pkgName) {
+ fmt.Printf(errExcluded, pkgName)
+ err = nil
+ return
+ }
var (
ok bool
@@ -957,7 +1086,7 @@ func (env *Env) Sync(pkgName, importPath string) (err error) {
}
// (2)
- curPkg := env.GetPackageFromDB(newPkg.ImportPath, newPkg.RemoteURL)
+ _, curPkg := env.GetPackageFromDB(newPkg.ImportPath, newPkg.RemoteURL)
if curPkg != nil {
ok, err = env.update(curPkg, newPkg)
} else {
@@ -1065,7 +1194,7 @@ func (env *Env) SyncAll() (err error) {
//
func (env *Env) postSync(curPkg, newPkg *Package) (err error) {
// (1)
- env.updateMissing(newPkg)
+ env.updateMissing(newPkg, true)
// (2)
err = curPkg.ScanDeps(env)
diff --git a/env_test.go b/env_test.go
index f427121..30e1a17 100644
--- a/env_test.go
+++ b/env_test.go
@@ -10,7 +10,176 @@ import (
"github.com/shuLhan/tekstus/diff"
)
+func testEnvAddExclude(t *testing.T) {
+ testEnv.pkgsExclude = nil
+
+ cases := []struct {
+ desc string
+ exclude string
+ expExclude []string
+ expReturn bool
+ }{{
+ desc: "With empty excluded",
+ }, {
+ desc: "Exclude A",
+ exclude: "A",
+ expExclude: []string{"A"},
+ expReturn: true,
+ }, {
+ desc: "Exclude A again",
+ exclude: "A",
+ expExclude: []string{"A"},
+ }}
+
+ for _, c := range cases {
+ t.Log(c.desc)
+
+ got := testEnv.addExclude(c.exclude)
+
+ test.Assert(t, "expExclude", c.expExclude, testEnv.pkgsExclude, true)
+ test.Assert(t, "expReturn", c.expReturn, got, true)
+ }
+}
+
+func testEnvExclude(t *testing.T) {
+ testEnv.pkgsExclude = nil
+ testEnv.pkgs = nil
+ testEnv.pkgsMissing = nil
+
+ err := testEnv.Load(testDBLoad)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ cases := []struct {
+ desc string
+ excludes []string
+ expExclude []string
+ expPkgsLen int
+ expPkg *Package
+ expMissing []string
+ }{{
+ desc: "Exclude package not in DB",
+ excludes: []string{"github.com/shuLhan/notInDB"},
+ expExclude: []string{"github.com/shuLhan/notInDB"},
+ expPkgsLen: 49,
+ expMissing: []string{
+ "github.com/BurntSushi/toml",
+ "gopkg.in/urfave/cli.v1",
+ "gopkg.in/yaml.v2",
+ "google.golang.org/appengine/log",
+ "golang.org/x/crypto/ssh/terminal",
+ "google.golang.org/appengine",
+ "github.com/modern-go/concurrent",
+ "github.com/modern-go/reflect2",
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2",
+ "github.com/yosssi/gohtml",
+ "cloud.google.com/go/compute/metadata",
+ "github.com/spf13/pflag",
+ },
+ }, {
+ desc: "Exclude package in missing",
+ excludes: []string{"github.com/spf13/pflag"},
+ expExclude: []string{
+ "github.com/shuLhan/notInDB",
+ "github.com/spf13/pflag",
+ },
+ expPkgsLen: 49,
+ expPkg: &Package{
+ ImportPath: "gotest.tools",
+ FullPath: filepath.Join(testEnv.dirSrc, "gotest.tools"),
+ RemoteName: "origin",
+ RemoteURL: "https://github.com/gotestyourself/gotestyourself",
+ Version: "v2.0.0",
+ isTag: true,
+ Deps: []string{
+ "github.com/pkg/errors",
+ "golang.org/x/tools",
+ "github.com/google/go-cmp",
+ },
+ RequiredBy: []string{
+ "github.com/alecthomas/gometalinter",
+ },
+ state: packageStateDirty,
+ vcs: VCSModeGit,
+ },
+ expMissing: []string{
+ "github.com/BurntSushi/toml",
+ "gopkg.in/urfave/cli.v1",
+ "gopkg.in/yaml.v2",
+ "google.golang.org/appengine/log",
+ "golang.org/x/crypto/ssh/terminal",
+ "google.golang.org/appengine",
+ "github.com/modern-go/concurrent",
+ "github.com/modern-go/reflect2",
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2",
+ "github.com/yosssi/gohtml",
+ "cloud.google.com/go/compute/metadata",
+ },
+ }, {
+ desc: "Exclude package in DB",
+ excludes: []string{
+ "github.com/shuLhan/beku",
+ },
+ expExclude: []string{
+ "github.com/shuLhan/notInDB",
+ "github.com/spf13/pflag",
+ "github.com/shuLhan/beku",
+ },
+ expPkgsLen: 48,
+ expPkg: &Package{
+ ImportPath: "github.com/shuLhan/share",
+ FullPath: filepath.Join(testEnv.dirSrc, "github.com/shuLhan/share"),
+ RemoteName: "origin",
+ RemoteURL: "git@github.com:shuLhan/share.git",
+ Version: "b2c8fd7",
+ state: packageStateLoad,
+ vcs: VCSModeGit,
+ },
+ expMissing: []string{
+ "github.com/BurntSushi/toml",
+ "gopkg.in/urfave/cli.v1",
+ "gopkg.in/yaml.v2",
+ "google.golang.org/appengine/log",
+ "golang.org/x/crypto/ssh/terminal",
+ "google.golang.org/appengine",
+ "github.com/modern-go/concurrent",
+ "github.com/modern-go/reflect2",
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2",
+ "github.com/yosssi/gohtml",
+ "cloud.google.com/go/compute/metadata",
+ },
+ }}
+
+ for _, c := range cases {
+ t.Log(c.desc)
+
+ testEnv.Exclude(c.excludes)
+
+ test.Assert(t, "exp excludes", c.expExclude, testEnv.pkgsExclude, true)
+ test.Assert(t, "pkgs length", c.expPkgsLen, len(testEnv.pkgs), true)
+ test.Assert(t, "pkgs missing", c.expMissing, testEnv.pkgsMissing, true)
+
+ if c.expPkg == nil {
+ continue
+ }
+
+ _, got := testEnv.GetPackageFromDB(c.expPkg.ImportPath, "")
+
+ test.Assert(t, "expPkg", c.expPkg, got, true)
+ }
+
+ err = testEnv.Save(testDBSaveExclude)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
func testEnvLoad(t *testing.T) {
+ testEnv.pkgsExclude = nil
+ testEnv.pkgs = nil
+ testEnv.pkgsMissing = nil
+
cases := []struct {
desc string
file string
@@ -25,7 +194,7 @@ func testEnvLoad(t *testing.T) {
expErr: fmt.Sprintf("open %s: no such file or directory", testEnv.dbDefFile),
}, {
desc: `With valid file`,
- file: "testdata/beku.db",
+ file: testDBLoad,
}}
var err error
@@ -96,7 +265,7 @@ func testEnvGetPackageFromDB(t *testing.T) {
for _, c := range cases {
t.Log(c.desc)
- got := testEnv.GetPackageFromDB(c.importPath, c.remoteURL)
+ _, got := testEnv.GetPackageFromDB(c.importPath, c.remoteURL)
test.Assert(t, "", c.exp, got, true)
}
@@ -222,7 +391,7 @@ func testEnvFilterUnusedDeps(t *testing.T) {
for _, c := range cases {
t.Log(c.importPath)
- pkg := testEnv.GetPackageFromDB(c.importPath, "")
+ _, pkg := testEnv.GetPackageFromDB(c.importPath, "")
unused := make(map[string]bool)
testEnv.filterUnusedDeps(pkg, unused)
@@ -264,7 +433,7 @@ func testEnvSave(t *testing.T) {
continue
}
- diffs, err := diff.Files("testdata/beku.db", c.file, diff.LevelLines)
+ diffs, err := diff.Files(testDBLoad, c.file, diff.LevelLines)
if err != nil {
t.Fatal(err)
}
@@ -296,9 +465,9 @@ func testEnvUpdateMissing(t *testing.T) {
}}
for _, c := range cases {
- testEnv.updateMissing(c.newPkg)
+ testEnv.updateMissing(c.newPkg, true)
- got := testEnv.GetPackageFromDB(c.expPkg, "")
+ _, got := testEnv.GetPackageFromDB(c.expPkg, "")
test.Assert(t, "expDeps", c.expDeps, got.Deps, true)
test.Assert(t, "expMissing", c.expMissing, got.DepsMissing, true)
@@ -366,6 +535,8 @@ func testEnvSync(t *testing.T) {
}
func TestEnv(t *testing.T) {
+ t.Run("addExclude", testEnvAddExclude)
+ t.Run("Exclude", testEnvExclude)
t.Run("Load", testEnvLoad)
t.Run("GetPackageFromDB", testEnvGetPackageFromDB)
t.Run("Query", testEnvQuery)
diff --git a/package.go b/package.go
index a2f2f48..0244e22 100644
--- a/package.go
+++ b/package.go
@@ -491,16 +491,17 @@ func (pkg *Package) Update(newPkg *Package) (err error) {
}
//
-// UpdateMissingDep will,
-// (1) remove missing package if it's already provided by new package
-// import-path,
-// (2) add it as one of package dependencies of current package, and,
-// (3) add current package as required by new package.
+// UpdateMissingDep will remove missing package if it's already provided by
+// new package import-path.
+//
+// If "addAsDep" is true, it will also,
+// (1) add new package as one of package dependencies of current package, and
+// (2) add current package as required by new package.
//
// It will return true if new package solve the missing deps on current
// package, otherwise it will return false.
//
-func (pkg *Package) UpdateMissingDep(newPkg *Package) (updated bool) {
+func (pkg *Package) UpdateMissingDep(newPkg *Package, addAsDep bool) (found bool) {
var missing []string
for x := 0; x < len(pkg.DepsMissing); x++ {
if !strings.HasPrefix(pkg.DepsMissing[x], newPkg.ImportPath) {
@@ -508,13 +509,16 @@ func (pkg *Package) UpdateMissingDep(newPkg *Package) (updated bool) {
continue
}
- pkg.pushDep(newPkg.ImportPath)
- newPkg.pushRequiredBy(pkg.ImportPath)
- updated = true
+ if addAsDep {
+ pkg.pushDep(newPkg.ImportPath)
+ newPkg.pushRequiredBy(pkg.ImportPath)
+ }
+ found = true
}
- if updated {
+ if found {
pkg.DepsMissing = missing
+ pkg.state = packageStateDirty
}
return
diff --git a/package_test.go b/package_test.go
index 815953b..cdac7f4 100644
--- a/package_test.go
+++ b/package_test.go
@@ -687,6 +687,7 @@ func testUpdateMissingDep(t *testing.T) {
Deps: []string{
"c",
},
+ state: packageStateDirty,
},
expMisPkg: &Package{
ImportPath: "c",
@@ -699,7 +700,7 @@ func testUpdateMissingDep(t *testing.T) {
for _, c := range cases {
t.Log(c.desc)
- got := c.curPkg.UpdateMissingDep(c.misPkg)
+ got := c.curPkg.UpdateMissingDep(c.misPkg, true)
test.Assert(t, "return value", c.exp, got, true)
test.Assert(t, "package", c.expCurPkg, c.curPkg, true)