Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

Commit

Permalink
Merge pull request #13 from sdboyer/missing
Browse files Browse the repository at this point in the history
dep: handle missing dependencies slightly better
  • Loading branch information
Edward Muller committed Nov 30, 2016
2 parents ed8adfe + caa0ce7 commit c391723
Showing 1 changed file with 68 additions and 14 deletions.
82 changes: 68 additions & 14 deletions status.go
Expand Up @@ -8,6 +8,7 @@ import (
"bytes"
"fmt"
"os"
"sort"
"text/tabwriter"

"github.com/sdboyer/gps"
Expand Down Expand Up @@ -74,6 +75,11 @@ type BasicStatus struct {
PackageCount int
}

type MissingStatus struct {
ProjectRoot string
MissingPackages string
}

func runStatus(args []string) error {
p, err := loadProject("")
if err != nil {
Expand Down Expand Up @@ -130,15 +136,22 @@ func runStatusAll(p *project, sm *gps.SourceMgr) error {
}

cm := collectConstraints(ptree, p, sm)
tw := tabwriter.NewWriter(os.Stdout, 0, 4, 1, ' ', 0)
// Print header row
fmt.Fprintf(tw, "Project\tConstraint\tVersion\tRevision\tLatest\tPkgs Used\t\n")

// Get the project list and sort it so that the printed output users see is
// deterministically ordered. (This may be superfluous if the lock is always
// written in alpha order, but it doesn't hurt to double down.)
slp := p.l.Projects()
sort.Sort(sortedLockedProjects(slp))

if bytes.Equal(s.HashInputs(), p.l.Memo) {
// If these are equal, we're guaranteed that the lock is a transitively
// complete picture of all deps. That eliminates the need for at least
// some checks.
for _, proj := range p.l.Projects() {

tw := tabwriter.NewWriter(os.Stdout, 0, 4, 1, ' ', 0)
fmt.Fprintf(tw, "Project\tConstraint\tVersion\tRevision\tLatest\tPkgs Used\t\n")

for _, proj := range slp {
bs := BasicStatus{
ProjectRoot: string(proj.Ident().ProjectRoot),
PackageCount: len(proj.Packages()),
Expand Down Expand Up @@ -201,29 +214,70 @@ func runStatusAll(p *project, sm *gps.SourceMgr) error {
bs.PackageCount,
)
}

tw.Flush()
} else {
// Not equal - the lock may or may not be a complete picture, and even
// if it does have all the deps, it may not be a valid set of
// constraints.
// Hash digest mismatch may indicate that some deps are no longer
// needed, some are missing, or that some constraints or source
// locations have changed.
//
// TODO
// It's possible for digests to not match, but still have a correct
// lock.
tw := tabwriter.NewWriter(os.Stdout, 0, 4, 1, ' ', 0)
fmt.Fprintf(tw, "Project\tMissing Packages\t\n")

external := ptree.ExternalReach(true, false, nil).ListExternalImports()
roots := make(map[gps.ProjectRoot][]string)
var errs []string
for _, e := range external {
root, err := sm.DeduceProjectRoot(e)
if err != nil {
errs = append(errs, string(root))
continue
}

roots[root] = append(roots[root], e)
}

outer:
for root, pkgs := range roots {
// TODO also handle the case where the project is present, but there
// are items missing from just the package list
for _, lp := range slp {
if lp.Ident().ProjectRoot == root {
continue outer
}
}

// List imports?
for _, importPath := range external {
fmt.Fprintf(tw,
"%s\t\t\t\t\t\t\n",
importPath,
"%s\t%s\t\n",
root,
pkgs,
)

}
tw.Flush()
}
tw.Flush()

return nil
}

type sortedLockedProjects []gps.LockedProject

func (s sortedLockedProjects) Len() int { return len(s) }
func (s sortedLockedProjects) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s sortedLockedProjects) Less(i, j int) bool {
l, r := s[i].Ident(), s[j].Ident()

if l.ProjectRoot < r.ProjectRoot {
return true
}
if r.ProjectRoot < l.ProjectRoot {
return false
}

return l.NetworkName < r.NetworkName
}

func runStatusDetailed(p *project, sm *gps.SourceMgr, args []string) error {
// TODO
return fmt.Errorf("not implemented")
Expand Down

0 comments on commit c391723

Please sign in to comment.