Skip to content

Commit

Permalink
fix(init): TargetDir for init, can be absolute, is created if needed
Browse files Browse the repository at this point in the history
Merge pull request #1574 from qri-io/qri-init-abs
  • Loading branch information
dustmop authored Nov 9, 2020
2 parents 3df66b4 + 55c9ff6 commit 878b7c4
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 150 deletions.
17 changes: 5 additions & 12 deletions api/fsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,11 @@ func (h *FSIHandlers) InitHandler(routePrefix string) http.HandlerFunc {

func (h *FSIHandlers) initHandler(routePrefix string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Backwards compatibility shim for now, can use either "dir" or "filepath".
// TODO: Update desktop to always use "dir", delete "filepath".
dir := r.FormValue("dir")
if dir == "" && r.FormValue("filepath") != "" {
dir = r.FormValue("filepath")
}
p := &lib.InitFSIDatasetParams{
Dir: dir,
Name: r.FormValue("name"),
Format: r.FormValue("format"),
Mkdir: r.FormValue("mkdir"),
SourceBodyPath: r.FormValue("sourcebodypath"),
p := &lib.InitDatasetParams{
TargetDir: r.FormValue("targetdir"),
Name: r.FormValue("name"),
Format: r.FormValue("format"),
BodyPath: r.FormValue("bodypath"),
}

var name string
Expand Down
6 changes: 3 additions & 3 deletions api/fsi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ func TestNoHistory(t *testing.T) {

// Create a linked dataset without saving, it has no versions in the repository
ref, err := run.Inst.FSI().InitDataset(fsi.InitParams{
Dir: workDir,
Name: "test_ds",
Format: "csv",
TargetDir: workDir,
Name: "test_ds",
Format: "csv",
})
if err != nil {
t.Fatal(err)
Expand Down
37 changes: 37 additions & 0 deletions cmd/fsi_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,22 @@ func TestInitExplicitDirectory(t *testing.T) {
}
}

// Test init command can use an explicit directory
func TestInitExplicitAbsoluteDirectory(t *testing.T) {
run := NewFSITestRunner(t, "test_peer_init_abs_dir", "qri_test_init_abs_dir")
defer run.Delete()

absDir := filepath.Join(run.RootPath, "datasets/my_work_dir")
run.MustExec(t, fmt.Sprintf("qri init --name abs_dir --format csv %s", absDir))

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

// Test init command can build dscache
func TestInitDscache(t *testing.T) {
run := NewFSITestRunner(t, "test_peer_init_dscache", "qri_test_init_dscache")
Expand Down Expand Up @@ -376,6 +392,27 @@ func TestGetBodyWithoutStructure(t *testing.T) {
}
}

// Test init command accepts dataset name on standard input
func TestInitUsingStdin(t *testing.T) {
run := NewFSITestRunner(t, "test_peer_init_json_body", "qri_test_init_json_body")
defer run.Delete()

workDir := run.CreateAndChdirToWorkDir("json_body")

// Init with configuration from standard input
err := run.ExecCommandWithStdin(run.Context, "qri init", "my_dataset\njson")
if err != nil {
t.Fatal(err)
}

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

// Test init command can create a json body using the format flag
func TestInitForJsonBody(t *testing.T) {
run := NewFSITestRunner(t, "test_peer_init_json_body", "qri_test_init_json_body")
Expand Down
62 changes: 27 additions & 35 deletions cmd/init.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cmd

import (
"os"
"path/filepath"
"strings"

Expand Down Expand Up @@ -46,8 +45,8 @@ already existing body file using the 'body' flag.`,
}

cmd.Flags().StringVar(&o.Name, "name", "", "name of the dataset")
cmd.Flags().StringVar(&o.Format, "format", "", "format of dataset")
cmd.Flags().StringVar(&o.SourceBodyPath, "body", "", "path to the body file")
cmd.Flags().StringVar(&o.Format, "format", "", "format of dataset body")
cmd.Flags().StringVar(&o.BodyPath, "body", "", "path to the body file")
cmd.Flags().BoolVarP(&o.UseDscache, "use-dscache", "", false, "experimental: build and use dscache if none exists")

return cmd
Expand All @@ -57,11 +56,16 @@ already existing body file using the 'body' flag.`,
type InitOptions struct {
ioes.IOStreams

Name string
Format string
SourceBodyPath string
Mkdir string
UseDscache bool
// Name of the dataset that will be created
Name string
// Format of the body
Format string
// Body file to initialize dataset with, if blank an example csv will be used
BodyPath string
// Path to use as a working directory. Will be created if it does not exist yet.
TargetDir string
// Experimental: Use dscache subsystem to store dataset references
UseDscache bool

DatasetMethods *lib.DatasetMethods
FSIMethods *lib.FSIMethods
Expand All @@ -73,48 +77,37 @@ func (o *InitOptions) Complete(f Factory, args []string) (err error) {
return err
}
o.FSIMethods, err = f.FSIMethods()
if len(args) > 0 && args[0] != "." {
o.Mkdir = args[0]
if len(args) > 0 {
o.TargetDir = args[0]
}
return err
}

// Run executes the `init` command
func (o *InitOptions) Run() (err error) {
pwd, err := os.Getwd()
if err != nil {
return err
}
targetDir := pwd
if o.Mkdir != "" {
targetDir = o.Mkdir
}

// First, check if the directory can be init'd, before prompting for any input
canInitParams := lib.InitFSIDatasetParams{
Dir: targetDir,
SourceBodyPath: o.SourceBodyPath,
canInitParams := lib.InitDatasetParams{
TargetDir: o.TargetDir,
BodyPath: o.BodyPath,
}
if err = o.FSIMethods.CanInitDatasetWorkDir(&canInitParams, nil); err != nil {
return err
}

// Suggestion for the dataset name defaults to directory it is being linked into
if o.Name == "" {
// TODO(dustmop): Currently all tests that call `init` use the --name flag. Add a test
// that receives stdin and checks what is written to stdout.
suggestedName := dsref.GenerateName(filepath.Base(targetDir), "dataset_")
suggestedName := dsref.GenerateName(filepath.Base(o.TargetDir), "dataset_")
o.Name = inputText(o.Out, o.In, "Name of new dataset", suggestedName)
}

// If user inputted there own dataset name, make sure it's valid.
// If user inputted their own dataset name, make sure it's valid.
if err := dsref.EnsureValidName(o.Name); err != nil {
return err
}

// If --body flag is set, use that to figure out the format
if o.SourceBodyPath != "" {
ext := filepath.Ext(o.SourceBodyPath)
if o.BodyPath != "" {
ext := filepath.Ext(o.BodyPath)
if strings.HasPrefix(ext, ".") {
ext = ext[1:]
}
Expand All @@ -125,13 +118,12 @@ func (o *InitOptions) Run() (err error) {
o.Format = inputText(o.Out, o.In, "Format of dataset, csv or json", "csv")
}

p := &lib.InitFSIDatasetParams{
Dir: pwd,
Mkdir: o.Mkdir,
Format: o.Format,
Name: o.Name,
SourceBodyPath: o.SourceBodyPath,
UseDscache: o.UseDscache,
p := &lib.InitDatasetParams{
TargetDir: o.TargetDir,
Format: o.Format,
Name: o.Name,
BodyPath: o.BodyPath,
UseDscache: o.UseDscache,
}
var refstr string
if err = o.FSIMethods.InitDataset(p, &refstr); err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/test_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ func (run *TestRunner) ExecCommand(cmdText string) error {
// ExecCommandWithStdin executes the given command string with the string as stdin content
func (run *TestRunner) ExecCommandWithStdin(ctx context.Context, cmdText, stdinText string) error {
setNoColor(true)
run.Streams.In = strings.NewReader(stdinText)
cmd, shutdown := NewQriCommand(ctx, run.RepoPath, run.RepoRoot.TestCrypto, run.Streams)
cmd.SetOutput(run.OutStream)
run.CmdR = cmd
Expand Down
Loading

0 comments on commit 878b7c4

Please sign in to comment.