Commit
+58 -45 +/-5 browse
1 | diff --git a/config.go b/config.go |
2 | index 777e82e..ec68006 100644 |
3 | --- a/config.go |
4 | +++ b/config.go |
5 | @@ -17,7 +17,10 @@ const ( |
6 | type Config struct { |
7 | Colors *ColorMap `json:"colors"` |
8 | DateTimeFmt string `json:"dateTimeFmt"` |
9 | + BasePath string `json:"basePath"` |
10 | DBPath string `json:"dbPath"` |
11 | + SocketPath string `json:"socketPath"` |
12 | + IconPath string `json:"iconPath"` |
13 | } |
14 | |
15 | type ColorMap struct { |
16 | @@ -72,31 +75,40 @@ func (c *ColorMap) UnmarshalJSON(raw []byte) error { |
17 | return nil |
18 | } |
19 | |
20 | - func NewConfig(configPath string) (*Config, error) { |
21 | + func LoadConfig(configPath string, config *Config) error { |
22 | raw, err := ioutil.ReadFile(configPath) |
23 | if err != nil { |
24 | + os.MkdirAll(path.Dir(configPath), 0755) |
25 | // Create an empty config file |
26 | // if it does not already exist. |
27 | if os.IsNotExist(err) { |
28 | raw, _ := json.Marshal(map[string]string{}) |
29 | err := ioutil.WriteFile(configPath, raw, 0644) |
30 | if err != nil { |
31 | - return nil, err |
32 | + return err |
33 | } |
34 | - return NewConfig(configPath) |
35 | + return LoadConfig(configPath, config) |
36 | } |
37 | - return nil, err |
38 | + return err |
39 | } |
40 | - config := &Config{} |
41 | err = json.Unmarshal(raw, config) |
42 | if err != nil { |
43 | - return nil, err |
44 | + return err |
45 | } |
46 | if config.DateTimeFmt == "" { |
47 | config.DateTimeFmt = defaultDateTimeFmt |
48 | } |
49 | + if config.BasePath == "" { |
50 | + config.BasePath = path.Dir(configPath) |
51 | + } |
52 | if config.DBPath == "" { |
53 | - config.DBPath = path.Dir(configPath) + "/pomo.db" |
54 | + config.DBPath = path.Join(config.BasePath, "/pomo.db") |
55 | } |
56 | - return config, nil |
57 | + if config.SocketPath == "" { |
58 | + config.SocketPath = path.Join(config.BasePath, "/pomo.sock") |
59 | + } |
60 | + if config.IconPath == "" { |
61 | + config.IconPath = path.Join(config.BasePath, "/icon.png") |
62 | + } |
63 | + return nil |
64 | } |
65 | diff --git a/main.go b/main.go |
66 | index e4c1f47..a7ebcf9 100644 |
67 | --- a/main.go |
68 | +++ b/main.go |
69 | @@ -11,7 +11,7 @@ import ( |
70 | cli "github.com/jawher/mow.cli" |
71 | ) |
72 | |
73 | - func start(path *string) func(*cli.Cmd) { |
74 | + func start(config *Config) func(*cli.Cmd) { |
75 | return func(cmd *cli.Cmd) { |
76 | cmd.Spec = "[OPTIONS] MESSAGE" |
77 | var ( |
78 | @@ -23,7 +23,7 @@ func start(path *string) func(*cli.Cmd) { |
79 | cmd.Action = func() { |
80 | parsed, err := time.ParseDuration(*duration) |
81 | maybe(err) |
82 | - db, err := NewStore(*path) |
83 | + db, err := NewStore(config.DBPath) |
84 | maybe(err) |
85 | defer db.Close() |
86 | task := &Task{ |
87 | @@ -40,9 +40,9 @@ func start(path *string) func(*cli.Cmd) { |
88 | task.ID = id |
89 | return nil |
90 | })) |
91 | - runner, err := NewTaskRunner(task, db, NewXnotifier(*path+"/icon.png")) |
92 | + runner, err := NewTaskRunner(task, db, NewXnotifier(config.IconPath)) |
93 | maybe(err) |
94 | - server, err := NewServer(*path+"/pomo.sock", runner) |
95 | + server, err := NewServer(config.SocketPath, runner) |
96 | maybe(err) |
97 | server.Start() |
98 | defer server.Stop() |
99 | @@ -52,7 +52,7 @@ func start(path *string) func(*cli.Cmd) { |
100 | } |
101 | } |
102 | |
103 | - func create(path *string) func(*cli.Cmd) { |
104 | + func create(config *Config) func(*cli.Cmd) { |
105 | return func(cmd *cli.Cmd) { |
106 | cmd.Spec = "[OPTIONS] MESSAGE" |
107 | var ( |
108 | @@ -64,7 +64,7 @@ func create(path *string) func(*cli.Cmd) { |
109 | cmd.Action = func() { |
110 | parsed, err := time.ParseDuration(*duration) |
111 | maybe(err) |
112 | - db, err := NewStore(*path) |
113 | + db, err := NewStore(config.DBPath) |
114 | maybe(err) |
115 | defer db.Close() |
116 | task := &Task{ |
117 | @@ -85,7 +85,7 @@ func create(path *string) func(*cli.Cmd) { |
118 | } |
119 | } |
120 | |
121 | - func begin(path *string) func(*cli.Cmd) { |
122 | + func begin(config *Config) func(*cli.Cmd) { |
123 | return func(cmd *cli.Cmd) { |
124 | cmd.Spec = "[OPTIONS] TASK_ID" |
125 | var ( |
126 | @@ -93,7 +93,7 @@ func begin(path *string) func(*cli.Cmd) { |
127 | ) |
128 | |
129 | cmd.Action = func() { |
130 | - db, err := NewStore(*path) |
131 | + db, err := NewStore(config.DBPath) |
132 | maybe(err) |
133 | defer db.Close() |
134 | var task *Task |
135 | @@ -110,9 +110,9 @@ func begin(path *string) func(*cli.Cmd) { |
136 | task.Pomodoros = []*Pomodoro{} |
137 | return nil |
138 | })) |
139 | - runner, err := NewTaskRunner(task, db, NewXnotifier(*path+"/icon.png")) |
140 | + runner, err := NewTaskRunner(task, db, NewXnotifier(config.IconPath)) |
141 | maybe(err) |
142 | - server, err := NewServer(*path+"/pomo.sock", runner) |
143 | + server, err := NewServer(config.SocketPath, runner) |
144 | maybe(err) |
145 | server.Start() |
146 | defer server.Stop() |
147 | @@ -122,11 +122,11 @@ func begin(path *string) func(*cli.Cmd) { |
148 | } |
149 | } |
150 | |
151 | - func initialize(path *string) func(*cli.Cmd) { |
152 | + func initialize(config *Config) func(*cli.Cmd) { |
153 | return func(cmd *cli.Cmd) { |
154 | cmd.Spec = "[OPTIONS]" |
155 | cmd.Action = func() { |
156 | - db, err := NewStore(*path) |
157 | + db, err := NewStore(config.DBPath) |
158 | maybe(err) |
159 | defer db.Close() |
160 | maybe(initDB(db)) |
161 | @@ -134,7 +134,7 @@ func initialize(path *string) func(*cli.Cmd) { |
162 | } |
163 | } |
164 | |
165 | - func list(path *string) func(*cli.Cmd) { |
166 | + func list(config *Config) func(*cli.Cmd) { |
167 | return func(cmd *cli.Cmd) { |
168 | cmd.Spec = "[OPTIONS]" |
169 | var ( |
170 | @@ -147,7 +147,7 @@ func list(path *string) func(*cli.Cmd) { |
171 | cmd.Action = func() { |
172 | duration, err := time.ParseDuration(*duration) |
173 | maybe(err) |
174 | - db, err := NewStore(*path) |
175 | + db, err := NewStore(config.DBPath) |
176 | maybe(err) |
177 | defer db.Close() |
178 | maybe(db.With(func(tx *sql.Tx) error { |
179 | @@ -166,7 +166,6 @@ func list(path *string) func(*cli.Cmd) { |
180 | maybe(json.NewEncoder(os.Stdout).Encode(tasks)) |
181 | return nil |
182 | } |
183 | - config, err := NewConfig(*path + "/config.json") |
184 | maybe(err) |
185 | summerizeTasks(config, tasks) |
186 | return nil |
187 | @@ -175,12 +174,12 @@ func list(path *string) func(*cli.Cmd) { |
188 | } |
189 | } |
190 | |
191 | - func _delete(path *string) func(*cli.Cmd) { |
192 | + func _delete(config *Config) func(*cli.Cmd) { |
193 | return func(cmd *cli.Cmd) { |
194 | cmd.Spec = "[OPTIONS] TASK_ID" |
195 | var taskID = cmd.IntArg("TASK_ID", -1, "task to delete") |
196 | cmd.Action = func() { |
197 | - db, err := NewStore(*path) |
198 | + db, err := NewStore(config.DBPath) |
199 | maybe(err) |
200 | defer db.Close() |
201 | maybe(db.With(func(tx *sql.Tx) error { |
202 | @@ -190,11 +189,11 @@ func _delete(path *string) func(*cli.Cmd) { |
203 | } |
204 | } |
205 | |
206 | - func _status(path *string) func(*cli.Cmd) { |
207 | + func _status(config *Config) func(*cli.Cmd) { |
208 | return func(cmd *cli.Cmd) { |
209 | cmd.Spec = "[OPTIONS]" |
210 | cmd.Action = func() { |
211 | - client, err := NewClient(*path + "/pomo.sock") |
212 | + client, err := NewClient(config.SocketPath) |
213 | if err != nil { |
214 | outputStatus(Status{}) |
215 | return |
216 | @@ -207,12 +206,10 @@ func _status(path *string) func(*cli.Cmd) { |
217 | } |
218 | } |
219 | |
220 | - func config(path *string) func(*cli.Cmd) { |
221 | + func _config(config *Config) func(*cli.Cmd) { |
222 | return func(cmd *cli.Cmd) { |
223 | cmd.Spec = "[OPTIONS]" |
224 | cmd.Action = func() { |
225 | - config, err := NewConfig(*path + "/config.json") |
226 | - maybe(err) |
227 | maybe(json.NewEncoder(os.Stdout).Encode(config)) |
228 | } |
229 | } |
230 | @@ -223,16 +220,20 @@ func main() { |
231 | app.LongDesc = "Pomo helps you track what you did, how long it took you to do it, and how much effort you expect it to take." |
232 | app.Spec = "[OPTIONS]" |
233 | var ( |
234 | - path = app.StringOpt("p path", defaultConfigPath(), "path to the pomo config directory") |
235 | + config = &Config{} |
236 | + path = app.StringOpt("p path", defaultConfigPath(), "path to the pomo config directory") |
237 | ) |
238 | + app.Before = func() { |
239 | + maybe(LoadConfig(*path, config)) |
240 | + } |
241 | app.Version("v version", Version) |
242 | - app.Command("start s", "start a new task", start(path)) |
243 | - app.Command("init", "initialize the sqlite database", initialize(path)) |
244 | - app.Command("config cf", "display the current configuration", config(path)) |
245 | - app.Command("create c", "create a new task without starting", create(path)) |
246 | - app.Command("begin b", "begin requested pomodoro", begin(path)) |
247 | - app.Command("list l", "list historical tasks", list(path)) |
248 | - app.Command("delete d", "delete a stored task", _delete(path)) |
249 | - app.Command("status st", "output the current status", _status(path)) |
250 | + app.Command("start s", "start a new task", start(config)) |
251 | + app.Command("init", "initialize the sqlite database", initialize(config)) |
252 | + app.Command("config cf", "display the current configuration", _config(config)) |
253 | + app.Command("create c", "create a new task without starting", create(config)) |
254 | + app.Command("begin b", "begin requested pomodoro", begin(config)) |
255 | + app.Command("list l", "list historical tasks", list(config)) |
256 | + app.Command("delete d", "delete a stored task", _delete(config)) |
257 | + app.Command("status st", "output the current status", _status(config)) |
258 | app.Run(os.Args) |
259 | } |
260 | diff --git a/runner_test.go b/runner_test.go |
261 | index 8c35da7..ca1b6f3 100644 |
262 | --- a/runner_test.go |
263 | +++ b/runner_test.go |
264 | @@ -3,13 +3,14 @@ package main |
265 | import ( |
266 | "fmt" |
267 | "io/ioutil" |
268 | + "path" |
269 | "testing" |
270 | "time" |
271 | ) |
272 | |
273 | func TestTaskRunner(t *testing.T) { |
274 | - path, _ := ioutil.TempDir("/tmp", "") |
275 | - store, err := NewStore(path) |
276 | + baseDir, _ := ioutil.TempDir("/tmp", "") |
277 | + store, err := NewStore(path.Join(baseDir, "pomo.db")) |
278 | if err != nil { |
279 | t.Error(err) |
280 | } |
281 | diff --git a/store.go b/store.go |
282 | index 0152fbe..f3bf795 100644 |
283 | --- a/store.go |
284 | +++ b/store.go |
285 | @@ -2,7 +2,6 @@ package main |
286 | |
287 | import ( |
288 | "database/sql" |
289 | - "os" |
290 | "strings" |
291 | "time" |
292 | |
293 | @@ -19,8 +18,7 @@ type Store struct { |
294 | } |
295 | |
296 | func NewStore(path string) (*Store, error) { |
297 | - os.Mkdir(path, 0755) |
298 | - db, err := sql.Open("sqlite3", path+"/pomo.db") |
299 | + db, err := sql.Open("sqlite3", path) |
300 | if err != nil { |
301 | return nil, err |
302 | } |
303 | diff --git a/util.go b/util.go |
304 | index d49501c..5ecb373 100644 |
305 | --- a/util.go |
306 | +++ b/util.go |
307 | @@ -4,6 +4,7 @@ import ( |
308 | "fmt" |
309 | "os" |
310 | "os/user" |
311 | + "path" |
312 | "time" |
313 | |
314 | "github.com/fatih/color" |
315 | @@ -19,7 +20,7 @@ func maybe(err error) { |
316 | func defaultConfigPath() string { |
317 | u, err := user.Current() |
318 | maybe(err) |
319 | - return u.HomeDir + "/.pomo" |
320 | + return path.Join(u.HomeDir, "/.pomo/config.json") |
321 | } |
322 | |
323 | func summerizeTasks(config *Config, tasks []*Task) { |