Skip to content

Commit 8286730

Browse files
committed
fix(use): Move use up to cmd/ from lib/. Delete select from repo/
1 parent 278deb9 commit 8286730

27 files changed

+151
-421
lines changed

cmd/diff.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ func (o *DiffOptions) Run() (err error) {
104104
Selector: o.Selector,
105105
}
106106

107+
// TODO(dlong): Reenable `use` functionality for this command.
108+
107109
res := &lib.DiffResponse{}
108110
if err = o.DatasetRequests.Diff(p, res); err != nil {
109111
return err

cmd/export.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ type ExportOptions struct {
6464

6565
// Complete adds any missing configuration that can only be added just before calling Run
6666
func (o *ExportOptions) Complete(f Factory, args []string) (err error) {
67-
if len(args) > 0 {
68-
o.Ref = args[0]
67+
o.Ref, err = GetDatasetRefString(f, args, 0)
68+
if err != nil {
69+
return err
6970
}
7071
if f.RPC() != nil {
7172
return usingRPCError("export")

cmd/factory.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ type Factory interface {
3636
ProfileMethods() (*lib.ProfileMethods, error)
3737
SearchRequests() (*lib.SearchRequests, error)
3838
RenderRequests() (*lib.RenderRequests, error)
39-
SelectionRequests() (*lib.SelectionRequests, error)
4039
}
4140

4241
// PathFactory is a function that returns paths to qri & ipfs repos

cmd/factory_test.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,6 @@ func (t TestFactory) ProfileMethods() (*lib.ProfileMethods, error) {
146146
return lib.NewProfileMethods(t.inst), nil
147147
}
148148

149-
// SelectionRequests creates a lib.SelectionRequests from internal state
150-
func (t TestFactory) SelectionRequests() (*lib.SelectionRequests, error) {
151-
return lib.NewSelectionRequests(t.repo, t.rpc), nil
152-
}
153-
154149
// SearchRequests generates a lib.SearchRequests from internal state
155150
func (t TestFactory) SearchRequests() (*lib.SearchRequests, error) {
156151
return lib.NewSearchRequests(t.node, t.rpc), nil

cmd/get.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,15 @@ func (o *GetOptions) Complete(f Factory, args []string) (err error) {
9292
args = args[1:]
9393
}
9494
}
95-
o.Refs = args
95+
o.Refs = make([]string, 0, len(args))
96+
for i := range args {
97+
var ref string
98+
ref, err = GetDatasetRefString(f, args, i)
99+
if err != nil {
100+
return
101+
}
102+
o.Refs = append(o.Refs, ref)
103+
}
96104
if o.DatasetRequests, err = f.DatasetRequests(); err != nil {
97105
return
98106
}
@@ -123,14 +131,6 @@ func (o *GetOptions) Complete(f Factory, args []string) (err error) {
123131

124132
// Run executes the get command
125133
func (o *GetOptions) Run() (err error) {
126-
var path string
127-
if len(o.Refs) > 0 {
128-
path = o.Refs[0]
129-
if err != nil {
130-
return err
131-
}
132-
}
133-
134134
// Pretty maps to a key in the FormatConfig map.
135135
var fc dataset.FormatConfig
136136
if o.HasPretty {
@@ -142,6 +142,11 @@ func (o *GetOptions) Run() (err error) {
142142
// convert Page and PageSize to Limit and Offset
143143
page := util.NewPage(o.Page, o.PageSize)
144144

145+
var path string
146+
if len(o.Refs) > 0 {
147+
// TODO(dlong): Restore ability to `get` from multiple datasets at once.
148+
path = o.Refs[0]
149+
}
145150
p := lib.GetParams{
146151
Path: path,
147152
Selector: o.Selector,

cmd/log.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ type LogOptions struct {
5959

6060
// Complete adds any missing configuration that can only be added just before calling Run
6161
func (o *LogOptions) Complete(f Factory, args []string) (err error) {
62-
if len(args) > 0 {
63-
o.Ref = args[0]
64-
}
65-
62+
o.Ref, err = GetDatasetRefString(f, args, 0)
6663
if err != nil {
6764
return err
6865
}

cmd/qri.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,6 @@ func (o *QriOptions) ProfileMethods() (m *lib.ProfileMethods, err error) {
224224
return lib.NewProfileMethods(o.inst), nil
225225
}
226226

227-
// SelectionRequests creates a lib.SelectionRequests from internal state
228-
func (o *QriOptions) SelectionRequests() (*lib.SelectionRequests, error) {
229-
if err := o.Init(); err != nil {
230-
return nil, err
231-
}
232-
return lib.NewSelectionRequests(o.inst.Repo(), o.inst.RPC()), nil
233-
}
234-
235227
// SearchRequests generates a lib.SearchRequests from internal state
236228
func (o *QriOptions) SearchRequests() (*lib.SearchRequests, error) {
237229
if err := o.Init(); err != nil {

cmd/render.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ type RenderOptions struct {
6060

6161
// Complete adds any missing configuration that can only be added just before calling Run
6262
func (o *RenderOptions) Complete(f Factory, args []string) (err error) {
63-
if len(args) > 0 {
64-
o.Ref = args[0]
63+
o.Ref, err = GetDatasetRefString(f, args, 0)
64+
if err != nil {
65+
return err
6566
}
6667
o.RenderRequests, err = f.RenderRequests()
6768
return

cmd/use.go

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package cmd
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"io/ioutil"
7+
"os"
8+
"path/filepath"
59

610
"github.com/qri-io/ioes"
711
"github.com/qri-io/qri/lib"
812
"github.com/qri-io/qri/repo"
913
"github.com/spf13/cobra"
1014
)
1115

16+
// FileSelectedRefs stores selection, is copied from github.com/qri-io/qri/repo/fs/files.go
17+
const FileSelectedRefs = "/selected_refs.json"
18+
1219
// NewUseCommand creates a new `qri search` command that searches for datasets
1320
func NewUseCommand(f Factory, ioStreams ioes.IOStreams) *cobra.Command {
1421
o := &UseOptions{IOStreams: ioStreams}
@@ -62,13 +69,13 @@ type UseOptions struct {
6269
List bool
6370
Clear bool
6471

65-
SelectionRequests *lib.SelectionRequests
72+
QriRepoPath string
6673
}
6774

6875
// Complete adds any missing configuration that can only be added just before calling Run
6976
func (o *UseOptions) Complete(f Factory, args []string) (err error) {
77+
o.QriRepoPath = f.QriRepoPath()
7078
o.Refs = args
71-
o.SelectionRequests, err = f.SelectionRequests()
7279
return
7380
}
7481

@@ -85,16 +92,21 @@ func (o *UseOptions) Validate() error {
8592

8693
// Run executes the search command
8794
func (o *UseOptions) Run() (err error) {
88-
var (
89-
refs []repo.DatasetRef
90-
res bool
91-
)
95+
var refs []repo.DatasetRef
96+
fileSelectionPath := filepath.Join(o.QriRepoPath, FileSelectedRefs)
9297

9398
if o.List {
94-
if err = o.SelectionRequests.SelectedRefs(&res, &refs); err != nil {
99+
refs, err = readFile(fileSelectionPath)
100+
if err != nil {
101+
return err
102+
}
103+
} else if o.Clear {
104+
err := writeFile(fileSelectionPath, refs)
105+
if err != nil {
95106
return err
96107
}
97-
} else if len(o.Refs) > 0 || o.Clear {
108+
printInfo(o.Out, "cleared selected datasets")
109+
} else if len(o.Refs) > 0 {
98110
for _, refstr := range o.Refs {
99111
ref, err := repo.ParseDatasetRef(refstr)
100112
if err != nil {
@@ -103,18 +115,73 @@ func (o *UseOptions) Run() (err error) {
103115
refs = append(refs, ref)
104116
}
105117

106-
if err = o.SelectionRequests.SetSelectedRefs(&refs, &res); err != nil {
118+
err := writeFile(fileSelectionPath, refs)
119+
if err != nil {
107120
return err
108121
}
109-
110-
if len(refs) == 0 {
111-
printInfo(o.Out, "cleared selected datasets")
112-
return nil
113-
}
114122
}
115123

116124
for _, ref := range refs {
117125
fmt.Fprintln(o.Out, ref.String())
118126
}
119127
return nil
120128
}
129+
130+
// GetDatasetRefString returns the arg at the index, or otherwise the first selected reference
131+
func GetDatasetRefString(f Factory, args []string, index int) (string, error) {
132+
if index < len(args) {
133+
return args[index], nil
134+
}
135+
refs, err := DefaultSelectedRefList(f)
136+
if err != nil {
137+
return "", err
138+
}
139+
if len(refs) == 0 {
140+
// If selected_refs.json is empty or doesn't exist, not an error.
141+
return "", nil
142+
}
143+
return refs[0], nil
144+
}
145+
146+
// DefaultSelectedRefList returns the list of currently selected dataset references
147+
func DefaultSelectedRefList(f Factory) ([]string, error) {
148+
fileSelectionPath := filepath.Join(f.QriRepoPath(), FileSelectedRefs)
149+
150+
refs, err := readFile(fileSelectionPath)
151+
if err != nil {
152+
// If selected_refs.json is empty or doesn't exist, not an error.
153+
if os.IsNotExist(err) {
154+
return nil, nil
155+
}
156+
return nil, err
157+
}
158+
159+
res := make([]string, 0, len(refs))
160+
for _, r := range refs {
161+
res = append(res, r.String())
162+
}
163+
164+
return res, nil
165+
}
166+
167+
// writeFile serializes the list of refs to a file at path
168+
func writeFile(path string, refs []repo.DatasetRef) error {
169+
data, err := json.Marshal(refs)
170+
if err != nil {
171+
return err
172+
}
173+
return ioutil.WriteFile(path, data, os.ModePerm)
174+
}
175+
176+
// readFile deserializes a list of refs from a file at path
177+
func readFile(path string) ([]repo.DatasetRef, error) {
178+
data, err := ioutil.ReadFile(path)
179+
if err != nil {
180+
return nil, err
181+
}
182+
res := []repo.DatasetRef{}
183+
if err = json.Unmarshal(data, &res); err != nil {
184+
return nil, err
185+
}
186+
return res, nil
187+
}

cmd/use_test.go

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package cmd
22

33
import (
4+
"os"
5+
"path/filepath"
46
"strings"
57
"testing"
68

@@ -48,13 +50,6 @@ func TestUseComplete(t *testing.T) {
4850
ioReset(in, out, errs)
4951
continue
5052
}
51-
52-
if opt.SelectionRequests == nil {
53-
t.Errorf("case %d, opt.SelectionRequests not set.", i)
54-
ioReset(in, out, errs)
55-
continue
56-
}
57-
ioReset(in, out, errs)
5853
}
5954
}
6055

@@ -100,7 +95,20 @@ func TestUseRun(t *testing.T) {
10095
streams, in, out, errs := ioes.NewTestIOStreams()
10196
setNoColor(true)
10297

103-
f, err := NewTestFactory(nil)
98+
tmpdir := filepath.Join(os.TempDir(), "qri_use_test")
99+
//clean up if previous cleanup failed
100+
if _, err := os.Stat(tmpdir); os.IsNotExist(err) {
101+
if err := os.RemoveAll(tmpdir); err != nil {
102+
t.Fatalf("failed to cleanup from previous test execution: %s", err.Error())
103+
}
104+
}
105+
if err := os.MkdirAll(tmpdir, os.ModePerm); err != nil {
106+
t.Errorf("error creating test path: %s", err.Error())
107+
return
108+
}
109+
defer os.RemoveAll(tmpdir)
110+
111+
_, err := NewTestFactory(nil)
104112
if err != nil {
105113
t.Errorf("error creating new test factory: %s", err)
106114
return
@@ -121,18 +129,12 @@ func TestUseRun(t *testing.T) {
121129
}
122130

123131
for i, c := range cases {
124-
slr, err := f.SelectionRequests()
125-
if err != nil {
126-
t.Errorf("case %d, error creating dataset request: %s", i, err)
127-
continue
128-
}
129-
130132
opt := &UseOptions{
131-
IOStreams: streams,
132-
Refs: c.refs,
133-
List: c.list,
134-
Clear: c.clear,
135-
SelectionRequests: slr,
133+
IOStreams: streams,
134+
Refs: c.refs,
135+
List: c.list,
136+
Clear: c.clear,
137+
QriRepoPath: tmpdir,
136138
}
137139

138140
err = opt.Run()

cmd/validate.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ func (o *ValidateOptions) Run() (err error) {
127127
}
128128
}
129129

130+
// TODO(dlong): Reenable `use` functionality for this command. Also, change Ref to a string.
131+
130132
p := &lib.ValidateDatasetParams{
131133
Ref: ref,
132134
// TODO: restore

lib/datasets.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,11 @@ func (r *DatasetRequests) Get(p *GetParams, res *GetResult) (err error) {
103103
ref := &repo.DatasetRef{}
104104

105105
if p.Path == "" {
106-
// Handle `qri use` to get the current default dataset.
107-
if err = DefaultSelectedRef(r.node.Repo, ref); err != nil {
108-
return
109-
}
110-
} else {
111-
*ref, err = repo.ParseDatasetRef(p.Path)
112-
if err != nil {
113-
return fmt.Errorf("'%s' is not a valid dataset reference", p.Path)
114-
}
106+
return repo.ErrEmptyRef
107+
}
108+
*ref, err = repo.ParseDatasetRef(p.Path)
109+
if err != nil {
110+
return fmt.Errorf("'%s' is not a valid dataset reference", p.Path)
115111
}
116112
if err = repo.CanonicalizeDatasetRef(r.node.Repo, ref); err != nil {
117113
return
@@ -554,10 +550,6 @@ func (r *DatasetRequests) Validate(p *ValidateDatasetParams, errors *[]jsonschem
554550
return r.cli.Call("DatasetRequests.Validate", p, errors)
555551
}
556552

557-
if err = DefaultSelectedRef(r.node.Repo, &p.Ref); err != nil {
558-
return
559-
}
560-
561553
// TODO: restore validating data from a URL
562554
// if p.URL != "" && ref.IsEmpty() && o.Schema == nil {
563555
// return (lib.NewError(ErrBadArgs, "if you are validating data from a url, please include a dataset name or supply the --schema flag with a file path that Qri can validate against"))

0 commit comments

Comments
 (0)