Skip to content

Commit 6989cf6

Browse files
authored
feat(logbook): write push & pull operations, add logbook summary output format
Merge pull request #1426 from qri-io/log_populate_published
2 parents b293695 + a59725d commit 6989cf6

File tree

19 files changed

+516
-316
lines changed

19 files changed

+516
-316
lines changed

base/log_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func TestDatasetLogForeign(t *testing.T) {
9292
ref.Path = "QmExample"
9393
foreignBuilder.Commit(ctx, t, initID, "their commit", ref.Path)
9494
foreignBook := foreignBuilder.Logbook()
95-
foreignLog, err := foreignBook.UserDatasetRef(ctx, ref)
95+
foreignLog, err := foreignBook.UserDatasetBranchesLog(ctx, initID)
9696
if err != nil {
9797
t.Fatal(err)
9898
}

cmd/log.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,17 @@ The logbook command shows entries for a dataset, from newest to oldest.`,
159159
}
160160
if o.Raw {
161161
return o.RawLogs()
162+
} else if o.Summary {
163+
return o.LogbookSummary()
162164
}
163165
return o.Logbook()
164166
},
165167
}
166168

167-
// cmd.Flags().StringVarP(&o.Format, "format", "f", "", "set output format [json]")
168169
cmd.Flags().IntVar(&o.PageSize, "page-size", 25, "page size of results, default 25")
169170
cmd.Flags().IntVar(&o.Page, "page", 1, "page number of results, default 1")
170171
cmd.Flags().BoolVar(&o.Raw, "raw", false, "full logbook in raw JSON format. overrides all other flags")
172+
cmd.Flags().BoolVar(&o.Summary, "summary", false, "print one oplog per line in the format 'MODEL ID OPCOUNT NAME'. overrides all other flags")
171173

172174
return cmd
173175
}
@@ -176,17 +178,21 @@ The logbook command shows entries for a dataset, from newest to oldest.`,
176178
type LogbookOptions struct {
177179
ioes.IOStreams
178180

179-
PageSize int
180-
Page int
181-
Refs *RefSelect
182-
Raw bool
181+
PageSize int
182+
Page int
183+
Refs *RefSelect
184+
Raw, Summary bool
183185

184186
LogMethods *lib.LogMethods
185187
}
186188

187189
// Complete adds any missing configuration that can only be added just before calling Run
188190
func (o *LogbookOptions) Complete(f Factory, args []string) (err error) {
189-
if o.Raw {
191+
if o.Raw && o.Summary {
192+
return fmt.Errorf("cannot use summary & raw flags at once")
193+
}
194+
195+
if o.Raw || o.Summary {
190196
if len(args) != 0 {
191197
return fmt.Errorf("can't use dataset reference. the raw flag shows the entire logbook")
192198
}
@@ -248,3 +254,14 @@ func (o *LogbookOptions) RawLogs() error {
248254
printToPager(o.Out, bytes.NewBuffer(data))
249255
return nil
250256
}
257+
258+
// LogbookSummary prints a logbook overview
259+
func (o *LogbookOptions) LogbookSummary() error {
260+
var res string
261+
if err := o.LogMethods.LogbookSummary(&struct{}{}, &res); err != nil {
262+
return err
263+
}
264+
265+
printToPager(o.Out, bytes.NewBufferString(res))
266+
return nil
267+
}

cmd/save.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ commit message and title to the save.`,
6767
cmd.Flags().StringVarP(&o.Recall, "recall", "", "", "restore revisions from dataset history")
6868
// cmd.Flags().BoolVarP(&o.ShowValidation, "show-validation", "s", false, "display a list of validation errors upon adding")
6969
cmd.Flags().StringSliceVar(&o.Secrets, "secrets", nil, "transform secrets as comma separated key,value,key,value,... sequence")
70-
cmd.Flags().BoolVarP(&o.Publish, "publish", "p", false, "publish this dataset to the registry")
7170
cmd.Flags().BoolVar(&o.DryRun, "dry-run", false, "simulate saving a dataset")
7271
cmd.Flags().BoolVar(&o.Force, "force", false, "force a new commit, even if no changes are detected")
7372
cmd.Flags().BoolVarP(&o.KeepFormat, "keep-format", "k", false, "convert incoming data to stored data format")
@@ -95,7 +94,6 @@ type SaveOptions struct {
9594

9695
Replace bool
9796
ShowValidation bool
98-
Publish bool
9997
DryRun bool
10098
KeepFormat bool
10199
Force bool
@@ -158,7 +156,6 @@ func (o *SaveOptions) Run() (err error) {
158156
ScriptOutput: o.ErrOut,
159157
FilePaths: o.FilePaths,
160158
Private: false,
161-
Publish: o.Publish,
162159
DryRun: o.DryRun,
163160
Recall: o.Recall,
164161
Drop: o.Drop,

cmd/save_test.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,22 +126,21 @@ func TestSaveRun(t *testing.T) {
126126
bodypath string
127127
title string
128128
message string
129-
publish bool
130129
dryrun bool
131130
noRender bool
132131
expect string
133132
err string
134133
msg string
135134
}{
136-
{"no data", "me/bad_dataset", "", "", "", "", false, false, true, "", "no changes to save", ""},
137-
{"bad dataset file", "me/cities", "bad/filpath.json", "", "", "", false, false, true, "", "open bad/filpath.json: no such file or directory", ""},
138-
{"bad body file", "me/cities", "", "bad/bodypath.csv", "", "", false, false, true, "", "opening dataset.bodyPath 'bad/bodypath.csv': path not found", ""},
139-
{"good inputs, dryrun", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_ten.csv", "", "", false, true, true, "dataset saved: peer/movies\n", "", ""},
140-
{"good inputs", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_ten.csv", "", "", true, false, true, "dataset saved: peer/movies@/map/QmVDSrf4BpupXYmDJc6eXanFVW9DS6g3Pfkkx6YqkcUjEQ\nthis dataset has 1 validation errors\n", "", ""},
141-
{"add rows, dry run", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_twenty.csv", "Added 10 more rows", "Adding to the number of rows in dataset", false, true, true, "dataset saved: peer/movies\n", "", ""},
142-
{"add rows, save", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_twenty.csv", "Added 10 more rows", "Adding to the number of rows in dataset", true, false, true, "dataset saved: peer/movies@/map/QmZof1Gc95VFxaAXBq28pTYLe4nQ3TMi4ceBL7ExDkXyyj\nthis dataset has 1 validation errors\n", "", ""},
143-
{"no changes", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_twenty.csv", "trying to add again", "hopefully this errors", false, false, true, "", "error saving: no changes", ""},
144-
{"add viz", "me/movies", "testdata/movies/dataset_with_viz.json", "", "", "", false, false, false, "dataset saved: peer/movies@/map/QmXDJLrEePbBGro5m9K9edszqN89XMePrampGhBq7QkyoF\nthis dataset has 1 validation errors\n", "", ""},
135+
{"no data", "me/bad_dataset", "", "", "", "", false, true, "", "no changes to save", ""},
136+
{"bad dataset file", "me/cities", "bad/filpath.json", "", "", "", false, true, "", "open bad/filpath.json: no such file or directory", ""},
137+
{"bad body file", "me/cities", "", "bad/bodypath.csv", "", "", false, true, "", "opening dataset.bodyPath 'bad/bodypath.csv': path not found", ""},
138+
{"good inputs, dryrun", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_ten.csv", "", "", true, true, "dataset saved: peer/movies\n", "", ""},
139+
{"good inputs", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_ten.csv", "", "", false, true, "dataset saved: peer/movies@/map/QmVDSrf4BpupXYmDJc6eXanFVW9DS6g3Pfkkx6YqkcUjEQ\nthis dataset has 1 validation errors\n", "", ""},
140+
{"add rows, dry run", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_twenty.csv", "Added 10 more rows", "Adding to the number of rows in dataset", true, true, "dataset saved: peer/movies\n", "", ""},
141+
{"add rows, save", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_twenty.csv", "Added 10 more rows", "Adding to the number of rows in dataset", false, true, "dataset saved: peer/movies@/map/QmZof1Gc95VFxaAXBq28pTYLe4nQ3TMi4ceBL7ExDkXyyj\nthis dataset has 1 validation errors\n", "", ""},
142+
{"no changes", "me/movies", "testdata/movies/dataset.json", "testdata/movies/body_twenty.csv", "trying to add again", "hopefully this errors", false, true, "", "error saving: no changes", ""},
143+
{"add viz", "me/movies", "testdata/movies/dataset_with_viz.json", "", "", "", false, false, "dataset saved: peer/movies@/map/QmXDJLrEePbBGro5m9K9edszqN89XMePrampGhBq7QkyoF\nthis dataset has 1 validation errors\n", "", ""},
145144
}
146145

147146
for _, c := range cases {
@@ -164,7 +163,6 @@ func TestSaveRun(t *testing.T) {
164163
BodyPath: c.bodypath,
165164
Title: c.title,
166165
Message: c.message,
167-
Publish: c.publish,
168166
DryRun: c.dryrun,
169167
NoRender: c.noRender,
170168
DatasetMethods: dsm,

dsref/spec/resolve.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,7 @@ func GenerateExampleOplog(ctx context.Context, journal *logbook.Book, dsname, he
208208
return "", nil, err
209209
}
210210

211-
// TODO (b5) - we need UserDatasetRef here b/c it returns the full hierarchy
212-
// of oplogs. This method should take an InitID
213-
lg, err := journal.UserDatasetRef(ctx, dsref.Ref{Username: username, Name: dsname})
211+
lg, err := journal.UserDatasetBranchesLog(ctx, initID)
214212
if err != nil {
215213
return "", nil, err
216214
}

lib/datasets.go

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ type SaveParams struct {
434434
// option to make dataset private. private data is not currently implimented,
435435
// see https://github.com/qri-io/qri/issues/291 for updates
436436
Private bool
437-
// if true, set saved dataset to published
438-
Publish bool
439437
// run without saving, returning results
440438
DryRun bool
441439
// if true, res.Dataset.Body will be a fs.file of the body
@@ -725,23 +723,6 @@ func (m *DatasetMethods) Save(p *SaveParams, res *reporef.DatasetRef) error {
725723
}
726724
}
727725

728-
if p.Publish {
729-
if p.DryRun {
730-
return fmt.Errorf("can't use publish & dry-run together")
731-
}
732-
var publishedRef reporef.DatasetRef
733-
err = m.SetPublishStatus(&SetPublishStatusParams{
734-
Ref: datasetRef.String(),
735-
PublishStatus: true,
736-
// UpdateRegistry: true,
737-
// UpdateRegistryPin: true,
738-
}, &publishedRef)
739-
740-
if err != nil {
741-
return err
742-
}
743-
}
744-
745726
*res = datasetRef
746727

747728
if fsiPath != "" && !p.DryRun {
@@ -770,37 +751,6 @@ func (m *DatasetMethods) nameIsInUse(ctx context.Context, ref dsref.Ref) bool {
770751
return true
771752
}
772753

773-
// SetPublishStatusParams encapsulates parameters for setting the publication status of a dataset
774-
type SetPublishStatusParams struct {
775-
Ref string
776-
PublishStatus bool
777-
// UpdateRegistry bool
778-
// UpdateRegistryPin bool
779-
}
780-
781-
// SetPublishStatus updates the publicity of a reference in the peer's namespace
782-
func (m *DatasetMethods) SetPublishStatus(p *SetPublishStatusParams, publishedRef *reporef.DatasetRef) error {
783-
if m.inst.rpc != nil {
784-
return checkRPCError(m.inst.rpc.Call("DatasetMethods.SetPublishStatus", p, publishedRef))
785-
}
786-
787-
ref, err := repo.ParseDatasetRef(p.Ref)
788-
if err != nil {
789-
return err
790-
}
791-
if err = repo.CanonicalizeDatasetRef(m.inst.repo, &ref); err != nil {
792-
return err
793-
}
794-
795-
ref.Published = p.PublishStatus
796-
if err = base.SetPublishStatus(m.inst.repo, &ref, ref.Published); err != nil {
797-
return err
798-
}
799-
800-
*publishedRef = ref
801-
return nil
802-
}
803-
804754
// RenameParams defines parameters for Dataset renaming
805755
type RenameParams struct {
806756
Current, Next string
@@ -1059,16 +1009,9 @@ func (m *DatasetMethods) Add(p *AddParams, res *reporef.DatasetRef) error {
10591009
p.RemoteAddr = m.inst.cfg.Registry.Location
10601010
}
10611011

1062-
mergeLogsError := m.inst.remoteClient.CloneLogs(ctx, ref, p.RemoteAddr)
1063-
// TODO(b5) - this line is swallowing errors that the cmd package integration
1064-
// tests are hitting. We need to change the behaviour of add to *require* logs
1065-
// successfully merge, which will require fixing lots of tests in cmd,
1066-
// ideally by removing remote.MockRepoClient
1067-
if p.LogsOnly {
1068-
return mergeLogsError
1069-
}
1070-
if mergeLogsError != nil {
1071-
return mergeLogsError
1012+
if err := m.inst.remoteClient.CloneLogs(ctx, ref, p.RemoteAddr); err != nil {
1013+
log.Error(err)
1014+
return err
10721015
}
10731016

10741017
rref := reporef.RefFromDsref(ref)

lib/integration_test.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,17 @@ func TestReferencePulling(t *testing.T) {
132132
ref := InitWorldBankDataset(t, nasim)
133133
PublishToRegistry(t, nasim, ref.AliasString())
134134

135+
// - nasim's local repo should reflect publication
136+
logRes := []DatasetLogItem{}
137+
err := NewLogMethods(nasim).Log(&LogParams{Ref: ref.AliasString(), ListParams: ListParams{Limit: 1}}, &logRes)
138+
if err != nil {
139+
t.Fatal(err)
140+
}
141+
142+
if logRes[0].Published != true {
143+
t.Errorf("nasim has published HEAD. ref[0] published is false")
144+
}
145+
135146
hinshun := tr.InitHinshun(t)
136147
sqlm := NewSQLMethods(hinshun)
137148

@@ -162,7 +173,7 @@ func TestReferencePulling(t *testing.T) {
162173
dsm := NewDatasetMethods(adnan)
163174

164175
// run a transform script that relies on world_bank_population, which adnan's
165-
// node should automatically pull to execute thisscript
176+
// node should automatically pull to execute this script
166177
tfScriptData := `
167178
wbp = load_dataset("nasim/world_bank_population")
168179
@@ -185,6 +196,17 @@ def transform(ds, ctx):
185196
if err := dsm.Save(saveParams, res); err != nil {
186197
t.Fatal(err)
187198
}
199+
200+
// - adnan's local repo should reflect nasim's publication
201+
logRes = []DatasetLogItem{}
202+
err = NewLogMethods(adnan).Log(&LogParams{Ref: ref.AliasString(), ListParams: ListParams{Limit: 1}}, &logRes)
203+
if err != nil {
204+
t.Fatal(err)
205+
}
206+
207+
if logRes[0].Published != true {
208+
t.Errorf("adnan's log expects head was published, ref[0] published is false")
209+
}
188210
}
189211

190212
type NetworkIntegrationTestRunner struct {
@@ -364,8 +386,7 @@ func AssertLogsEqual(a, b *Instance, ref *reporef.DatasetRef) error {
364386
func InitWorldBankDataset(t *testing.T, inst *Instance) *reporef.DatasetRef {
365387
res := &reporef.DatasetRef{}
366388
err := NewDatasetMethods(inst).Save(&SaveParams{
367-
Publish: true,
368-
Ref: "me/world_bank_population",
389+
Ref: "me/world_bank_population",
369390
Dataset: &dataset.Dataset{
370391
Meta: &dataset.Meta{
371392
Title: "World Bank Population",
@@ -390,8 +411,7 @@ d,e,f,false,3`),
390411
func Commit2WorldBank(t *testing.T, inst *Instance) *reporef.DatasetRef {
391412
res := &reporef.DatasetRef{}
392413
err := NewDatasetMethods(inst).Save(&SaveParams{
393-
Publish: true,
394-
Ref: "me/world_bank_population",
414+
Ref: "me/world_bank_population",
395415
Dataset: &dataset.Dataset{
396416
Meta: &dataset.Meta{
397417
Title: "World Bank Population",

lib/log.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,6 @@ func (m *LogMethods) Log(params *LogParams, res *[]DatasetLogItem) error {
114114
}
115115
}
116116

117-
// TODO (b5) - store logs on pull
118-
// if params.Pull {
119-
// }
120-
121117
*res = items
122118
return nil
123119
}
@@ -163,12 +159,21 @@ type PlainLogsParams struct {
163159
type PlainLogs = []logbook.PlainLog
164160

165161
// PlainLogs encodes the full logbook as human-oriented json
166-
func (m *LogMethods) PlainLogs(p *PlainLogsParams, res *PlainLogs) error {
167-
var err error
162+
func (m *LogMethods) PlainLogs(p *PlainLogsParams, res *PlainLogs) (err error) {
168163
if m.inst.rpc != nil {
169164
return checkRPCError(m.inst.rpc.Call("LogMethods.PlainLogs", p, res))
170165
}
171166
ctx := context.TODO()
172167
*res, err = m.inst.repo.Logbook().PlainLogs(ctx)
173168
return err
174169
}
170+
171+
// LogbookSummary returns a string overview of the logbook
172+
func (m *LogMethods) LogbookSummary(p *struct{}, res *string) (err error) {
173+
if m.inst.rpc != nil {
174+
return checkRPCError(m.inst.rpc.Call("LogMethods.Diagnostic", p, res))
175+
}
176+
ctx := context.TODO()
177+
*res = m.inst.repo.Logbook().SummaryString(ctx)
178+
return nil
179+
}

lib/remote.go

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,18 @@ func (r *RemoteMethods) Publish(p *PublicationParams, res *dsref.Ref) error {
4545
return checkRPCError(r.inst.rpc.Call("RemoteMethods.Publish", p, res))
4646
}
4747

48-
ref, err := repo.ParseDatasetRef(p.Ref)
48+
// TODO (b5) - need contexts yo
49+
ctx := context.TODO()
50+
51+
ref, err := dsref.Parse(p.Ref)
4952
if err != nil {
5053
return err
5154
}
5255
if ref.Path != "" {
5356
return fmt.Errorf("can only publish entire dataset, cannot use version %s", ref.Path)
5457
}
55-
if err = repo.CanonicalizeDatasetRef(r.inst.Repo(), &ref); err != nil {
58+
59+
if _, err := r.inst.ResolveReference(ctx, &ref, "local"); err != nil {
5660
return err
5761
}
5862

@@ -61,27 +65,26 @@ func (r *RemoteMethods) Publish(p *PublicationParams, res *dsref.Ref) error {
6165
return err
6266
}
6367

64-
// TODO (b5) - need contexts yo
65-
ctx := context.TODO()
66-
67-
// TODO (b5) - we're early in log syncronization days. This is going to fail a bunch
68-
// while we work to upgrade the stack. Long term we may want to consider a mechanism
69-
// for allowing partial completion where only one of logs or dataset pushing works
70-
// by doing both in parallel and reporting issues on both
71-
if pushLogsErr := r.inst.RemoteClient().PushLogs(ctx, reporef.ConvertToDsref(ref), addr); pushLogsErr != nil {
72-
log.Errorf("pushing logs: %s", pushLogsErr)
68+
if err = r.inst.RemoteClient().PushLogs(ctx, ref, addr); err != nil {
69+
return err
7370
}
7471

75-
if err = r.inst.RemoteClient().PushDataset(ctx, ref, addr); err != nil {
72+
// TODO (b5) - another example of where reference resolution needs to set
73+
// the profileID, and isn't. the conversion to a reporef & dataset push will
74+
// fail if profileID isn't specified
75+
pro, _ := r.inst.Repo().Profile()
76+
ref.ProfileID = pro.ID.String()
77+
78+
datasetRef := reporef.RefFromDsref(ref)
79+
if err = r.inst.RemoteClient().PushDataset(ctx, datasetRef, addr); err != nil {
7680
return err
7781
}
78-
79-
ref.Published = true
80-
if err = base.SetPublishStatus(r.inst.node.Repo, &ref, ref.Published); err != nil {
82+
datasetRef.Published = true
83+
if err = base.SetPublishStatus(r.inst.node.Repo, &datasetRef, datasetRef.Published); err != nil {
8184
return err
8285
}
8386

84-
*res = reporef.ConvertToDsref(ref)
87+
*res = ref
8588
return nil
8689
}
8790

0 commit comments

Comments
 (0)