Skip to content

Commit dd9b341

Browse files
committed
enhance sync
1 parent a560f97 commit dd9b341

File tree

4 files changed

+253
-232
lines changed

4 files changed

+253
-232
lines changed

cmd/sync.go

+92-22
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,36 @@ var syncCmd = &cobra.Command{
9494
}
9595
}
9696

97+
localFS := module.NewFileSystem()
98+
remoteFs := module.NewFileSystem()
99+
100+
err = localFS.LoadFromLocal(conf.Services.Directory, "toml")
101+
102+
if err != nil {
103+
fmt.Printf(
104+
"Error while reading local files inside %s: %s",
105+
conf.Services.Directory,
106+
err.Error(),
107+
)
108+
return
109+
}
110+
111+
localData, err := localFS.ConvertToJSON()
112+
113+
if err != nil {
114+
fmt.Printf(
115+
"Error while converting local files data to json %s: %s",
116+
conf.Services.Directory,
117+
err.Error(),
118+
)
119+
return
120+
}
121+
97122
if strings.TrimSpace(conf.Gist.GistID) == "" || !found {
98123
// Create github gist
99124
files := make(map[string]module.File)
100125
files["poodle"] = module.File{
101-
Content: "#",
126+
Content: localData,
102127
Filename: "poodle",
103128
}
104129

@@ -130,45 +155,90 @@ var syncCmd = &cobra.Command{
130155
}
131156
}
132157

133-
status, err := githubClient.GetSyncStatus(
134-
context.TODO(),
135-
conf.Services.Directory,
136-
conf.Gist.GistID,
137-
)
158+
remoteGist, err := githubClient.GetGist(context.TODO(), conf.Gist.GistID)
138159

139160
if err != nil {
140161
fmt.Printf(
141-
"Error while fetching sync status: %s",
162+
"Error while fetching remote gist: %s",
142163
err.Error(),
143164
)
144165
return
145166
}
146167

