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

Commit 391e768

Browse files
committed
Implement missing flag for dep status
Comply with command spec by making dep status -missing list the dependencies that are missing from the lock file but are used in the project. Issue #1382.
1 parent 7ea232e commit 391e768

File tree

3 files changed

+132
-39
lines changed

3 files changed

+132
-39
lines changed

cmd/dep/status.go

+66-14
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ type outputter interface {
119119
MissingHeader() error
120120
MissingLine(*MissingStatus) error
121121
MissingFooter() error
122+
StatusMissingHeader() error
123+
StatusMissingLine(gps.ProjectRoot) error
124+
StatusMissingFooter() error
122125
}
123126

124127
// Only a subset of the outputters should be able to output old statuses.
@@ -170,6 +173,20 @@ func (out *tableOutput) MissingFooter() error {
170173
return out.w.Flush()
171174
}
172175

176+
func (out *tableOutput) StatusMissingHeader() error {
177+
_, err := fmt.Fprintln(out.w, "Missing dependencies (not present in lock):")
178+
return err
179+
}
180+
181+
func (out *tableOutput) StatusMissingLine(missingDep gps.ProjectRoot) error {
182+
_, err := fmt.Fprintf(out.w, " %v\n", missingDep)
183+
return err
184+
}
185+
186+
func (out *tableOutput) StatusMissingFooter() error {
187+
return out.w.Flush()
188+
}
189+
173190
func (out *tableOutput) OldHeader() error {
174191
_, err := fmt.Fprintf(out.w, "PROJECT\tCONSTRAINT\tREVISION\tLATEST\n")
175192
return err
@@ -191,10 +208,11 @@ func (out *tableOutput) OldFooter() error {
191208
}
192209

193210
type jsonOutput struct {
194-
w io.Writer
195-
basic []*rawStatus
196-
missing []*MissingStatus
197-
old []*rawOldStatus
211+
w io.Writer
212+
basic []*rawStatus
213+
missing []*MissingStatus
214+
statusMissing []struct{ ProjectRoot gps.ProjectRoot }
215+
old []*rawOldStatus
198216
}
199217

200218
func (out *jsonOutput) BasicHeader() error {
@@ -225,6 +243,21 @@ func (out *jsonOutput) MissingFooter() error {
225243
return json.NewEncoder(out.w).Encode(out.missing)
226244
}
227245

246+
func (out *jsonOutput) StatusMissingHeader() error {
247+
out.statusMissing = []struct{ ProjectRoot gps.ProjectRoot }{}
248+
return nil
249+
}
250+
251+
func (out *jsonOutput) StatusMissingLine(missingDep gps.ProjectRoot) error {
252+
out.statusMissing = append(out.statusMissing,
253+
struct{ ProjectRoot gps.ProjectRoot }{missingDep})
254+
return nil
255+
}
256+
257+
func (out *jsonOutput) StatusMissingFooter() error {
258+
return json.NewEncoder(out.w).Encode(out.statusMissing)
259+
}
260+
228261
func (out *jsonOutput) OldHeader() error {
229262
out.old = []*rawOldStatus{}
230263
return nil
@@ -269,9 +302,12 @@ func (out *dotOutput) BasicLine(bs *BasicStatus) error {
269302
return nil
270303
}
271304

272-
func (out *dotOutput) MissingHeader() error { return nil }
273-
func (out *dotOutput) MissingLine(ms *MissingStatus) error { return nil }
274-
func (out *dotOutput) MissingFooter() error { return nil }
305+
func (out *dotOutput) MissingHeader() error { return nil }
306+
func (out *dotOutput) MissingLine(ms *MissingStatus) error { return nil }
307+
func (out *dotOutput) MissingFooter() error { return nil }
308+
func (out *dotOutput) StatusMissingHeader() error { return nil }
309+
func (out *dotOutput) StatusMissingLine(missingDep gps.ProjectRoot) error { return nil }
310+
func (out *dotOutput) StatusMissingFooter() error { return nil }
275311

276312
type templateOutput struct {
277313
w io.Writer
@@ -303,6 +339,12 @@ func (out *templateOutput) MissingFooter() error { return nil }
303339
func (out *templateOutput) MissingLine(ms *MissingStatus) error {
304340
return out.tmpl.Execute(out.w, ms)
305341
}
342+
func (out *templateOutput) StatusMissingHeader() error { return nil }
343+
func (out *templateOutput) StatusMissingLine(missingDep gps.ProjectRoot) error {
344+
t := struct{ ProjectRoot gps.ProjectRoot }{missingDep}
345+
return out.tmpl.Execute(out.w, t)
346+
}
347+
func (out *templateOutput) StatusMissingFooter() error { return nil }
306348

307349
func (cmd *statusCommand) Run(ctx *dep.Ctx, args []string) error {
308350
if cmd.examples {
@@ -373,7 +415,10 @@ func (cmd *statusCommand) Run(ctx *dep.Ctx, args []string) error {
373415
}
374416

375417
if cmd.missing {
376-
err := cmd.runStatusMissing(ctx, p)
418+
err := cmd.runStatusMissing(ctx, out, p)
419+
if len(buf.String()) > 0 {
420+
ctx.Out.Print(buf.String())
421+
}
377422
return err
378423
}
379424

@@ -491,7 +536,7 @@ func (os OldStatus) marshalJSON() *rawOldStatus {
491536
}
492537

493538
// runStatusMissing analyses the project for missing dependencies in lock file.
494-
func (cmd *statusCommand) runStatusMissing(ctx *dep.Ctx, p *dep.Project) error {
539+
func (cmd *statusCommand) runStatusMissing(ctx *dep.Ctx, out outputter, p *dep.Project) error {
495540

496541
ptree, err := p.ParseRootPackageTree()
497542
if err != nil {
@@ -500,7 +545,7 @@ func (cmd *statusCommand) runStatusMissing(ctx *dep.Ctx, p *dep.Project) error {
500545
rm, _ := ptree.ToReachMap(true, true, false, p.Manifest.IgnoredPackages())
501546
external := rm.FlattenFn(paths.IsStandardImportPath)
502547

503-
var missingDeps []string
548+
var missingDeps []gps.ProjectRoot
504549

505550
missingOuter:
506551
for _, d := range external {
@@ -510,16 +555,23 @@ missingOuter:
510555
}
511556
}
512557

513-
missingDeps = append(missingDeps, d)
558+
missingDeps = append(missingDeps, gps.ProjectRoot(d))
514559
}
515560

516561
if missingDeps != nil {
517-
ctx.Err.Printf("Missing dependencies (not present in lock):\n")
562+
if err = out.StatusMissingHeader(); err != nil {
563+
return err
564+
}
518565
for _, d := range missingDeps {
519-
ctx.Err.Printf(" %v\n", d)
566+
if err = out.StatusMissingLine(d); err != nil {
567+
return err
568+
}
569+
}
570+
if err = out.StatusMissingFooter(); err != nil {
571+
return err
520572
}
521573
} else {
522-
ctx.Err.Println("No missing dependencies found.")
574+
ctx.Err.Printf("No missing dependencies found.")
523575
}
524576

525577
return nil

cmd/dep/status_test.go

+64-24
Original file line numberDiff line numberDiff line change
@@ -560,10 +560,13 @@ func TestValidateFlags(t *testing.T) {
560560
func TestStatusMissing(t *testing.T) {
561561

562562
cases := []struct {
563-
name string
564-
lock dep.Lock
565-
wantStatus string
566-
wantErr bool
563+
name string
564+
lock dep.Lock
565+
cmds []statusCommand
566+
wantTableStatus string
567+
wantJSONStatus string
568+
wantTemplateStatus string
569+
wantErr bool
567570
}{
568571
{
569572
name: "no missing dependencies",
@@ -586,7 +589,10 @@ func TestStatusMissing(t *testing.T) {
586589
),
587590
},
588591
},
589-
wantStatus: "No missing dependencies found.\n",
592+
cmds: []statusCommand{
593+
statusCommand{missing: true}, //default for table output
594+
},
595+
wantTableStatus: "No missing dependencies found.\n",
590596
},
591597
{
592598
name: "two missing dependencies",
@@ -599,9 +605,16 @@ func TestStatusMissing(t *testing.T) {
599605
),
600606
},
601607
},
602-
wantStatus: "Missing dependencies (not present in lock):\n" +
608+
cmds: []statusCommand{
609+
statusCommand{missing: true}, //default for table output
610+
statusCommand{missing: true, json: true},
611+
statusCommand{missing: true, template: "Missing:{{.ProjectRoot}} "},
612+
},
613+
wantTableStatus: "Missing dependencies (not present in lock):\n" +
603614
" github.com/boltdb/bolt\n" +
604615
" github.com/sdboyer/dep-test\n",
616+
wantJSONStatus: `[{"ProjectRoot":"github.com/boltdb/bolt"},{"ProjectRoot":"github.com/sdboyer/dep-test"}]` + "\n",
617+
wantTemplateStatus: "Missing:github.com/boltdb/bolt Missing:github.com/sdboyer/dep-test \n",
605618
},
606619
}
607620

@@ -613,14 +626,13 @@ func TestStatusMissing(t *testing.T) {
613626
h.TempCopy(filepath.Join(testdir, "main.go"), filepath.Join("status", "missing", "main.go"))
614627
testProjPath := h.Path(testdir)
615628

616-
var buf bytes.Buffer
617-
bufferWriter := bufio.NewWriter(&buf)
629+
var bufW bytes.Buffer
630+
bufferWriter := bufio.NewWriter(&bufW)
618631
bufferLogger := log.New(bufferWriter, "", 0)
619-
discardLogger := log.New(ioutil.Discard, "", 0)
620632

621633
ctx := &dep.Ctx{
622634
GOPATH: testProjPath,
623-
Out: discardLogger,
635+
Out: bufferLogger,
624636
Err: bufferLogger,
625637
}
626638

@@ -631,25 +643,53 @@ func TestStatusMissing(t *testing.T) {
631643
p := new(dep.Project)
632644
p.SetRoot(testProjPath)
633645

634-
cmd := statusCommand{
635-
missing: true,
636-
}
646+
var bufO bytes.Buffer
647+
var out outputter
637648

638649
for _, c := range cases {
639650
t.Run(c.name, func(t *testing.T) {
640-
buf.Reset()
641-
p.Manifest = &dep.Manifest{} // needed for empty Ignored packages string
642-
p.Lock = &c.lock
643651

644-
err = cmd.runStatusMissing(ctx, p)
645-
bufferWriter.Flush()
646-
actualStatus := buf.String()
652+
for _, statusCmd := range c.cmds {
653+
bufO.Reset()
654+
bufW.Reset()
655+
656+
var wantStatus string
657+
switch {
658+
case statusCmd.json:
659+
out = &jsonOutput{
660+
w: &bufO,
661+
}
662+
wantStatus = c.wantJSONStatus
663+
case statusCmd.template != "":
664+
tmpl, _ := template.New("status").Parse(statusCmd.template)
665+
out = &templateOutput{
666+
w: &bufO,
667+
tmpl: tmpl,
668+
}
669+
wantStatus = c.wantTemplateStatus
670+
default:
671+
out = &tableOutput{
672+
w: tabwriter.NewWriter(&bufO, 0, 4, 2, ' ', 0),
673+
}
674+
wantStatus = c.wantTableStatus
675+
}
647676

648-
if err != nil && !c.wantErr {
649-
t.Fatalf("unexpected errors while collecting constraints: %v", err)
650-
}
651-
if actualStatus != c.wantStatus {
652-
t.Fatalf("unexpected missign status: \n\t(GOT): %v\n\t(WNT): %v", actualStatus, c.wantStatus)
677+
p.Manifest = &dep.Manifest{} // needed for empty Ignored packages string
678+
p.Lock = &c.lock
679+
680+
err = statusCmd.runStatusMissing(ctx, out, p)
681+
if len(bufO.String()) > 0 {
682+
ctx.Out.Print(bufO.String())
683+
}
684+
bufferWriter.Flush()
685+
actualStatus := bufW.String()
686+
687+
if err != nil && !c.wantErr {
688+
t.Fatalf("unexpected errors while collecting constraints: %v", err)
689+
}
690+
if actualStatus != wantStatus {
691+
t.Fatalf("unexpected missing status: \n\t(GOT): %v\n\t(WNT): %v", actualStatus, wantStatus)
692+
}
653693
}
654694
})
655695
}

cmd/dep/testdata/status/missing/main.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2017 The Go Authors. All rights reserved.
1+
// Copyright 2018 The Go Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

@@ -10,4 +10,5 @@ import (
1010
_ "github.com/sdboyer/deptestdos"
1111
)
1212

13+
// FooBar is a dummy type
1314
type FooBar int

0 commit comments

Comments
 (0)