pominal/config.go
Dan Anglin 19eb9b20be
feat: support configuring Pominal with config file
This commit adds a feature to load Pominal
configuration from a JSON configuration file.

A new data type called PominalConfig was created for
the purpose of configuring Pominal.
A new factory function called newPominalConfig was
created which takes the path to the JSON configuration
file and the flag overrides and generates the new
PominalConfig value.

Here, the JSON config is parsed to create the initial
configuration and any flag overrides can override
the corresponding fields in the PominalConfig object.
Currently only the sessions times and the maximum work
sessions per Pominal cycle have flag overrides.

Additionally users can now configure custom notification
messages for each session type from the configuration file.
There are currently no flag overrides for these.

This commit resolves dananglin/Pominal#1
2020-02-13 12:42:55 +00:00

120 lines
3.3 KiB
Go

/*
Pominal
Copyright (C) 2020 Daniel Anglin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"encoding/json"
"os"
)
// Pominal config is a type used to configure Pominal
type PominalConfig struct {
MaxWorkSessions int `json:"max-work-sessions"`
Sessions Sessions `json:"sessions"`
}
type Sessions struct {
Work SessionConfig `json:"work"`
ShortBreak SessionConfig `json:"short-break"`
LongBreak SessionConfig `json:"long-break"`
}
type SessionConfig struct {
Duration string `json:"duration"`
NotificationMessage string `json:"notification-message"`
}
// newPominalConfig creates a new value of type config which will configure
// Pominal based on the configuration set in the configuration file
// and the command-line flags.
func newPominalConfig(file string, workTime, shortBreakTime, longBreakTime string, maxWorkSessions int) (PominalConfig, error) {
c, err := configureFromFile(file)
if err != nil {
return PominalConfig{}, err
}
c = configureFlagOverrides(c, workTime, shortBreakTime, longBreakTime, maxWorkSessions)
return c, nil
}
// configureFromFile parses the JSON file and create the initial
// config value. If the argument is an empty string (i.e. the user
// has not specified the path to a configuration file) a new config value will
// be created from the default values.
func configureFromFile(file string) (PominalConfig, error) {
if len(file) == 0 {
config := PominalConfig{
MaxWorkSessions: defaultMaxWorkSessions,
Sessions: Sessions{
Work: SessionConfig{
Duration: defaultWorkTime,
},
ShortBreak: SessionConfig{
Duration: defaultShortBreakTime,
},
LongBreak: SessionConfig{
Duration: defaultLongBreakTime,
},
},
}
return config, nil
}
f, err := os.Open(file)
if err != nil {
return PominalConfig{}, err
}
defer f.Close()
dec := json.NewDecoder(f)
config := PominalConfig{}
if err := dec.Decode(&config); err != nil {
return PominalConfig{}, err
}
return config, nil
}
// configureFlagOverrides returns the config value where the
// command-line flags override the corresponding fields in the
// config value. Right now the session durations and the maximum
// work sessions can be overridden.
func configureFlagOverrides(config PominalConfig, workTime, shortBreakTime, longBreakTime string, maxWorkSessions int) PominalConfig {
if len(workTime) > 0 {
config.Sessions.Work.Duration = workTime
}
if len(shortBreakTime) > 0 {
config.Sessions.ShortBreak.Duration = shortBreakTime
}
if len(longBreakTime) > 0 {
config.Sessions.LongBreak.Duration = longBreakTime
}
if maxWorkSessions > 0 {
config.MaxWorkSessions = maxWorkSessions
}
return config
}