147-
if status == "upload" {
148-
ok, err = githubClient.SyncByUpload(
149-
context.TODO(),
150-
conf.Services.Directory,
151-
conf.Gist.GistID,
152-
)
168+
if _, found := remoteGist.Files["poodle"]; found {
169+
170+
ok, err = remoteFs.LoadFromJSON([]byte(remoteGist.Files["poodle"].Content))
171+
172+
if !ok || err != nil {
173+
fmt.Printf(
174+
"Error while loading remote fs from json: %s",
175+
err.Error(),
176+
)
177+
return
178+
}
179+
180+
err = localFS.Sync(remoteFs)
181+
182+
if err != nil {
183+
fmt.Printf(
184+
"Error while sync remote and local fs: %s",
185+
err.Error(),
186+
)
187+
return
188+
}
189+
190+
remoteData, err := remoteFs.ConvertToJSON()
191+
192+
if err != nil {
193+
fmt.Printf(
194+
"Error while converting remote data to json: %s",
195+
err.Error(),
196+
)
197+
return
198+
}
199+
200+
remoteGist.Files["poodle"] = module.File{
201+
Content: remoteData,
202+
Filename: "poodle",
203+
}
153204
} else {
154-
ok, err = githubClient.SyncByDownload(
155-
context.TODO(),
156-
conf.Services.Directory,
157-
conf.Gist.GistID,
205+
remoteGist.Files["poodle"] = module.File{
206+
Content: localData,
207+
Filename: "poodle",
208+
}
209+
}
210+
211+
fmt.Println(localFS.Files)
212+
213+
err = localFS.DumpLocally(conf.Services.Directory)
214+
215+
if err != nil {
216+
fmt.Printf(
217+
"Error while updating local files: %s",
218+
err.Error(),
158219
)
220+
return
159221
}
160222

161-
if !ok || err != nil {
223+
_, err = githubClient.UpdateGist(
224+
context.TODO(),
225+
conf.Gist.GistID,
226+
module.Gist{
227+
Description: "Poodle",
228+
Public: conf.Gist.Public,
229+
Files: remoteGist.Files,
230+
},
231+
)
232+
233+
if err != nil {
162234
fmt.Printf(
163-
"Error while syncing services definitions directory: %s",
235+
"Error while updating remote gist: %s",
164236
err.Error(),
165237
)
166238
return
167239
}
168240

169-
log.WithFields(log.Fields{
170-
"status": status,
171-
}).Debug("Sync Done")
241+
log.Debug("Sync Done")
172242

173243
spin.Stop()
174244

core/module/file_system.go

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright 2020 Clivern. All rights reserved.
2+
// Use of this source code is governed by the MIT
3+
// license that can be found in the LICENSE file.
4+
5+
package module
6+
7+
import (
8+
"encoding/json"
9+
"fmt"
10+
"os"
11+
"path/filepath"
12+
"strings"
13+
14+
"github.com/clivern/poodle/core/util"
15+
16+
"github.com/araddon/dateparse"
17+
)
18+
19+
// VFile struct
20+
type VFile struct {
21+
ModTimestamp int64
22+
Content string
23+
Name string
24+
}
25+
26+
// FileSystem struct
27+
type FileSystem struct {
28+
Files map[string]VFile
29+
}
30+
31+
// NewFileSystem creates a file system object
32+
func NewFileSystem() *FileSystem {
33+
return &FileSystem{
34+
Files: make(map[string]VFile),
35+
}
36+
}
37+
38+
// LoadFromLocal gets files from a local path
39+
func (f *FileSystem) LoadFromLocal(basePath string, extension string) error {
40+
41+
f.Files = make(map[string]VFile)
42+
basePath = util.RemoveTrailingSlash(basePath)
43+
44+
err := filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
45+
if err != nil {
46+
return err
47+
}
48+
49+
modifParsed, err := dateparse.ParseLocal(info.ModTime().String())
50+
51+
if err != nil {
52+
return err
53+
}
54+
55+
if basePath != path && !info.IsDir() && strings.Contains(path, extension) {
56+
file := strings.Replace(path, util.EnsureTrailingSlash(basePath), "", -1)
57+
58+
content, err := util.ReadFile(path)
59+
60+
if err != nil {
61+
return err
62+
}
63+
64+
f.Files[file] = VFile{
65+
ModTimestamp: modifParsed.Unix(),
66+
Content: content,
67+
Name: file,
68+
}
69+
}
70+
71+
return nil
72+
})
73+
74+
return err
75+
}
76+
77+
// DumpLocally updates a local path
78+
func (f *FileSystem) DumpLocally(basePath string) error {
79+
80+
for key, file := range f.Files {
81+
handler, err := os.Create(fmt.Sprintf(
82+
"%s%s",
83+
util.EnsureTrailingSlash(basePath),
84+
key,
85+
))
86+
87+
if err != nil {
88+
return err
89+
}
90+
91+
defer handler.Close()
92+
93+
handler.WriteString(file.Content)
94+
}
95+
96+
return nil
97+
}
98+
99+
// Sync update fs object from remote fs
100+
func (f *FileSystem) Sync(remoteFs *FileSystem) error {
101+
102+
for key, file := range f.Files {
103+
if v, found := remoteFs.Files[key]; found {
104+
105+
// Rewrite the remote file
106+
if file.ModTimestamp > v.ModTimestamp {
107+
remoteFs.Files[key] = file
108+
}
109+
110+
// Rewrite the local file
111+
if file.ModTimestamp < v.ModTimestamp {
112+
f.Files[key] = file
113+
}
114+
115+
} else {
116+
// File locally and missing remotely
117+
remoteFs.Files[key] = file
118+
}
119+
}
120+
121+
for key, file := range remoteFs.Files {
122+
if v, found := f.Files[key]; found {
123+
124+
// Rewrite the local file
125+
if file.ModTimestamp > v.ModTimestamp {
126+
f.Files[key] = file
127+
}
128+
129+
// Rewrite the remote file
130+
if file.ModTimestamp < v.ModTimestamp {
131+
remoteFs.Files[key] = file
132+
}
133+
134+
} else {
135+
// File remotely & not locally
136+
f.Files[key] = file
137+
}
138+
}
139+
140+
return nil
141+
}
142+
143+
// LoadFromJSON update object from json
144+
func (f *FileSystem) LoadFromJSON(data []byte) (bool, error) {
145+
err := json.Unmarshal(data, &f)
146+
if err != nil {
147+
return false, err
148+
}
149+
150+
return true, nil
151+
}
152+
153+
// ConvertToJSON convert object to json
154+
func (f *FileSystem) ConvertToJSON() (string, error) {
155+
data, err := json.Marshal(&f)
156+
if err != nil {
157+
return "", err
158+
}
159+
160+
return string(data), nil
161+
}

core/module/fs.go

-50
This file was deleted.

0 commit comments

Comments
 (0)