Remove fsrepo.At, make Open a constructor function
Nobody calls At without immediately calling Open. First step, a mechanical transformation. Cleanups will follow.
Tommi Virtanen committed
Mar 13, 2015 at 16:01 UTC
fdd1cd8dc045db90b06497a15df7f6f232f76bda
13 files changed
+87
-102
cmd/ipfs/daemon.go
+2
-2
@@ -118,8 +118,8 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
118
119
// acquire the repo lock _before_ constructing a node. we need to make
120
// sure we are permitted to access the resources (datastore, etc.)
121
- repo := fsrepo.At(req.Context().ConfigRoot)
122
- if err := repo.Open(); err != nil {
121
+ repo, err := fsrepo.Open(req.Context().ConfigRoot)
122
+ if err != nil {
123
res.SetError(debugerror.Errorf("Couldn't obtain lock. Is another daemon already running?"), cmds.ErrNormal)
124
return
125
}
cmd/ipfs/init.go
+4
-4
@@ -110,8 +110,8 @@ func addDefaultAssets(out io.Writer, repoRoot string) error {
110
ctx, cancel := context.WithCancel(context.Background())
111
defer cancel()
112
113
- r := fsrepo.At(repoRoot)
114
- if err := r.Open(); err != nil { // NB: repo is owned by the node
113
+ r, err := fsrepo.Open(repoRoot)
114
+ if err != nil { // NB: repo is owned by the node
115
return err
116
}
117
@@ -163,8 +163,8 @@ func initializeIpnsKeyspace(repoRoot string) error {
163
ctx, cancel := context.WithCancel(context.Background())
164
defer cancel()
165
166
- r := fsrepo.At(repoRoot)
167
- if err := r.Open(); err != nil { // NB: repo is owned by the node
166
+ r, err := fsrepo.Open(repoRoot)
167
+ if err != nil { // NB: repo is owned by the node
168
return err
169
}
170
cmd/ipfs/main.go
+2
-2
@@ -193,8 +193,8 @@ func (i *cmdInvocation) constructNodeFunc(ctx context.Context) func() (*core.Ipf
193
return nil, errors.New("constructing node without a request context")
194
}
195
196
- r := fsrepo.At(i.req.Context().ConfigRoot)
197
- if err := r.Open(); err != nil { // repo is owned by the node
196
+ r, err := fsrepo.Open(i.req.Context().ConfigRoot)
197
+ if err != nil { // repo is owned by the node
198
return nil, err
199
}
200
cmd/ipfs/tour.go
+2
-2
@@ -193,8 +193,8 @@ func tourGet(id tour.ID) (*tour.Topic, error) {
193
// TODO share func
194
func writeConfig(path string, cfg *config.Config) error {
195
// NB: This needs to run on the daemon.
196
- r := fsrepo.At(path)
197
- if err := r.Open(); err != nil {
196
+ r, err := fsrepo.Open(path)
197
+ if err != nil {
198
return err
199
}
200
defer r.Close()
cmd/ipfs_bootstrapd/main.go
+2
-2
@@ -57,8 +57,8 @@ func run() error {
57
}
58
}
59
60
- repo := fsrepo.At(repoPath)
61
- if err := repo.Open(); err != nil { // owned by node
60
+ repo, err := fsrepo.Open(repoPath)
61
+ if err != nil { // owned by node
62
return err
63
}
64
cmd/ipfs_routingd/main.go
+2
-2
@@ -57,8 +57,8 @@ func run() error {
57
return err
58
}
59
}
60
- repo := fsrepo.At(repoPath)
61
- if err := repo.Open(); err != nil { // owned by node
60
+ repo, err := fsrepo.Open(repoPath)
61
+ if err != nil { // owned by node
62
return err
63
}
64
cmd/ipfswatch/main.go
+2
-2
@@ -65,8 +65,8 @@ func run(ipfsPath, watchPath string) error {
65
return err
66
}
67
68
- r := fsrepo.At(ipfsPath)
69
- if err := r.Open(); err != nil {
68
+ r, err := fsrepo.Open(ipfsPath)
69
+ if err != nil {
70
// TODO handle case: daemon running
71
// TODO handle case: repo doesn't exist or isn't initialized
72
return err
core/commands/bootstrap.go
+6
-6
@@ -66,8 +66,8 @@ in the bootstrap list).
66
return
67
}
68
69
- r := fsrepo.At(req.Context().ConfigRoot)
70
- if err := r.Open(); err != nil {
69
+ r, err := fsrepo.Open(req.Context().ConfigRoot)
70
+ if err != nil {
71
res.SetError(err, cmds.ErrNormal)
72
return
73
}
@@ -143,8 +143,8 @@ var bootstrapRemoveCmd = &cmds.Command{
143
return
144
}
145
146
- r := fsrepo.At(req.Context().ConfigRoot)
147
- if err := r.Open(); err != nil {
146
+ r, err := fsrepo.Open(req.Context().ConfigRoot)
147
+ if err != nil {
148
res.SetError(err, cmds.ErrNormal)
149
return
150
}
@@ -192,8 +192,8 @@ var bootstrapListCmd = &cmds.Command{
192
},
193
194
Run: func(req cmds.Request, res cmds.Response) {
195
- r := fsrepo.At(req.Context().ConfigRoot)
196
- if err := r.Open(); err != nil {
195
+ r, err := fsrepo.Open(req.Context().ConfigRoot)
196
+ if err != nil {
197
res.SetError(err, cmds.ErrNormal)
198
return
199
}
core/commands/config.go
+4
-5
@@ -64,14 +64,13 @@ Set the value of the 'datastore.path' key:
64
args := req.Arguments()
65
key := args[0]
66
67
- r := fsrepo.At(req.Context().ConfigRoot)
68
- if err := r.Open(); err != nil {
67
+ r, err := fsrepo.Open(req.Context().ConfigRoot)
68
+ if err != nil {
69
res.SetError(err, cmds.ErrNormal)
70
return
71
}
72
defer r.Close()
73
74
- var err error
74
var output *ConfigField
75
if len(args) == 2 {
76
value := args[1]
@@ -182,8 +181,8 @@ can't be undone.
181
cmds.FileArg("file", true, false, "The file to use as the new config"),
182
},
183
Run: func(req cmds.Request, res cmds.Response) {
185
- r := fsrepo.At(req.Context().ConfigRoot)
186
- if err := r.Open(); err != nil {
184
+ r, err := fsrepo.Open(req.Context().ConfigRoot)
185
+ if err != nil {
186
res.SetError(err, cmds.ErrNormal)
187
return
188
}
repo/fsrepo/fsrepo.go
+42
-43
@@ -75,13 +75,51 @@ type FSRepo struct {
75
76
var _ repo.Repo = (*FSRepo)(nil)
77
78
-// At returns a handle to an FSRepo at the provided |path|.
79
-func At(repoPath string) *FSRepo {
80
- // This method must not have side-effects.
81
- return &FSRepo{
78
+// Open the FSRepo at path. Returns an error if the repo is not
79
+// initialized.
80
+func Open(repoPath string) (*FSRepo, error) {
81
+ packageLock.Lock()
82
+ defer packageLock.Unlock()
83
+
84
+ r := &FSRepo{
85
path: path.Clean(repoPath),
86
state: unopened, // explicitly set for clarity
87
}
88
+
89
+ expPath, err := u.TildeExpansion(r.path)
90
+ if err != nil {
91
+ return nil, err
92
+ }
93
+ r.path = expPath
94
+
95
+ if r.state != unopened {
96
+ return nil, debugerror.Errorf("repo is %s", r.state)
97
+ }
98
+ if !isInitializedUnsynced(r.path) {
99
+ return nil, debugerror.New("ipfs not initialized, please run 'ipfs init'")
100
+ }
101
+ // check repo path, then check all constituent parts.
102
+ // TODO acquire repo lock
103
+ // TODO if err := initCheckDir(logpath); err != nil { // }
104
+ if err := dir.Writable(r.path); err != nil {
105
+ return nil, err
106
+ }
107
+
108
+ if err := r.openConfig(); err != nil {
109
+ return nil, err
110
+ }
111
+
112
+ if err := r.openDatastore(); err != nil {
113
+ return nil, err
114
+ }
115
+
116
+ // log.Debugf("writing eventlogs to ...", c.path)
117
+ configureEventLoggerAtRepoPath(r.config, r.path)
118
+
119
+ if err := r.transitionToOpened(); err != nil {
120
+ return nil, err
121
+ }
122
+ return r, nil
123
}
124
125
// ConfigAt returns an error if the FSRepo at the given path is not
@@ -236,45 +274,6 @@ func configureEventLoggerAtRepoPath(c *config.Config, repoPath string) {
274
eventlog.Configure(eventlog.OutputRotatingLogFile(rotateConf))
275
}
276
239
-// Open returns an error if the repo is not initialized.
240
-func (r *FSRepo) Open() error {
241
-
242
- packageLock.Lock()
243
- defer packageLock.Unlock()
244
-
245
- expPath, err := u.TildeExpansion(r.path)
246
- if err != nil {
247
- return err
248
- }
249
- r.path = expPath
250
-
251
- if r.state != unopened {
252
- return debugerror.Errorf("repo is %s", r.state)
253
- }
254
- if !isInitializedUnsynced(r.path) {
255
- return debugerror.New("ipfs not initialized, please run 'ipfs init'")
256
- }
257
- // check repo path, then check all constituent parts.
258
- // TODO acquire repo lock
259
- // TODO if err := initCheckDir(logpath); err != nil { // }
260
- if err := dir.Writable(r.path); err != nil {
261
- return err
262
- }
263
-
264
- if err := r.openConfig(); err != nil {
265
- return err
266
- }
267
-
268
- if err := r.openDatastore(); err != nil {
269
- return err
270
- }
271
-
272
- // log.Debugf("writing eventlogs to ...", c.path)
273
- configureEventLoggerAtRepoPath(r.config, r.path)
274
-
275
- return r.transitionToOpened()
276
-}
277
-
277
func (r *FSRepo) closeDatastore() error {
278
dsLock.Lock()
279
defer dsLock.Unlock()
repo/fsrepo/fsrepo_test.go
+15
-28
@@ -33,19 +33,6 @@ func TestRemove(t *testing.T) {
33
assert.Nil(Remove(path), t, "can remove a repository")
34
}
35
36
-func TestCannotBeReopened(t *testing.T) {
37
- t.Parallel()
38
- path := testRepoPath("", t)
39
- assert.Nil(Init(path, &config.Config{}), t)
40
- r := At(path)
41
- assert.Nil(r.Open(), t)
42
- assert.Nil(r.Close(), t)
43
- assert.Err(r.Open(), t, "shouldn't be possible to re-open the repo")
44
-
45
- // mutable state is the enemy. Take Close() as an opportunity to reduce
46
- // entropy. Callers ought to start fresh with a new handle by calling `At`.
47
-}
48
-
36
func TestCanManageReposIndependently(t *testing.T) {
37
t.Parallel()
38
pathA := testRepoPath("a", t)
@@ -60,10 +47,10 @@ func TestCanManageReposIndependently(t *testing.T) {
47
assert.True(IsInitialized(pathB), t, "b should be initialized")
48
49
t.Log("open the two repos")
63
- repoA := At(pathA)
64
- repoB := At(pathB)
65
- assert.Nil(repoA.Open(), t, "a")
66
- assert.Nil(repoB.Open(), t, "b")
50
+ repoA, err := Open(pathA)
51
+ assert.Nil(err, t, "a")
52
+ repoB, err := Open(pathB)
53
+ assert.Nil(err, t, "b")
54
55
t.Log("close and remove b while a is open")
56
assert.Nil(repoB.Close(), t, "close b")
@@ -80,15 +67,15 @@ func TestDatastoreGetNotAllowedAfterClose(t *testing.T) {
67
68
assert.True(!IsInitialized(path), t, "should NOT be initialized")
69
assert.Nil(Init(path, &config.Config{}), t, "should initialize successfully")
83
- r := At(path)
84
- assert.Nil(r.Open(), t, "should open successfully")
70
+ r, err := Open(path)
71
+ assert.Nil(err, t, "should open successfully")
72
73
k := "key"
74
data := []byte(k)
75
assert.Nil(r.Datastore().Put(datastore.NewKey(k), data), t, "Put should be successful")
76
77
assert.Nil(r.Close(), t)
91
- _, err := r.Datastore().Get(datastore.NewKey(k))
78
+ _, err = r.Datastore().Get(datastore.NewKey(k))
79
assert.Err(err, t, "after closer, Get should be fail")
80
}
81
@@ -97,16 +84,16 @@ func TestDatastorePersistsFromRepoToRepo(t *testing.T) {
84
path := testRepoPath("test", t)
85
86
assert.Nil(Init(path, &config.Config{}), t)
100
- r1 := At(path)
101
- assert.Nil(r1.Open(), t)
87
+ r1, err := Open(path)
88
+ assert.Nil(err, t)
89
90
k := "key"
91
expected := []byte(k)
92
assert.Nil(r1.Datastore().Put(datastore.NewKey(k), expected), t, "using first repo, Put should be successful")
93
assert.Nil(r1.Close(), t)
94
108
- r2 := At(path)
109
- assert.Nil(r2.Open(), t)
95
+ r2, err := Open(path)
96
+ assert.Nil(err, t)
97
v, err := r2.Datastore().Get(datastore.NewKey(k))
98
assert.Nil(err, t, "using second repo, Get should be successful")
99
actual, ok := v.([]byte)
@@ -120,10 +107,10 @@ func TestOpenMoreThanOnceInSameProcess(t *testing.T) {
107
path := testRepoPath("", t)
108
assert.Nil(Init(path, &config.Config{}), t)
109
123
- r1 := At(path)
124
- r2 := At(path)
125
- assert.Nil(r1.Open(), t, "first repo should open successfully")
126
- assert.Nil(r2.Open(), t, "second repo should open successfully")
110
+ r1, err := Open(path)
111
+ assert.Nil(err, t, "first repo should open successfully")
112
+ r2, err := Open(path)
113
+ assert.Nil(err, t, "second repo should open successfully")
114
assert.True(r1.ds == r2.ds, t, "repos should share the datastore")
115
116
assert.Nil(r1.Close(), t)
test/supernode_client/main.go
+2
-2
@@ -66,8 +66,8 @@ func run() error {
66
repoPath := gopath.Join(cwd, ".go-ipfs")
67
if err := ensureRepoInitialized(repoPath); err != nil {
68
}
69
- repo := fsrepo.At(repoPath)
70
- if err := repo.Open(); err != nil { // owned by node
69
+ repo, err := fsrepo.Open(repoPath)
70
+ if err != nil { // owned by node
71
return err
72
}
73
cfg := repo.Config()
updates/updates.go
+2
-2
@@ -212,8 +212,8 @@ func CliCheckForUpdates(cfg *config.Config, repoPath string) error {
212
// if we checked successfully.
213
if err == ErrNoUpdateAvailable {
214
log.Noticef("No update available, checked on %s", time.Now())
215
- r := fsrepo.At(repoPath)
216
- if err := r.Open(); err != nil {
215
+ r, err := fsrepo.Open(repoPath)
216
+ if err != nil {
217
return err
218
}
219
if err := recordUpdateCheck(cfg); err != nil {