Skip to content

Commit

Permalink
fix(fsi unlink): unlink command removes .qri-ref file
Browse files Browse the repository at this point in the history
added some basic tests to make sure this works as expected
  • Loading branch information
b5 committed Sep 10, 2019
1 parent b018fd4 commit 0e6a8fd
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 22 deletions.
41 changes: 19 additions & 22 deletions cmd/fsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,12 @@ type FSIOptions struct {
FSIMethods *lib.FSIMethods
}

// Complete adds any missing configuration that can only be added just before calling Run
// Complete adds any missing configuration that can only be added just before
// calling Run
func (o *FSIOptions) Complete(f Factory, args []string) (err error) {
// TODO (b5): From dustmop: This is okay as a starting point, but we also want
// to add flags to explicitly set the directory and dataset-ref.
// Since the fsi command is "plumbing", we may actually want to require them,
// under the assumption that this is only for advanced use cases, and the UI
// doesn't need to be as friendly. In addition, a common use case is going to
// be a user deleted their dataset folder, and doesn't have access to the
// .qri-ref file any more, so they want to remove the entry from the .fbs,
// but don't have any access to the linked ref. In that case, relying on the
// implicit ref doesn't work.
if len(args) < 1 {
return fmt.Errorf("please provide the name of a dataset to unlink")
}
if o.Refs, err = GetCurrentRefSelect(f, args, -1); err != nil {
return
}
Expand All @@ -73,25 +68,27 @@ func (o *FSIOptions) Complete(f Factory, args []string) (err error) {

// Link creates a FSI link
func (o *FSIOptions) Link() (err error) {
return fmt.Errorf("not finished: link")
return fmt.Errorf("not finished: link command")
}

// Unlink executes the fsi unlink command
func (o *FSIOptions) Unlink() error {
printRefSelect(o.ErrOut, o.Refs)
var res string

p := &lib.LinkParams{
Dir: o.Refs.Dir(),
Ref: o.Refs.Ref(),
}
for _, ref := range o.Refs.RefList() {
printRefSelect(o.Out, o.Refs)

res := ""
p := &lib.LinkParams{
Dir: o.Refs.Dir(),
Ref: ref,
}

if err := o.FSIMethods.Unlink(p, &res); err != nil {
printErr(o.ErrOut, err)
return nil
}
if err := o.FSIMethods.Unlink(p, &res); err != nil {
printErr(o.ErrOut, err)
return nil
}

printSuccess(o.ErrOut, "unlinked: %s", res)
printSuccess(o.Out, "unlinked: %s", res)
}
return nil
}
47 changes: 47 additions & 0 deletions cmd/fsi_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cmd

import (
"testing"

"github.com/google/go-cmp/cmp"
)

func TestFSILinkingCommands(t *testing.T) {
runner := NewFSITestRunner(t, "fsi_commands")
defer runner.Delete()

pwd := runner.CreateAndChdirToWorkDir("save_and_unlink")

// Init as a linked directory
if err := runner.ExecCommand("qri init --name save_and_unlink --format csv"); err != nil {
t.Fatal(err.Error())
}

// TODO (b5) - get output of qri list, confirm dataset is linked

// Save a version of the dataset
if err := runner.ExecCommand("qri save"); err != nil {
t.Fatal(err.Error())
}

// Verify the directory contains the files that we expect, including .qri-ref link file
dirContents := listDirectory(pwd)
expectContents := []string{".qri-ref", "body.csv", "meta.json", "schema.json"}
if diff := cmp.Diff(dirContents, expectContents); diff != "" {
t.Errorf("directory contents (-want +got):\n%s", diff)
}

// Unlink the dataset
if err := runner.ExecCommand("qri fsi unlink me/save_and_unlink"); err != nil {
t.Errorf("unlinking dataset: %s", err.Error())
}

// Verify the directory contains the files that we expect
dirContents = listDirectory(pwd)
expectContents = []string{"body.csv", "meta.json", "schema.json"}
if diff := cmp.Diff(dirContents, expectContents); diff != "" {
t.Errorf("directory contents after unlinking (-want +got):\n%s", diff)
}

// TODO (b5) - get output of qri list, confirm dataset is unlinked
}
8 changes: 8 additions & 0 deletions fsi/fsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ import (
"path/filepath"
"strings"

golog "github.com/ipfs/go-log"
"github.com/qri-io/qri/repo"
)

// package level logger
var log = golog.Logger("fsi")

// QriRefFilename is the name of the file that links a folder to a dataset.
// The file contains a dataset reference that declares the link
// ref files are the authoritative definition of weather a folder is linked
Expand Down Expand Up @@ -135,6 +139,10 @@ func (fsi *FSI) Unlink(dirPath, refStr string) error {
return err
}

if removeLinkErr := removeLinkFile(dirPath); removeLinkErr != nil {
log.Debugf("removing link file: %s", removeLinkErr.Error())
}

if err = repo.CanonicalizeDatasetRef(fsi.repo, &ref); err != nil {
if err == repo.ErrNoHistory {
// if we're unlinking a ref without history, delete it
Expand Down
19 changes: 19 additions & 0 deletions fsi/fsi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,22 @@ func TestUpdateLink(t *testing.T) {
t.Errorf("error: link did not match, actual: %s, expect: %s", link, expect)
}
}

func TestUnlink(t *testing.T) {
paths := NewTmpPaths()
defer paths.Close()

fsi := NewFSI(paths.testRepo)
_, err := fsi.CreateLink(paths.firstDir, "me/test_ds")
if err != nil {
t.Fatalf(err.Error())
}

if err := fsi.Unlink(paths.firstDir, "me/mismatched_reference"); err == nil {
t.Errorf("expected unlinking mismatched reference to error")
}

if err := fsi.Unlink(paths.firstDir, "me/test_ds"); err != nil {
t.Errorf("unlinking valid reference: %s", err.Error())
}
}
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
Expand Down

0 comments on commit 0e6a8fd

Please sign in to comment.