1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-05 02:29:54 +00:00

Config auto-creation, update port from arguments

This commit is contained in:
handlerug 2021-06-19 23:48:54 +07:00
parent 235fba5007
commit 317e3a2049
No known key found for this signature in database
GPG Key ID: 38009F0605051491
4 changed files with 87 additions and 52 deletions

View File

@ -2,16 +2,18 @@
package cfg
import (
"errors"
"log"
"path/filepath"
"os"
"strconv"
"github.com/go-ini/ini"
)
// These variables represent the configuration. You are not meant to modify them after they were set.
//
// See https://mycorrhiza.lesarbr.es/hypha/configuration/fields for their docs.
// These variables represent the configuration. You are not meant to modify
// them after they were set.
// See https://mycorrhiza.lesarbr.es/hypha/configuration/fields for the
// documentation.
var (
WikiName string
NaviTitleIcon string
@ -24,69 +26,68 @@ var (
URL string
GeminiCertificatePath string
UseFixedAuth bool
UseRegistration bool
LimitRegistration int
UseFixedAuth bool
UseRegistration bool
LimitRegistration int
OmnipresentScripts []string
ViewScripts []string
EditScripts []string
)
// These variables are set before reading the config file, they are set in main.parseCliArgs.
var (
// WikiDir is a full path to the wiki storage directory, which also must be a git repo.
WikiDir string
// ConfigFilePath is a path to the config file. Its value is used when calling ReadConfigFile.
ConfigFilePath string
)
// WikiDir is a full path to the wiki storage directory, which also must be a
// git repo. This variable is set in parseCliArgs().
var WikiDir string
// Config represents a Mycorrhiza wiki configuration file. This type is used only when reading configs.
// Config represents a Mycorrhiza wiki configuration file. This type is used
// only when reading configs.
type Config struct {
WikiName string
NaviTitleIcon string
WikiName string `comment:"This name appears in the header and on various pages."`
NaviTitleIcon string `comment:"This icon is used in the breadcrumbs bar."`
Hyphae
Network
Authorization
CustomScripts
Authorization `comment:""`
CustomScripts `comment:"You can specify additional scripts to load on different kinds of pages, delimited by a comma ',' sign."`
}
// Hyphae is a section of Config which has fields related to special hyphae.
type Hyphae struct {
HomeHypha string
UserHypha string
HeaderLinksHypha string
HomeHypha string `comment:"This hypha will be the main (index) page of your wiki, served on /."`
UserHypha string `comment:"This hypha is used as a prefix for user hyphae."`
HeaderLinksHypha string `comment:"You can also specify a hypha to populate your own custom header links from."`
}
// Network is a section of Config that has fields related to network stuff: HTTP and Gemini.
// Network is a section of Config that has fields related to network stuff:
// HTTP and Gemini.
type Network struct {
HTTPPort uint64
URL string
GeminiCertificatePath string
URL string `comment:"Set your wiki's public URL here. It's used for OpenGraph generation and syndication feeds."`
GeminiCertificatePath string `comment:"Gemini requires servers to use TLS for client connections. Specify your certificate's path here."`
}
// CustomScripts is a section with paths to JavaScript files that are loaded on specified pages.
// CustomScripts is a section with paths to JavaScript files that are loaded on
// specified pages.
type CustomScripts struct {
// OmnipresentScripts: everywhere...
OmnipresentScripts []string `delim:","`
OmnipresentScripts []string `delim:"," comment:"These scripts are loaded from anywhere."`
// ViewScripts: /hypha, /rev
ViewScripts []string `delim:","`
ViewScripts []string `delim:"," comment:"These scripts are only loaded on view pages."`
// Edit: /edit
EditScripts []string `delim:","`
EditScripts []string `delim:"," comment:"These scripts are only loaded on the edit page."`
}
// Authorization is a section of Config that has fields related to authorization and authentication.
// Authorization is a section of Config that has fields related to
// authorization and authentication.
type Authorization struct {
UseFixedAuth bool
UseRegistration bool
LimitRegistration uint64
UseFixedAuth bool
UseRegistration bool
LimitRegistration uint64 `comment:"This field controls the maximum amount of allowed registrations."`
}
// ReadConfigFile reads a config on the given path and stores the configuration. Call it sometime during the initialization.
//
// Note that it may log.Fatal.
func ReadConfigFile() {
// ReadConfigFile reads a config on the given path and stores the
// configuration. Call it sometime during the initialization.
// Note that it may call log.Fatal, which terminates the program.
func ReadConfigFile(path string) {
cfg := &Config{
WikiName: "Mycorrhiza Wiki",
NaviTitleIcon: "🍄",
@ -101,10 +102,9 @@ func ReadConfigFile() {
GeminiCertificatePath: "",
},
Authorization: Authorization{
UseFixedAuth: false,
UseRegistration: false,
LimitRegistration: 0,
UseFixedAuth: false,
UseRegistration: false,
LimitRegistration: 0,
},
CustomScripts: CustomScripts{
OmnipresentScripts: []string{},
@ -113,16 +113,47 @@ func ReadConfigFile() {
},
}
if ConfigFilePath != "" {
path, err := filepath.Abs(ConfigFilePath)
dirty := false
f, err := ini.Load(path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
f = ini.Empty()
dirty = true
} else {
log.Fatal("Failed to parse the config file:", err)
}
}
// Map the config file to the config struct. It'll do nothing if the file
// doesn't exist or is empty.
f.MapTo(cfg)
// Update the port if it's set externally and is different from what's in
// the config file
if HTTPPort != "" && HTTPPort != strconv.FormatUint(cfg.Network.HTTPPort, 10) {
port, err := strconv.ParseUint(HTTPPort, 10, 64)
if err != nil {
log.Fatalf("cannot expand config file path: %s", err)
log.Fatal("Failed to parse the port from command-line arguments:", err)
}
log.Println("Loading config at", path)
err = ini.MapTo(cfg, path)
cfg.Network.HTTPPort = port
dirty = true
}
// Save changes, if there are any
if dirty {
err = f.ReflectFrom(cfg)
if err != nil {
log.Fatal(err)
log.Fatal("Failed to serialize the config:", err)
}
// Disable key-value auto-aligning, but retain spaces around '=' sign
ini.PrettyFormat = false
ini.PrettyEqual = true
if err = f.SaveTo(path); err != nil {
log.Println("Failed to save the config file:", err)
}
}

View File

@ -12,6 +12,7 @@ var paths struct {
gitRepo string
cacheDir string
staticFiles string
configPath string
tokensJSON string
registrationCredentialsJSON string
fixedCredentialsJSON string
@ -29,6 +30,9 @@ func GitRepo() string { return paths.gitRepo }
// StaticFiles returns the path to static files directory
func StaticFiles() string { return paths.staticFiles }
// ConfigPath returns the path to the config file.
func ConfigPath() string { return paths.configPath }
// TokensJSON returns the path to the JSON user tokens storage.
func TokensJSON() string { return paths.tokensJSON }
@ -61,6 +65,8 @@ func PrepareWikiRoot() error {
return err
}
paths.configPath = filepath.Join(cfg.WikiDir, "config.ini")
paths.tokensJSON = filepath.Join(paths.cacheDir, "tokens.json")
paths.fixedCredentialsJSON = filepath.Join(cfg.WikiDir, "fixed-users.json")
paths.registrationCredentialsJSON = filepath.Join(paths.cacheDir, "registered-users.json")

View File

@ -19,7 +19,7 @@ var defaultConfig []byte
var printExampleConfig bool
func init() {
flag.StringVar(&cfg.ConfigFilePath, "config-path", "", "Path to a configuration file. Leave empty if you don't want to use it.")
flag.StringVar(&cfg.HTTPPort, "port", "", "Listen on another port. This option also updates the config file for your convenience.")
flag.BoolVar(&printExampleConfig, "print-example-config", false, "If true, print an example configuration file contents and exit. You can save the output to a file and base your own configuration on it.")
flag.Usage = printHelp
}

View File

@ -22,12 +22,10 @@ import (
func main() {
parseCliArgs()
// It is ok if the path is ""
cfg.ReadConfigFile()
if err := files.PrepareWikiRoot(); err != nil {
log.Fatal(err)
}
cfg.ReadConfigFile(files.ConfigPath())
log.Println("Running Mycorrhiza Wiki 1.2.0 indev")
if err := os.Chdir(files.HyphaeDir()); err != nil {