Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for InputField (used for new "Enjoy Life Forever!" brochure) #52

Merged
merged 11 commits into from
Mar 21, 2021
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ is only usable for Notes). As their names suggest, `chooseLeft` and
`chooseRight` will always choose the same side if a conflict occurs, while
`chooseNewest` always chooses the newest entry.

You can enable these solvers with the `--bookmarks`, `--markings`, and
`--notes` flags:
You can enable these solvers with the `--bookmarks`, `--markings`,
`--notes`, and `--inputFields` flags:

```shell
go-jwlm merge <left-backup> <right-backup> <merged-backup> --bookmarks chooseLeft --markings chooseRight --notes chooseNewest
go-jwlm merge <left-backup> <right-backup> <merged-backup> --bookmarks chooseLeft --markings chooseRight --notes chooseNewest --inputFields chooseLef
```

The conflict resolvers are helpful for regular merging when you are
Expand Down Expand Up @@ -77,8 +77,8 @@ See the instructions on how to install Homebrew at https://brew.sh
## Mobile version
If you want to merge backups using your iPhone or iPad, have a look at
[JWLM](https://github.com/AndreasSko/ios-jwlm). It uses the whole merge
logic of go-jwlm, but wraps it in a nice and easy to use iOS app. It is still
in beta, but volunteers for testing are always welcome!
logic of go-jwlm, but wraps it in a nice and easy to use iOS app. It is
already available on the [App Store](https://apps.apple.com/us/app/jwlm-jw-library-merger/id1539780103).

There might come an Android version at some point, but as I personally
don't use any Android devices, it is - unfortunately - not the highest
Expand Down
2 changes: 1 addition & 1 deletion cmd/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"github.com/AlecAivazis/survey/v2/terminal"
expect "github.com/Netflix/go-expect"
"github.com/tj/assert"
"github.com/stretchr/testify/assert"
)

func Test_compare(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions cmd/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ func mergeConflictHelp(name string) string {
"*model.Note": `A note collides if it exists on both sides (so they must have been synced at least once)
and it differers in the title or content. It generally makes sense to choose the note
with the newest date.`,

"*model.InputField": `InputFields are used in interactive publications where you can enter custom notes,
tick boxes, etc. An example would be the "Enjoy Life Forever!" brochure.`,
}

if text, ok := helpTexts[name]; ok {
Expand Down
37 changes: 36 additions & 1 deletion cmd/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ be included in the merged backup. You are able to let the merger
automatically solve conflicts using the 'chooseLeft', 'chooseRight', and
'chooseNewest' resolvers (see Flags).`,
Example: `go-jwlm merge left.jwlibrary right.jwlibrary merged.jwlibrary
go-jwlm merge left.jwlibrary right.jwlibrary merged.jwlibrary --bookmarks chooseLeft --markings chooseRight --notes chooseNewest`,
go-jwlm merge left.jwlibrary right.jwlibrary merged.jwlibrary --bookmarks chooseLeft --markings chooseRight --notes chooseNewest --inputFields chooseRight`,
Run: func(cmd *cobra.Command, args []string) {
leftFilename := args[0]
rightFilename := args[1]
Expand All @@ -46,6 +46,9 @@ var MarkingResolver string
// NoteResolver represents a resolver that should be used for conflicting Notes
var NoteResolver string

// InputFieldResolver represents a resolver that should be used for conflicting InputFields
var InputFieldResolver string

func merge(leftFilename string, rightFilename string, mergedFilename string, stdio terminal.Stdio) {
fmt.Fprintln(stdio.Out, "Importing left backup")
left := model.Database{}
Expand All @@ -65,9 +68,13 @@ func merge(leftFilename string, rightFilename string, mergedFilename string, std

fmt.Fprintln(stdio.Out, "🧭 Merging Locations")
mergedLocations, locationIDChanges, err := merger.MergeLocations(left.Location, right.Location)
if err != nil {
log.Fatal(err)
}
merged.Location = mergedLocations
merger.UpdateLRIDs(left.Bookmark, right.Bookmark, "LocationID", locationIDChanges)
merger.UpdateLRIDs(left.Bookmark, right.Bookmark, "PublicationLocationID", locationIDChanges)
AndreasSko marked this conversation as resolved.
Show resolved Hide resolved
merger.UpdateLRIDs(left.InputField, right.InputField, "LocationID", locationIDChanges)
merger.UpdateLRIDs(left.Note, right.Note, "LocationID", locationIDChanges)
merger.UpdateLRIDs(left.TagMap, right.TagMap, "LocationID", locationIDChanges)
merger.UpdateLRIDs(left.UserMark, right.UserMark, "LocationID", locationIDChanges)
Expand Down Expand Up @@ -100,6 +107,33 @@ func merge(leftFilename string, rightFilename string, mergedFilename string, std
}
fmt.Fprintln(stdio.Out, "Done.")

fmt.Fprintln(stdio.Out, "✍️ Merging InputFields")
inputFieldConflictSolution := map[string]merger.MergeSolution{}
for {
mergedInputFields, _, err := merger.MergeInputFields(left.InputField, right.InputField, inputFieldConflictSolution)
if err == nil {
merged.InputField = mergedInputFields
break
}
switch err := err.(type) {
case merger.MergeConflictError:
if InputFieldResolver != "" {
var resErr error
newSolutions, resErr := merger.AutoResolveConflicts(err.Conflicts, InputFieldResolver)
if resErr != nil {
log.Fatal(resErr)
}
addToSolutions(inputFieldConflictSolution, newSolutions)
} else {
newSolutions := handleMergeConflict(err.Conflicts, &merged, stdio)
addToSolutions(inputFieldConflictSolution, newSolutions)
}
default:
log.Fatal(err)
}
}
fmt.Fprintln(stdio.Out, "Done.")

fmt.Fprintln(stdio.Out, "🏷 Merging Tags")
var tagsConflictSolution map[string]merger.MergeSolution
for {
Expand Down Expand Up @@ -277,4 +311,5 @@ func init() {
mergeCmd.Flags().StringVar(&BookmarkResolver, "bookmarks", "", "Resolve conflicting bookmarks with resolver (can be 'chooseLeft' or 'chooseRight')")
mergeCmd.Flags().StringVar(&MarkingResolver, "markings", "", "Resolve conflicting markings with resolver (can be 'chooseLeft' or 'chooseRight')")
mergeCmd.Flags().StringVar(&NoteResolver, "notes", "", "Resolve conflicting notes with resolver (can be 'chooseNewest', 'chooseLeft', or 'chooseRight')")
mergeCmd.Flags().StringVar(&InputFieldResolver, "inputFields", "", "Resolve conflicting inputFields with resolver (can be 'chooseLeft', or 'chooseRight')")
}
141 changes: 138 additions & 3 deletions cmd/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
"github.com/AndreasSko/go-jwlm/model"
expect "github.com/Netflix/go-expect"
"github.com/hinshun/vt10x"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tj/assert"
)

func Test_merge(t *testing.T) {
Expand Down Expand Up @@ -59,6 +59,9 @@ func Test_merge(t *testing.T) {
c.ExpectString("📑 Merging Bookmarks")
c.SendLine(string(terminal.KeyArrowDown))

c.ExpectString("✍️ Merging InputFields")
c.SendLine(string(terminal.KeyArrowDown))

c.ExpectString("🖍 Merging Markings")
c.SendLine(string(terminal.KeyArrowDown))

Expand All @@ -81,6 +84,9 @@ func Test_merge(t *testing.T) {
c.ExpectString("📑 Merging Bookmarks")
c.SendLine("")

c.ExpectString("✍️ Merging InputFields")
c.SendLine("")

c.ExpectString("🖍 Merging Markings")
c.SendLine("")

Expand Down Expand Up @@ -108,6 +114,7 @@ func Test_merge(t *testing.T) {
BookmarkResolver = "chooseRight"
MarkingResolver = "chooseRight"
NoteResolver = "chooseNewest"
InputFieldResolver = "chooseRight"
merge(leftFilename, rightFilename, mergedFilename,
terminal.Stdio{In: c.Tty(), Out: c.Tty(), Err: c.Tty()})
merged := &model.Database{}
Expand Down Expand Up @@ -197,6 +204,19 @@ var leftMultiCollision = &model.Database{
},
},
Bookmark: []*model.Bookmark{nil},
InputField: []*model.InputField{
nil,
{
LocationID: 1,
TextTag: "a1",
Value: "a1",
},
{
LocationID: 1,
TextTag: "a2",
Value: "a2",
},
},
Location: []*model.Location{
nil,
{
Expand Down Expand Up @@ -258,6 +278,24 @@ var rightMultiCollision = &model.Database{
},
},
Bookmark: []*model.Bookmark{nil},
InputField: []*model.InputField{
nil,
{
LocationID: 1,
TextTag: "a1",
Value: "different",
},
{
LocationID: 1,
TextTag: "a2",
Value: "a2",
},
{
LocationID: 1,
TextTag: "b1",
Value: "b1",
},
},
Location: []*model.Location{
nil,
{
Expand Down Expand Up @@ -311,6 +349,19 @@ var leftDB = &model.Database{
BlockIdentifier: sql.NullInt32{1, true},
},
},
InputField: []*model.InputField{
nil,
{
LocationID: 5,
TextTag: "a1",
Value: "a1",
},
{
LocationID: 5,
TextTag: "a2",
Value: "a2",
},
},
Location: []*model.Location{
nil,
{
Expand All @@ -328,6 +379,15 @@ var leftDB = &model.Database{
MepsLanguage: 2,
LocationType: 1,
},
nil,
nil,
{
LocationID: 5,
DocumentID: sql.NullInt32{1102021811, true},
KeySymbol: sql.NullString{"lffi", true},
MepsLanguage: 2,
LocationType: 0,
},
},
Note: []*model.Note{
nil,
Expand Down Expand Up @@ -445,6 +505,24 @@ var rightDB = &model.Database{
BlockIdentifier: sql.NullInt32{1, true},
},
},
InputField: []*model.InputField{
nil,
{
LocationID: 4,
TextTag: "a1",
Value: "different",
},
{
LocationID: 4,
TextTag: "a2",
Value: "a2",
},
{
LocationID: 4,
TextTag: "b1",
Value: "b1",
},
},
Location: []*model.Location{
nil,
{
Expand All @@ -471,6 +549,13 @@ var rightDB = &model.Database{
LocationType: 0,
Title: sql.NullString{"1. Mose 1", true},
},
{
LocationID: 4,
DocumentID: sql.NullInt32{1102021811, true},
KeySymbol: sql.NullString{"lffi", true},
MepsLanguage: 2,
LocationType: 0,
},
},
Note: []*model.Note{
nil,
Expand Down Expand Up @@ -558,7 +643,7 @@ var rightDB = &model.Database{
},
}

var mergedAllLeftDB = model.Database{
var mergedAllLeftDB = &model.Database{
BlockRange: []*model.BlockRange{
nil,
{
Expand Down Expand Up @@ -598,6 +683,24 @@ var mergedAllLeftDB = model.Database{
BlockIdentifier: sql.NullInt32{1, true},
},
},
InputField: []*model.InputField{
nil,
{
LocationID: 4,
TextTag: "a1",
Value: "a1",
},
{
LocationID: 4,
TextTag: "a2",
Value: "a2",
},
{
LocationID: 4,
TextTag: "b1",
Value: "b1",
},
},
Location: []*model.Location{
nil,
{
Expand All @@ -624,6 +727,13 @@ var mergedAllLeftDB = model.Database{
LocationType: 0,
Title: sql.NullString{"1. Mose 2", true},
},
{
LocationID: 4,
DocumentID: sql.NullInt32{1102021811, true},
KeySymbol: sql.NullString{"lffi", true},
MepsLanguage: 2,
LocationType: 0,
},
},
Note: []*model.Note{
nil,
Expand Down Expand Up @@ -731,7 +841,7 @@ var mergedAllLeftDB = model.Database{
},
}

var mergedAllRightDB = model.Database{
var mergedAllRightDB = &model.Database{
BlockRange: []*model.BlockRange{
nil,
{
Expand Down Expand Up @@ -779,6 +889,24 @@ var mergedAllRightDB = model.Database{
BlockIdentifier: sql.NullInt32{1, true},
},
},
InputField: []*model.InputField{
nil,
{
LocationID: 4,
TextTag: "a1",
Value: "different",
},
{
LocationID: 4,
TextTag: "a2",
Value: "a2",
},
{
LocationID: 4,
TextTag: "b1",
Value: "b1",
},
},
Location: []*model.Location{
nil,
{
Expand All @@ -805,6 +933,13 @@ var mergedAllRightDB = model.Database{
LocationType: 0,
Title: sql.NullString{"1. Mose 2", true},
},
{
LocationID: 4,
DocumentID: sql.NullInt32{1102021811, true},
KeySymbol: sql.NullString{"lffi", true},
MepsLanguage: 2,
LocationType: 0,
},
},
Note: []*model.Note{
nil,
Expand Down
Loading