From 48f04369546d9746694ae6cf02ebf66b99aea1d1 Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 12 Oct 2020 20:24:13 +0200 Subject: [PATCH 1/8] Add basic parsing of sample config with comments Signed-off-by: kolaente --- go.mod | 1 + magefile.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/go.mod b/go.mod index bcd72f320..c375466e4 100644 --- a/go.mod +++ b/go.mod @@ -77,6 +77,7 @@ require ( gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/d4l3k/messagediff.v1 v1.2.1 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c honnef.co/go/tools v0.0.1-2020.1.5 src.techknowlogick.com/xgo v1.1.1-0.20200811225412-bff6512e7c9c src.techknowlogick.com/xormigrate v1.3.0 diff --git a/magefile.go b/magefile.go index 4401988a7..ca98c9af0 100644 --- a/magefile.go +++ b/magefile.go @@ -26,7 +26,9 @@ import ( "fmt" "github.com/magefile/mage/mg" "golang.org/x/sync/errgroup" + "gopkg.in/yaml.v3" "io" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -729,3 +731,93 @@ func init() { _, err = f.WriteString(migration) return err } + +type configOption struct { + key string + description string + defaultValue string + + children []*configOption +} + +func parseYamlNode(node *yaml.Node) (config *configOption) { + config = &configOption{ + key: node.Value, + description: node.HeadComment, + } + + for i, n2 := range node.Content { + coo := &configOption{ + key: n2.Value, + description: n2.HeadComment, + } + + if i%2 == 0 { + continue + } + + if i-1 >= 0 && i-1 <= len(node.Content) && node.Content[i-1].Value != "" { + coo.defaultValue = n2.Value + coo.key = node.Content[i-1].Value + } + + config.children = append(config.children, coo) + + if len(n2.Content) > 0 { + for _, n := range n2.Content { + coo.children = append(coo.children, parseYamlNode(n)) + } + } + } + + return config +} + +// Generates the error docs from a commented config.yml.sample file in the repo root. +func GenerateDocs() error { + + config, err := ioutil.ReadFile("config.yml.sample") + if err != nil { + return err + } + + var d yaml.Node + err = yaml.Unmarshal(config, &d) + if err != nil { + return err + } + + conf := []*configOption{} + + for _, node := range d.Content { + for _, n := range node.Content { + co := parseYamlNode(n) + conf = append(conf, co) + } + } + + for _, option := range conf { + if option.key != "" { + fmt.Printf("Option: %s\n", option.key) + + if option.description != "" { + fmt.Printf("Description: %s\n", option.description) + } + } + + for _, child := range option.children { + if child.key != "" { + + // TODO: Add generating docs from recursive structure + + fmt.Printf("[Child] Option: %s, Default: %s\n", child.key, child.defaultValue) + + if child.description != "" { + fmt.Printf("[Child] Description: %s\n", child.description) + } + } + } + } + + return nil +} -- 2.40.1 From 613d1706d8e388a3f3d5871a3aabb54283d06b1e Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Oct 2020 20:40:56 +0200 Subject: [PATCH 2/8] Add printing config Signed-off-by: kolaente --- magefile.go | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/magefile.go b/magefile.go index ca98c9af0..e096a4820 100644 --- a/magefile.go +++ b/magefile.go @@ -740,7 +740,7 @@ type configOption struct { children []*configOption } -func parseYamlNode(node *yaml.Node) (config *configOption) { +func parseYamlConfigNode(node *yaml.Node) (config *configOption) { config = &configOption{ key: node.Value, description: node.HeadComment, @@ -765,7 +765,7 @@ func parseYamlNode(node *yaml.Node) (config *configOption) { if len(n2.Content) > 0 { for _, n := range n2.Content { - coo.children = append(coo.children, parseYamlNode(n)) + coo.children = append(coo.children, parseYamlConfigNode(n)) } } } @@ -773,6 +773,27 @@ func parseYamlNode(node *yaml.Node) (config *configOption) { return config } +func printConfig(config []*configOption, level int) (rendered string) { + for _, option := range config { + if option.key != "" { + + for i := 0; i <= level; i++ { + rendered += "#" + } + rendered += " " + option.key + "\n" + + if option.description != "" { + rendered += "\n\n" + option.description + "\n\n" + } + rendered += "Default: `" + option.defaultValue + "`\n" + } + + rendered += "\n" + printConfig(option.children, level+1) + } + + return +} + // Generates the error docs from a commented config.yml.sample file in the repo root. func GenerateDocs() error { @@ -791,33 +812,12 @@ func GenerateDocs() error { for _, node := range d.Content { for _, n := range node.Content { - co := parseYamlNode(n) + co := parseYamlConfigNode(n) conf = append(conf, co) } } - for _, option := range conf { - if option.key != "" { - fmt.Printf("Option: %s\n", option.key) - - if option.description != "" { - fmt.Printf("Description: %s\n", option.description) - } - } - - for _, child := range option.children { - if child.key != "" { - - // TODO: Add generating docs from recursive structure - - fmt.Printf("[Child] Option: %s, Default: %s\n", child.key, child.defaultValue) - - if child.description != "" { - fmt.Printf("[Child] Description: %s\n", child.description) - } - } - } - } + fmt.Println(printConfig(conf, 0)) return nil } -- 2.40.1 From ced8f7d063f871395224872b6573ca5a9c4f1f72 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Oct 2020 20:43:40 +0200 Subject: [PATCH 3/8] Remove comment headings from yaml comments Signed-off-by: kolaente --- magefile.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/magefile.go b/magefile.go index e096a4820..16592a5d9 100644 --- a/magefile.go +++ b/magefile.go @@ -743,13 +743,13 @@ type configOption struct { func parseYamlConfigNode(node *yaml.Node) (config *configOption) { config = &configOption{ key: node.Value, - description: node.HeadComment, + description: strings.ReplaceAll(node.HeadComment, "# ", ""), } for i, n2 := range node.Content { coo := &configOption{ key: n2.Value, - description: n2.HeadComment, + description: strings.ReplaceAll(n2.HeadComment, "# ", ""), } if i%2 == 0 { -- 2.40.1 From decfd35cb168f5d41e131efde827d52ef6bf3307 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Oct 2020 20:50:36 +0200 Subject: [PATCH 4/8] Only render default value for non-top-level values Signed-off-by: kolaente --- magefile.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/magefile.go b/magefile.go index 16592a5d9..064255418 100644 --- a/magefile.go +++ b/magefile.go @@ -780,12 +780,20 @@ func printConfig(config []*configOption, level int) (rendered string) { for i := 0; i <= level; i++ { rendered += "#" } - rendered += " " + option.key + "\n" + rendered += " " + option.key + "\n\n" if option.description != "" { - rendered += "\n\n" + option.description + "\n\n" + rendered += option.description + "\n\n" + } + + // Top level config values never have a default value + if level > 0 { + rendered += "Default: `" + option.defaultValue + if option.defaultValue == "" { + rendered += "" + } + rendered += "`\n" } - rendered += "Default: `" + option.defaultValue + "`\n" } rendered += "\n" + printConfig(option.children, level+1) -- 2.40.1 From f3f705d23b57bccedd53b60efcb919ba19a97990 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Oct 2020 21:07:53 +0200 Subject: [PATCH 5/8] Add method to write out the file Signed-off-by: kolaente --- magefile.go | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/magefile.go b/magefile.go index 064255418..efab51287 100644 --- a/magefile.go +++ b/magefile.go @@ -746,6 +746,8 @@ func parseYamlConfigNode(node *yaml.Node) (config *configOption) { description: strings.ReplaceAll(node.HeadComment, "# ", ""), } + // TODO: second-level comments don't work + for i, n2 := range node.Content { coo := &configOption{ key: n2.Value, @@ -777,6 +779,7 @@ func printConfig(config []*configOption, level int) (rendered string) { for _, option := range config { if option.key != "" { + rendered += "#" for i := 0; i <= level; i++ { rendered += "#" } @@ -802,6 +805,11 @@ func printConfig(config []*configOption, level int) (rendered string) { return } +const ( + configDocPath = `docs/content/doc/setup/config.md` + configInjectComment = `` +) + // Generates the error docs from a commented config.yml.sample file in the repo root. func GenerateDocs() error { @@ -825,7 +833,37 @@ func GenerateDocs() error { } } - fmt.Println(printConfig(conf, 0)) + renderedConfig := printConfig(conf, 0) + + // Rebuild the config + file, err := os.OpenFile(configDocPath, os.O_RDWR, 0) + if err != nil { + return err + } + defer file.Close() + + // We read the config doc up until the marker, then stop and append our generated config + fullConfig := "" + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + t := scanner.Text() + fullConfig += t + "\n" + + if t == configInjectComment { + break + } + } + + if err := scanner.Err(); err != nil { + return err + } + + fullConfig += "\n" + renderedConfig + + if _, err := file.WriteAt([]byte(fullConfig), 0); err != nil { + return err + } return nil } -- 2.40.1 From fac00436f9109c8652cab67a43d44656e9c44781 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Oct 2020 21:41:29 +0200 Subject: [PATCH 6/8] Fix parsing of descriptions and multi-level values Signed-off-by: kolaente --- docs/content/doc/setup/config.md | 980 ++++++++++++++++++++++++------- magefile.go | 33 +- 2 files changed, 804 insertions(+), 209 deletions(-) diff --git a/docs/content/doc/setup/config.md b/docs/content/doc/setup/config.md index 5a645cc11..b5e00e873 100644 --- a/docs/content/doc/setup/config.md +++ b/docs/content/doc/setup/config.md @@ -40,222 +40,790 @@ Vikunja will search on various places for a config file: This is the same as the `config.yml.sample` file you'll find in the root of vikunja. -{{< highlight yaml >}} -service: - # This token is used to verify issued JWT tokens. - # Default is a random token which will be generated at each startup of vikunja. - # (This means all already issued tokens will be invalid once you restart vikunja) - JWTSecret: "cei6gaezoosah2bao3ieZohkae5aicah" - # The interface on which to run the webserver - interface: ":3456" - # The URL of the frontend, used to send password reset emails. - frontendurl: "" - # The base path on the file system where the binary and assets are. - # Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder - # with a config file which will then be used. - rootpath: - # The max number of items which can be returned per page - maxitemsperpage: 50 - # If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system - # You'll need to use redis for this in order to enable common metrics over multiple nodes - enablemetrics: false - # Enable the caldav endpoint, see the docs for more details - enablecaldav: true - # Set the motd message, available from the /info endpoint - motd: "" - # Enable sharing of lists via a link - enablelinksharing: true - # Whether to let new users registering themselves or not - enableregistration: true - # Whether to enable task attachments or not - enabletaskattachments: true - # The time zone all timestamps are in - timezone: GMT - # Whether task comments should be enabled or not - enabletaskcomments: true - # Whether totp is enabled. In most cases you want to leave that enabled. - enabletotp: true - # If not empty, enables logging of crashes and unhandled errors in sentry. - sentrydsn: '' + -database: - # Database type to use. Supported types are mysql, postgres and sqlite. - type: "sqlite" - # Database user which is used to connect to the database. - user: "vikunja" - # Databse password - password: "" - # Databse host - host: "localhost" - # Databse to use - database: "vikunja" - # When using sqlite, this is the path where to store the data - path: "./vikunja.db" - # Sets the max open connections to the database. Only used when using mysql and postgres. - maxopenconnections: 100 - # Sets the maximum number of idle connections to the db. - maxidleconnections: 50 - # The maximum lifetime of a single db connection in miliseconds. - maxconnectionlifetime: 10000 - # Secure connection mode. Only used with postgres. - # (see https://pkg.go.dev/github.com/lib/pq?tab=doc#hdr-Connection_String_Parameters) - sslmode: disable +## service -cache: - # If cache is enabled or not - enabled: false - # Cache type. Possible values are "keyvalue", "memory" or "redis". - # When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. - # When choosing "redis" you will need to configure the redis connection seperately. - type: keyvalue - # When using memory this defines the maximum size an element can take - maxelementsize: 1000 -redis: - # Whether to enable redis or not - enabled: false - # The host of the redis server including its port. - host: 'localhost:6379' - # The password used to authenicate against the redis server - password: '' - # 0 means default database - db: 0 -cors: - # Whether to enable or disable cors headers. - # Note: If you want to put the frontend and the api on seperate domains or ports, you will need to enable this. - # Otherwise the frontend won't be able to make requests to the api through the browser. - enable: true - # A list of origins which may access the api. - origins: - - * - # How long (in seconds) the results of a preflight request can be cached. - maxage: 0 +### JWTSecret -mailer: - # Whether to enable the mailer or not. If it is disabled, all users are enabled right away and password reset is not possible. - enabled: false - # SMTP Host - host: "" - # SMTP Host port - port: 587 - # SMTP username - username: "user" - # SMTP password - password: "" - # Wether to skip verification of the tls certificate on the server - skiptlsverify: false - # The default from address when sending emails - fromemail: "mail@vikunja" - # The length of the mail queue. - queuelength: 100 - # The timeout in seconds after which the current open connection to the mailserver will be closed. - queuetimeout: 30 - # By default, vikunja will try to connect with starttls, use this option to force it to use ssl. - forcessl: false +This token is used to verify issued JWT tokens. +Default is a random token which will be generated at each startup of vikunja. +(This means all already issued tokens will be invalid once you restart vikunja) -log: - # A folder where all the logfiles should go. - path: logs - # Whether to show any logging at all or none - enabled: true - # Where the normal log should go. Possible values are stdout, stderr, file or off to disable standard logging. - standard: "stdout" - # Change the log level. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. - level: "INFO" - # Whether or not to log database queries. Useful for debugging. Possible values are stdout, stderr, file or off to disable database logging. - database: "off" - # The log level for database log messages. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. - databaselevel: "WARNING" - # Whether to log http requests or not. Possible values are stdout, stderr, file or off to disable http logging. - http: "stdout" - # Echo has its own logging which usually is unnessecary, which is why it is disabled by default. Possible values are stdout, stderr, file or off to disable standard logging. - echo: "off" +Default: `` -ratelimit: - # whether or not to enable the rate limit - enabled: false - # The kind on which rates are based. Can be either "user" for a rate limit per user or "ip" for an ip-based rate limit. - kind: user - # The time period in seconds for the limit - period: 60 - # The max number of requests a user is allowed to do in the configured time period - limit: 100 - # The store where the limit counter for each user is stored. - # Possible values are "keyvalue", "memory" or "redis". - # When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. - store: keyvalue +### interface -files: - # The path where files are stored - basepath: ./files # relative to the binary - # The maximum size of a file, as a human-readable string. - # Warning: The max size is limited 2^64-1 bytes due to the underlying datatype - maxsize: 20MB +The interface on which to run the webserver -migration: - # These are the settings for the wunderlist migrator - wunderlist: - # Wheter to enable the wunderlist migrator or not - enable: false - # The client id, required for making requests to the wunderlist api - # You need to register your vikunja instance at https://developer.wunderlist.com/apps/new to get this - clientid: - # The client secret, also required for making requests to the wunderlist api - clientsecret: - # The url where clients are redirected after they authorized Vikunja to access their wunderlist stuff. - # This needs to match the url you entered when registering your Vikunja instance at wunderlist. - # This is usually the frontend url where the frontend then makes a request to /migration/wunderlist/migrate - # with the code obtained from the wunderlist api. - # Note that the vikunja frontend expects this to be /migrate/wunderlist - redirecturl: - todoist: - # Wheter to enable the todoist migrator or not - enable: false - # The client id, required for making requests to the wunderlist api - # You need to register your vikunja instance at https://developer.todoist.com/appconsole.html to get this - clientid: - # The client secret, also required for making requests to the todoist api - clientsecret: - # The url where clients are redirected after they authorized Vikunja to access their todoist items. - # This needs to match the url you entered when registering your Vikunja instance at todoist. - # This is usually the frontend url where the frontend then makes a request to /migration/todoist/migrate - # with the code obtained from the todoist api. - # Note that the vikunja frontend expects this to be /migrate/todoist - redirecturl: +Default: `:3456` -avatar: - # When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires - gravatarexpiration: 3600 +### frontendurl -backgrounds: - # Whether to enable backgrounds for lists at all. - enabled: true - providers: - upload: - # Whethere to enable uploaded list backgrounds - enabled: true - unsplash: - # Whether to enable setting backgrounds from unsplash as list backgrounds - enabled: false - # You need to create an application for your installation at https://unsplash.com/oauth/applications/new - # and set the access token below. - accesstoken: - # The unsplash application id is only used for pingback and required as per their api guidelines. - # You can find the Application ID in the dashboard for your API application. It should be a numeric ID. - # It will only show in the UI if your application has been approved for Enterprise usage, therefore if - # you’re in Demo mode, you can also find the ID in the URL at the end: https://unsplash.com/oauth/applications/:application_id - applicationid: +The URL of the frontend, used to send password reset emails. -# Legal urls -# Will be shown in the frontend if configured here -legal: - imprinturl: - privacyurl: +Default: `` + +### rootpath + +The base path on the file system where the binary and assets are. +Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder +with a config file which will then be used. + +Default: `` + +### maxitemsperpage + +The max number of items which can be returned per page + +Default: `50` + +### enablemetrics + +If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system +You'll need to use redis for this in order to enable common metrics over multiple nodes + +Default: `false` + +### enablecaldav + +Enable the caldav endpoint, see the docs for more details + +Default: `true` + +### motd + +Set the motd message, available from the /info endpoint + +Default: `` + +### enablelinksharing + +Enable sharing of lists via a link + +Default: `true` + +### enableregistration + +Whether to let new users registering themselves or not + +Default: `true` + +### enabletaskattachments + +Whether to enable task attachments or not + +Default: `true` + +### timezone + +The time zone all timestamps are in + +Default: `GMT` + +### enabletaskcomments + +Whether task comments should be enabled or not + +Default: `true` + +### enabletotp + +Whether totp is enabled. In most cases you want to leave that enabled. + +Default: `true` + +### sentrydsn + +If not empty, enables logging of crashes and unhandled errors in sentry. + +Default: `` + +## database + + + +### type + +Database type to use. Supported types are mysql, postgres and sqlite. + +Default: `sqlite` + +### user + +Database user which is used to connect to the database. + +Default: `vikunja` + +### password + +Databse password + +Default: `` + +### host + +Databse host + +Default: `localhost` + +### database + +Databse to use + +Default: `vikunja` + +### path + +When using sqlite, this is the path where to store the data + +Default: `./vikunja.db` + +### maxopenconnections + +Sets the max open connections to the database. Only used when using mysql and postgres. + +Default: `100` + +### maxidleconnections + +Sets the maximum number of idle connections to the db. + +Default: `50` + +### maxconnectionlifetime + +The maximum lifetime of a single db connection in miliseconds. + +Default: `10000` + +### sslmode + +Secure connection mode. Only used with postgres. +(see https://pkg.go.dev/github.com/lib/pq?tab=doc#hdr-Connection_String_Parameters) + +Default: `disable` + +## cache + + + +### enabled + +If cache is enabled or not + +Default: `false` + +### type + +Cache type. Possible values are "keyvalue", "memory" or "redis". +When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. +When choosing "redis" you will need to configure the redis connection seperately. + +Default: `keyvalue` + +### maxelementsize + +When using memory this defines the maximum size an element can take + +Default: `1000` + +## redis + + + +### enabled + +Whether to enable redis or not + +Default: `false` + +### host + +The host of the redis server including its port. + +Default: `localhost:6379` + +### password + +The password used to authenicate against the redis server + +Default: `` + +### db + +0 means default database + +Default: `0` + +## cors + + + +### enable + +Whether to enable or disable cors headers. +Note: If you want to put the frontend and the api on seperate domains or ports, you will need to enable this. + Otherwise the frontend won't be able to make requests to the api through the browser. + +Default: `true` + +### origins + +A list of origins which may access the api. + +Default: `` + +### maxage + +How long (in seconds) the results of a preflight request can be cached. + +Default: `0` + +## mailer + + + +### enabled + +Whether to enable the mailer or not. If it is disabled, all users are enabled right away and password reset is not possible. + +Default: `false` + +### host + +SMTP Host + +Default: `` + +### port + +SMTP Host port + +Default: `587` + +### username + +SMTP username + +Default: `user` + +### password + +SMTP password + +Default: `` + +### skiptlsverify + +Wether to skip verification of the tls certificate on the server + +Default: `false` + +### fromemail + +The default from address when sending emails + +Default: `mail@vikunja` + +### queuelength + +The length of the mail queue. + +Default: `100` + +### queuetimeout + +The timeout in seconds after which the current open connection to the mailserver will be closed. + +Default: `30` + +### forcessl + +By default, vikunja will try to connect with starttls, use this option to force it to use ssl. + +Default: `false` + +## log + + + +### path + +A folder where all the logfiles should go. + +Default: `logs` + +### enabled + +Whether to show any logging at all or none + +Default: `true` + +### standard + +Where the normal log should go. Possible values are stdout, stderr, file or off to disable standard logging. + +Default: `stdout` + +### level + +Change the log level. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. + +Default: `INFO` + +### database + +Whether or not to log database queries. Useful for debugging. Possible values are stdout, stderr, file or off to disable database logging. + +Default: `off` + +### databaselevel + +The log level for database log messages. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. + +Default: `WARNING` + +### http + +Whether to log http requests or not. Possible values are stdout, stderr, file or off to disable http logging. + +Default: `stdout` + +### echo + +Echo has its own logging which usually is unnessecary, which is why it is disabled by default. Possible values are stdout, stderr, file or off to disable standard logging. + +Default: `off` + +## ratelimit + + + +### enabled + +whether or not to enable the rate limit + +Default: `false` + +### kind + +The kind on which rates are based. Can be either "user" for a rate limit per user or "ip" for an ip-based rate limit. + +Default: `user` + +### period + +The time period in seconds for the limit + +Default: `60` + +### limit + +The max number of requests a user is allowed to do in the configured time period + +Default: `100` + +### store + +The store where the limit counter for each user is stored. +Possible values are "keyvalue", "memory" or "redis". +When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. + +Default: `keyvalue` + +## files + + + +### basepath + +The path where files are stored + +Default: `./files` + +### maxsize + +The maximum size of a file, as a human-readable string. +Warning: The max size is limited 2^64-1 bytes due to the underlying datatype + +Default: `20MB` + +## migration + + + +### wunderlist + +These are the settings for the wunderlist migrator + +Default: `` + +### todoist + +Default: `` + +## avatar + + + +### gravatarexpiration + +When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires + +Default: `3600` + +## backgrounds + + + +### enabled + +Whether to enable backgrounds for lists at all. + +Default: `true` + +### providers + +Default: `` + +## legal + +Legal urls +Will be shown in the frontend if configured here + + + +### imprinturl + +Default: `` + +### privacyurl + +Default: `` + +## keyvalue + +Key Value Storage settings +The Key Value Storage is used for different kinds of things like metrics and a few cache systems. + + + +### type + +The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured seperately. + +Default: `memory` + +mit + +The max number of requests a user is allowed to do in the configured time period + +Default: `100` + +### limit + +Default: `100` + +### store + +The store where the limit counter for each user is stored. +Possible values are "keyvalue", "memory" or "redis". +When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. + +Default: `keyvalue` + +### store + +Default: `keyvalue` + +## files + + + +### basepath + +The path where files are stored + +Default: `./files` + +### basepath + +Default: `./files` + +### maxsize + +The maximum size of a file, as a human-readable string. +Warning: The max size is limited 2^64-1 bytes due to the underlying datatype + +Default: `20MB` + +### maxsize + +Default: `20MB` + +## migration + + + +### wunderlist + +These are the settings for the wunderlist migrator + +Default: `` + +### wunderlist + +Default: `` + +#### enable + +Wheter to enable the wunderlist migrator or not + +Default: `` + +#### false + +Default: `` + +#### clientid + +The client id, required for making requests to the wunderlist api +You need to register your vikunja instance at https://developer.wunderlist.com/apps/new to get this + +Default: `` + + +#### clientsecret + +The client secret, also required for making requests to the wunderlist api + +Default: `` + + +#### redirecturl + +The url where clients are redirected after they authorized Vikunja to access their wunderlist stuff. +This needs to match the url you entered when registering your Vikunja instance at wunderlist. +This is usually the frontend url where the frontend then makes a request to /migration/wunderlist/migrate +with the code obtained from the wunderlist api. +Note that the vikunja frontend expects this to be /migrate/wunderlist + +Default: `` + + +### todoist + +Default: `` + +## avatar + + + +### gravatarexpiration + +When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires + +Default: `3600` + +### gravatarexpiration + +Default: `3600` + +## backgrounds + + + +### enabled + +Whether to enable backgrounds for lists at all. + +Default: `true` + +### enabled + +Default: `true` + +### providers + +Default: `` + +### providers + +Default: `` + +#### upload + +Default: `` + + +##### enabled + +Whethere to enable uploaded list backgrounds + +Default: `true` + +##### enabled + +Default: `true` + +#### unsplash + +Default: `` + + +##### enabled + +Whether to enable setting backgrounds from unsplash as list backgrounds + +Default: `false` + +##### enabled + +Default: `false` + +##### accesstoken + +You need to create an application for your installation at https://unsplash.com/oauth/applications/new +and set the access token below. + +Default: `` + +##### accesstoken + +Default: `` + +##### applicationid + +The unsplash application id is only used for pingback and required as per their api guidelines. +You can find the Application ID in the dashboard for your API application. It should be a numeric ID. +It will only show in the UI if your application has been approved for Enterprise usage, therefore if +you�re in Demo mode, you can also find the ID in the URL at the end: https://unsplash.com/oauth/applications/:application_id + +Default: `` + +## legal + +Legal urls +Will be shown in the frontend if configured here + + + +### imprinturl + +Default: `` + +### imprinturl + +Default: `` + +### privacyurl + +Default: `` + +## keyvalue + +Key Value Storage settings +The Key Value Storage is used for different kinds of things like metrics and a few cache systems. + + + +### type + +The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured seperately. + +Default: `memory` + +### type + +Default: `memory` + + chosen it needs to be configured seperately. + +Default: `` + +### type + +Default: `memory` + +## unsplash + +Default: `` + + +##### enabled + +Whether to enable setting backgrounds from unsplash as list backgrounds + +Default: `` + +##### enabled + +Default: `false` + +##### accesstoken + +You need to create an application for your installation at https://unsplash.com/oauth/applications/new +and set the access token below. + +Default: `` + +##### accesstoken + +Default: `` + +##### applicationid + +The unsplash application id is only used for pingback and required as per their api guidelines. +You can find the Application ID in the dashboard for your API application. It should be a numeric ID. +It will only show in the UI if your application has been approved for Enterprise usage, therefore if +you�re in Demo mode, you can also find the ID in the URL at the end: https://unsplash.com/oauth/applications/:application_id + +Default: `` + +##### applicationid + +Default: `` + +## legal + +Legal urls +Will be shown in the frontend if configured here + + + +### imprinturl + +Default: `` + +### imprinturl + +Default: `` + +### privacyurl + +Default: `` + +### privacyurl + +Default: `` + +## keyvalue + +Key Value Storage settings +The Key Value Storage is used for different kinds of things like metrics and a few cache systems. + + + +### type + +The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured seperately. + +Default: `` + +### type + +Default: `memory` -# Key Value Storage settings -# The Key Value Storage is used for different kinds of things like metrics and a few cache systems. -keyvalue: - # The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured seperately. - type: "memory" -{{< /highlight >}} diff --git a/magefile.go b/magefile.go index efab51287..fc91de798 100644 --- a/magefile.go +++ b/magefile.go @@ -746,7 +746,9 @@ func parseYamlConfigNode(node *yaml.Node) (config *configOption) { description: strings.ReplaceAll(node.HeadComment, "# ", ""), } - // TODO: second-level comments don't work + valMap := make(map[string]*configOption) + + var lastOption *configOption for i, n2 := range node.Content { coo := &configOption{ @@ -754,8 +756,23 @@ func parseYamlConfigNode(node *yaml.Node) (config *configOption) { description: strings.ReplaceAll(n2.HeadComment, "# ", ""), } + // If there's a key in valMap for the current key we should use that to append etc + // Else we just create a new configobject + co, exists := valMap[n2.Value] + if exists { + co.description = coo.description + } else { + valMap[n2.Value] = coo + config.children = append(config.children, coo) + } + + // fmt.Println(i, coo.key, coo.description, n2.Value) + if i%2 == 0 { + lastOption = coo continue + } else { + lastOption.defaultValue = n2.Value } if i-1 >= 0 && i-1 <= len(node.Content) && node.Content[i-1].Value != "" { @@ -763,8 +780,6 @@ func parseYamlConfigNode(node *yaml.Node) (config *configOption) { coo.key = node.Content[i-1].Value } - config.children = append(config.children, coo) - if len(n2.Content) > 0 { for _, n := range n2.Content { coo.children = append(coo.children, parseYamlConfigNode(n)) @@ -776,9 +791,20 @@ func parseYamlConfigNode(node *yaml.Node) (config *configOption) { } func printConfig(config []*configOption, level int) (rendered string) { + + // Keep track of what we already printed to prevent printing things twice + printed := make(map[string]bool) + for _, option := range config { + if option.key != "" { + // Filter out all config objects where the default value == key + // Yaml is weired: It gives you a slice with an entry each for the key and their value. + if printed[option.key] { + continue + } + rendered += "#" for i := 0; i <= level; i++ { rendered += "#" @@ -799,6 +825,7 @@ func printConfig(config []*configOption, level int) (rendered string) { } } + printed[option.key] = true rendered += "\n" + printConfig(option.children, level+1) } -- 2.40.1 From 8dc62240f3d79e339d2352b3dc11a91d93db372b Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 16 Oct 2020 22:14:52 +0200 Subject: [PATCH 7/8] Clarify docs --- docs/content/doc/setup/config.md | 358 ++++--------------------------- magefile.go | 8 +- 2 files changed, 54 insertions(+), 312 deletions(-) diff --git a/docs/content/doc/setup/config.md b/docs/content/doc/setup/config.md index b5e00e873..619867b55 100644 --- a/docs/content/doc/setup/config.md +++ b/docs/content/doc/setup/config.md @@ -27,7 +27,14 @@ first: child: true {{< /highlight >}} -## Config file locations +# Formats + +Vikunja supports using `toml`, `yaml`, `hcl`, `ini`, `json`, envfile, env variables and Java Properties files. +We reccomend yaml or toml, but you're free to use whatever you want. + +Vikunja provides a default [`config.yml`](https://kolaente.dev/vikunja/api/src/branch/master/config.yml.sample) file which you can use as a starting point. + +# Config file locations Vikunja will search on various places for a config file: @@ -38,10 +45,23 @@ Vikunja will search on various places for a config file: # Default configuration with explanations -This is the same as the `config.yml.sample` file you'll find in the root of vikunja. +The following explains all possible config variables and their defaults. +You can find a full example configuration file in [here](https://code.vikunja.io/api/src/branch/master/config.yml.sample). + +If you don't provide a value in your config file, their default will be used. + +## Nesting + +Most config variables are nested under some "higher-level" key. +For example, the `interface` config variable is a child of the `service` key. + +The docs below aim to reflect that leveling, but please also have a lookt at [the default config](https://code.vikunja.io/api/src/branch/master/config.yml.sample) file +to better grasp how the nesting looks like. +--- + ## service @@ -141,6 +161,8 @@ If not empty, enables logging of crashes and unhandled errors in sentry. Default: `` +--- + ## database @@ -206,6 +228,8 @@ Secure connection mode. Only used with postgres. Default: `disable` +--- + ## cache @@ -230,6 +254,8 @@ When using memory this defines the maximum size an element can take Default: `1000` +--- + ## redis @@ -258,6 +284,8 @@ Default: `` Default: `0` +--- + ## cors @@ -282,6 +310,8 @@ How long (in seconds) the results of a preflight request can be cached. Default: `0` +--- + ## mailer @@ -346,6 +376,8 @@ By default, vikunja will try to connect with starttls, use this option to force Default: `false` +--- + ## log @@ -398,6 +430,8 @@ Echo has its own logging which usually is unnessecary, which is why it is disabl Default: `off` +--- + ## ratelimit @@ -434,6 +468,8 @@ When choosing "keyvalue" this setting follows the one configured in the "keyvalu Default: `keyvalue` +--- + ## files @@ -451,6 +487,8 @@ Warning: The max size is limited 2^64-1 bytes due to the underlying datatype Default: `20MB` +--- + ## migration @@ -465,6 +503,8 @@ Default: `` Default: `` +--- + ## avatar @@ -475,6 +515,8 @@ When using gravatar, this is the duration in seconds until a cached gravatar use Default: `3600` +--- + ## backgrounds @@ -489,6 +531,8 @@ Default: `true` Default: `` +--- + ## legal Legal urls @@ -504,224 +548,7 @@ Default: `` Default: `` -## keyvalue - -Key Value Storage settings -The Key Value Storage is used for different kinds of things like metrics and a few cache systems. - - - -### type - -The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured seperately. - -Default: `memory` - -mit - -The max number of requests a user is allowed to do in the configured time period - -Default: `100` - -### limit - -Default: `100` - -### store - -The store where the limit counter for each user is stored. -Possible values are "keyvalue", "memory" or "redis". -When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. - -Default: `keyvalue` - -### store - -Default: `keyvalue` - -## files - - - -### basepath - -The path where files are stored - -Default: `./files` - -### basepath - -Default: `./files` - -### maxsize - -The maximum size of a file, as a human-readable string. -Warning: The max size is limited 2^64-1 bytes due to the underlying datatype - -Default: `20MB` - -### maxsize - -Default: `20MB` - -## migration - - - -### wunderlist - -These are the settings for the wunderlist migrator - -Default: `` - -### wunderlist - -Default: `` - -#### enable - -Wheter to enable the wunderlist migrator or not - -Default: `` - -#### false - -Default: `` - -#### clientid - -The client id, required for making requests to the wunderlist api -You need to register your vikunja instance at https://developer.wunderlist.com/apps/new to get this - -Default: `` - - -#### clientsecret - -The client secret, also required for making requests to the wunderlist api - -Default: `` - - -#### redirecturl - -The url where clients are redirected after they authorized Vikunja to access their wunderlist stuff. -This needs to match the url you entered when registering your Vikunja instance at wunderlist. -This is usually the frontend url where the frontend then makes a request to /migration/wunderlist/migrate -with the code obtained from the wunderlist api. -Note that the vikunja frontend expects this to be /migrate/wunderlist - -Default: `` - - -### todoist - -Default: `` - -## avatar - - - -### gravatarexpiration - -When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires - -Default: `3600` - -### gravatarexpiration - -Default: `3600` - -## backgrounds - - - -### enabled - -Whether to enable backgrounds for lists at all. - -Default: `true` - -### enabled - -Default: `true` - -### providers - -Default: `` - -### providers - -Default: `` - -#### upload - -Default: `` - - -##### enabled - -Whethere to enable uploaded list backgrounds - -Default: `true` - -##### enabled - -Default: `true` - -#### unsplash - -Default: `` - - -##### enabled - -Whether to enable setting backgrounds from unsplash as list backgrounds - -Default: `false` - -##### enabled - -Default: `false` - -##### accesstoken - -You need to create an application for your installation at https://unsplash.com/oauth/applications/new -and set the access token below. - -Default: `` - -##### accesstoken - -Default: `` - -##### applicationid - -The unsplash application id is only used for pingback and required as per their api guidelines. -You can find the Application ID in the dashboard for your API application. It should be a numeric ID. -It will only show in the UI if your application has been approved for Enterprise usage, therefore if -you�re in Demo mode, you can also find the ID in the URL at the end: https://unsplash.com/oauth/applications/:application_id - -Default: `` - -## legal - -Legal urls -Will be shown in the frontend if configured here - - - -### imprinturl - -Default: `` - -### imprinturl - -Default: `` - -### privacyurl - -Default: `` +--- ## keyvalue @@ -736,94 +563,3 @@ The type of the storage backend. Can be either "memory" or "redis". If "redis" i Default: `memory` -### type - -Default: `memory` - - chosen it needs to be configured seperately. - -Default: `` - -### type - -Default: `memory` - -## unsplash - -Default: `` - - -##### enabled - -Whether to enable setting backgrounds from unsplash as list backgrounds - -Default: `` - -##### enabled - -Default: `false` - -##### accesstoken - -You need to create an application for your installation at https://unsplash.com/oauth/applications/new -and set the access token below. - -Default: `` - -##### accesstoken - -Default: `` - -##### applicationid - -The unsplash application id is only used for pingback and required as per their api guidelines. -You can find the Application ID in the dashboard for your API application. It should be a numeric ID. -It will only show in the UI if your application has been approved for Enterprise usage, therefore if -you�re in Demo mode, you can also find the ID in the URL at the end: https://unsplash.com/oauth/applications/:application_id - -Default: `` - -##### applicationid - -Default: `` - -## legal - -Legal urls -Will be shown in the frontend if configured here - - - -### imprinturl - -Default: `` - -### imprinturl - -Default: `` - -### privacyurl - -Default: `` - -### privacyurl - -Default: `` - -## keyvalue - -Key Value Storage settings -The Key Value Storage is used for different kinds of things like metrics and a few cache systems. - - - -### type - -The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured seperately. - -Default: `` - -### type - -Default: `memory` - diff --git a/magefile.go b/magefile.go index fc91de798..550074de7 100644 --- a/magefile.go +++ b/magefile.go @@ -805,6 +805,10 @@ func printConfig(config []*configOption, level int) (rendered string) { continue } + if level == 0 { + rendered += "---\n\n" + } + rendered += "#" for i := 0; i <= level; i++ { rendered += "#" @@ -888,7 +892,9 @@ func GenerateDocs() error { fullConfig += "\n" + renderedConfig - if _, err := file.WriteAt([]byte(fullConfig), 0); err != nil { + // We write the full file to prevent old content leftovers at the end + // I know, there are probably better ways to do this. + if err := ioutil.WriteFile(configDocPath, []byte(fullConfig), 0); err != nil { return err } -- 2.40.1 From c3082b111fa8bee2b13a121e3aa96068950ae42d Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 16 Oct 2020 22:16:42 +0200 Subject: [PATCH 8/8] Add docs todo to PR template --- .gitea/pull_request_template.md | 2 +- magefile.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md index 437175d3f..b5bd61263 100644 --- a/.gitea/pull_request_template.md +++ b/.gitea/pull_request_template.md @@ -8,4 +8,4 @@ * [ ] I added or improved docs for my feature * [ ] Swagger (including `mage do-the-swag`) * [ ] Error codes - * [ ] New config options \ No newline at end of file + * [ ] New config options (including adding them to `config.yml.saml` and running `mage generate-docs`) diff --git a/magefile.go b/magefile.go index 550074de7..d835dad10 100644 --- a/magefile.go +++ b/magefile.go @@ -64,6 +64,7 @@ var ( "check:got-swag": Check.GotSwag, "release:os-package": Release.OsPackage, "dev:create-migration": Dev.CreateMigration, + "generate-docs": GenerateDocs, } ) -- 2.40.1