mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-09-13 00:06:06 +00:00
Config auto-creation, update port from arguments
This commit is contained in:
111
cfg/config.go
111
cfg/config.go
@@ -2,16 +2,18 @@
|
|||||||
package cfg
|
package cfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"path/filepath"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/go-ini/ini"
|
"github.com/go-ini/ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These variables represent the configuration. You are not meant to modify them after they were set.
|
// 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.
|
// See https://mycorrhiza.lesarbr.es/hypha/configuration/fields for the
|
||||||
|
// documentation.
|
||||||
var (
|
var (
|
||||||
WikiName string
|
WikiName string
|
||||||
NaviTitleIcon string
|
NaviTitleIcon string
|
||||||
@@ -33,60 +35,59 @@ var (
|
|||||||
EditScripts []string
|
EditScripts []string
|
||||||
)
|
)
|
||||||
|
|
||||||
// These variables are set before reading the config file, they are set in main.parseCliArgs.
|
// WikiDir is a full path to the wiki storage directory, which also must be a
|
||||||
var (
|
// git repo. This variable is set in parseCliArgs().
|
||||||
// WikiDir is a full path to the wiki storage directory, which also must be a git repo.
|
var WikiDir string
|
||||||
WikiDir string
|
|
||||||
// ConfigFilePath is a path to the config file. Its value is used when calling ReadConfigFile.
|
|
||||||
ConfigFilePath 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 {
|
type Config struct {
|
||||||
WikiName string
|
WikiName string `comment:"This name appears in the header and on various pages."`
|
||||||
NaviTitleIcon string
|
NaviTitleIcon string `comment:"This icon is used in the breadcrumbs bar."`
|
||||||
Hyphae
|
Hyphae
|
||||||
Network
|
Network
|
||||||
Authorization
|
Authorization `comment:""`
|
||||||
CustomScripts
|
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.
|
// Hyphae is a section of Config which has fields related to special hyphae.
|
||||||
type Hyphae struct {
|
type Hyphae struct {
|
||||||
HomeHypha string
|
HomeHypha string `comment:"This hypha will be the main (index) page of your wiki, served on /."`
|
||||||
UserHypha string
|
UserHypha string `comment:"This hypha is used as a prefix for user hyphae."`
|
||||||
HeaderLinksHypha string
|
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 {
|
type Network struct {
|
||||||
HTTPPort uint64
|
HTTPPort uint64
|
||||||
URL string
|
URL string `comment:"Set your wiki's public URL here. It's used for OpenGraph generation and syndication feeds."`
|
||||||
GeminiCertificatePath string
|
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 {
|
type CustomScripts struct {
|
||||||
// OmnipresentScripts: everywhere...
|
// OmnipresentScripts: everywhere...
|
||||||
OmnipresentScripts []string `delim:","`
|
OmnipresentScripts []string `delim:"," comment:"These scripts are loaded from anywhere."`
|
||||||
// ViewScripts: /hypha, /rev
|
// ViewScripts: /hypha, /rev
|
||||||
ViewScripts []string `delim:","`
|
ViewScripts []string `delim:"," comment:"These scripts are only loaded on view pages."`
|
||||||
// Edit: /edit
|
// 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 {
|
type Authorization struct {
|
||||||
UseFixedAuth bool
|
UseFixedAuth bool
|
||||||
|
|
||||||
UseRegistration bool
|
UseRegistration bool
|
||||||
LimitRegistration uint64
|
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.
|
// ReadConfigFile reads a config on the given path and stores the
|
||||||
//
|
// configuration. Call it sometime during the initialization.
|
||||||
// Note that it may log.Fatal.
|
// Note that it may call log.Fatal, which terminates the program.
|
||||||
func ReadConfigFile() {
|
func ReadConfigFile(path string) {
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
WikiName: "Mycorrhiza Wiki",
|
WikiName: "Mycorrhiza Wiki",
|
||||||
NaviTitleIcon: "🍄",
|
NaviTitleIcon: "🍄",
|
||||||
@@ -102,7 +103,6 @@ func ReadConfigFile() {
|
|||||||
},
|
},
|
||||||
Authorization: Authorization{
|
Authorization: Authorization{
|
||||||
UseFixedAuth: false,
|
UseFixedAuth: false,
|
||||||
|
|
||||||
UseRegistration: false,
|
UseRegistration: false,
|
||||||
LimitRegistration: 0,
|
LimitRegistration: 0,
|
||||||
},
|
},
|
||||||
@@ -113,16 +113,47 @@ func ReadConfigFile() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if ConfigFilePath != "" {
|
dirty := false
|
||||||
path, err := filepath.Abs(ConfigFilePath)
|
|
||||||
|
f, err := ini.Load(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("cannot expand config file path: %s", err)
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
f = ini.Empty()
|
||||||
|
dirty = true
|
||||||
|
} else {
|
||||||
|
log.Fatal("Failed to parse the config file:", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Loading config at", path)
|
// Map the config file to the config struct. It'll do nothing if the file
|
||||||
err = ini.MapTo(cfg, path)
|
// 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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal("Failed to parse the port from command-line arguments:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.Network.HTTPPort = port
|
||||||
|
|
||||||
|
dirty = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save changes, if there are any
|
||||||
|
if dirty {
|
||||||
|
err = f.ReflectFrom(cfg)
|
||||||
|
if err != nil {
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ var paths struct {
|
|||||||
gitRepo string
|
gitRepo string
|
||||||
cacheDir string
|
cacheDir string
|
||||||
staticFiles string
|
staticFiles string
|
||||||
|
configPath string
|
||||||
tokensJSON string
|
tokensJSON string
|
||||||
registrationCredentialsJSON string
|
registrationCredentialsJSON string
|
||||||
fixedCredentialsJSON string
|
fixedCredentialsJSON string
|
||||||
@@ -29,6 +30,9 @@ func GitRepo() string { return paths.gitRepo }
|
|||||||
// StaticFiles returns the path to static files directory
|
// StaticFiles returns the path to static files directory
|
||||||
func StaticFiles() string { return paths.staticFiles }
|
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.
|
// TokensJSON returns the path to the JSON user tokens storage.
|
||||||
func TokensJSON() string { return paths.tokensJSON }
|
func TokensJSON() string { return paths.tokensJSON }
|
||||||
|
|
||||||
@@ -61,6 +65,8 @@ func PrepareWikiRoot() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
paths.configPath = filepath.Join(cfg.WikiDir, "config.ini")
|
||||||
|
|
||||||
paths.tokensJSON = filepath.Join(paths.cacheDir, "tokens.json")
|
paths.tokensJSON = filepath.Join(paths.cacheDir, "tokens.json")
|
||||||
paths.fixedCredentialsJSON = filepath.Join(cfg.WikiDir, "fixed-users.json")
|
paths.fixedCredentialsJSON = filepath.Join(cfg.WikiDir, "fixed-users.json")
|
||||||
paths.registrationCredentialsJSON = filepath.Join(paths.cacheDir, "registered-users.json")
|
paths.registrationCredentialsJSON = filepath.Join(paths.cacheDir, "registered-users.json")
|
||||||
|
2
flag.go
2
flag.go
@@ -19,7 +19,7 @@ var defaultConfig []byte
|
|||||||
var printExampleConfig bool
|
var printExampleConfig bool
|
||||||
|
|
||||||
func init() {
|
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.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
|
flag.Usage = printHelp
|
||||||
}
|
}
|
||||||
|
4
main.go
4
main.go
@@ -22,12 +22,10 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
parseCliArgs()
|
parseCliArgs()
|
||||||
|
|
||||||
// It is ok if the path is ""
|
|
||||||
cfg.ReadConfigFile()
|
|
||||||
|
|
||||||
if err := files.PrepareWikiRoot(); err != nil {
|
if err := files.PrepareWikiRoot(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
cfg.ReadConfigFile(files.ConfigPath())
|
||||||
|
|
||||||
log.Println("Running Mycorrhiza Wiki 1.2.0 indev")
|
log.Println("Running Mycorrhiza Wiki 1.2.0 indev")
|
||||||
if err := os.Chdir(files.HyphaeDir()); err != nil {
|
if err := os.Chdir(files.HyphaeDir()); err != nil {
|
||||||
|
Reference in New Issue
Block a user