From bf542ab6841dd10cb77aaab2f3cf073546c3ecab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Fri, 6 Jun 2025 13:45:21 +0200 Subject: [PATCH] fix: Config loading from file --- README.md | 60 +++++++++++++++++++++++++-------------------------- util/cli.go | 4 ++-- util/flags.go | 58 ++++++++++++++++++++++++------------------------- 3 files changed, 60 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 501954f..1381df2 100644 --- a/README.md +++ b/README.md @@ -799,36 +799,36 @@ DESCRIPTION: Mark is a tool to update Atlassian Confluence pages from markdown. Documentation is available here: https://github.com/kovetskiy/mark GLOBAL OPTIONS: - --files string, -f string use specified markdown file(s) for converting to html. Supports file globbing patterns (needs to be quoted). [$MARK_FILES] - --continue-on-error don't exit if an error occurs while processing a file, continue processing remaining files. (default: false) [$MARK_CONTINUE_ON_ERROR] - --compile-only show resulting HTML and don't update Confluence page content. (default: false) [$MARK_COMPILE_ONLY] - --dry-run resolve page and ancestry, show resulting HTML and exit. (default: false) [$MARK_DRY_RUN] - --edit-lock, -k lock page editing to current user only to prevent accidental manual edits over Confluence Web UI. (default: false) [$MARK_EDIT_LOCK] - --drop-h1, --h1_drop don't include the first H1 heading in Confluence output. (default: false) [$MARK_H1_DROP] - --strip-linebreaks, -L remove linebreaks inside of tags, to accommodate non-standard Confluence behavior (default: false) [$MARK_STRIP_LINEBREAKS] - --title-from-h1, --h1_title extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata. (default: false) [$MARK_H1_TITLE] - --title-append-generated-hash appends a short hash generated from the path of the page (space, parents, and title) to the title (default: false) [$MARK_TITLE_APPEND_GENERATED_HASH] - --minor-edit don't send notifications while updating Confluence page. (default: false) [$MARK_MINOR_EDIT] - --version-message string add a message to the page version, to explain the edit (default: "") [$MARK_VERSION_MESSAGE] - --color string display logs in color. Possible values: auto, never. (default: "auto") [$MARK_COLOR] - --log-level string set the log level. Possible values: TRACE, DEBUG, INFO, WARNING, ERROR, FATAL. (default: "info") [$MARK_LOG_LEVEL] - --username string, -u string use specified username for updating Confluence page. [$MARK_USERNAME] - --password string, -p string use specified token for updating Confluence page. Specify - as password to read password from stdin, or your Personal access token. Username is not mandatory if personal access token is provided. For more info please see: https://developer.atlassian.com/server/confluence/confluence-server-rest-api/#authentication. [$MARK_PASSWORD] - --target-url string, -l string edit specified Confluence page. If -l is not specified, file should contain metadata (see above). [$MARK_TARGET_URL] - --base-url string, -b string, --base_url string base URL for Confluence. Alternative option for base_url config field. [$MARK_BASE_URL] - --config string, -c string use the specified configuration file. (default: "/home/mrueg/.config/mark") [$MARK_CONFIG] - --ci run on CI mode. It won't fail if files are not found. (default: false) [$MARK_CI] - --space string use specified space key. If the space key is not specified, it must be set in the page metadata. [$MARK_SPACE] - --parents string A list containing the parents of the document separated by parents-delimiter (default: '/'). These will be prepended to the ones defined in the document itself. [$MARK_PARENTS] - --parents-delimiter string The delimiter used for the parents list (default: "/") [$MARK_PARENTS_DELIMITER] - --mermaid-provider string defines the mermaid provider to use. Supported options are: cloudscript, mermaid-go. (default: "cloudscript") [$MARK_MERMAID_PROVIDER] - --mermaid-scale float defines the scaling factor for mermaid renderings. (default: 1) [$MARK_MERMAID_SCALE] - --include-path string Path for shared includes, used as a fallback if the include doesn't exist in the current directory. [$MARK_INCLUDE_PATH] - --changes-only Avoids re-uploading pages that haven't changed since the last run. (default: false) [$MARK_CHANGES_ONLY] - --d2-scale float defines the scaling factor for d2 renderings. (default: 1) [$MARK_D2_SCALE] - --features string [ --features string ] Enables optional features. Current features: d2, mermaid (default: "mermaid") [$MARK_FEATURES] - --help, -h show help - --version, -v print the version + --files string, -f string use specified markdown file(s) for converting to html. Supports file globbing patterns (needs to be quoted). [$MARK_FILES] + --continue-on-error don't exit if an error occurs while processing a file, continue processing remaining files. (default: false) [$MARK_CONTINUE_ON_ERROR] + --compile-only show resulting HTML and don't update Confluence page content. (default: false) [$MARK_COMPILE_ONLY] + --dry-run resolve page and ancestry, show resulting HTML and exit. (default: false) [$MARK_DRY_RUN] + --edit-lock, -k lock page editing to current user only to prevent accidental manual edits over Confluence Web UI. (default: false) [$MARK_EDIT_LOCK] + --drop-h1 don't include the first H1 heading in Confluence output. (default: false) [$MARK_DROP_H1] + --strip-linebreaks, -L remove linebreaks inside of tags, to accommodate non-standard Confluence behavior (default: false) [$MARK_STRIP_LINEBREAKS] + --title-from-h1 extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata. (default: false) [$MARK_TITLE_FROM_H1] + --title-append-generated-hash appends a short hash generated from the path of the page (space, parents, and title) to the title (default: false) [$MARK_TITLE_APPEND_GENERATED_HASH] + --minor-edit don't send notifications while updating Confluence page. (default: false) [$MARK_MINOR_EDIT] + --version-message string add a message to the page version, to explain the edit (default: "") [$MARK_VERSION_MESSAGE] + --color string display logs in color. Possible values: auto, never. (default: "auto") [$MARK_COLOR] + --log-level string set the log level. Possible values: TRACE, DEBUG, INFO, WARNING, ERROR, FATAL. (default: "info") [$MARK_LOG_LEVEL] + --username string, -u string use specified username for updating Confluence page. [$MARK_USERNAME] + --password string, -p string use specified token for updating Confluence page. Specify - as password to read password from stdin, or your Personal access token. Username is not mandatory if personal access token is provided. For more info please see: https://developer.atlassian.com/server/confluence/confluence-server-rest-api/#authentication. [$MARK_PASSWORD] + --target-url string, -l string edit specified Confluence page. If -l is not specified, file should contain metadata (see above). [$MARK_TARGET_URL] + --base-url string, -b string base URL for Confluence. Alternative option for base_url config field. [$MARK_BASE_URL] + --config string, -c string use the specified configuration file. (default: $HOME/.config/mark.toml") [$MARK_CONFIG] + --ci run on CI mode. It won't fail if files are not found. (default: false) [$MARK_CI] + --space string use specified space key. If the space key is not specified, it must be set in the page metadata. [$MARK_SPACE] + --parents string A list containing the parents of the document separated by parents-delimiter (default: '/'). These will be prepended to the ones defined in the document itself. [$MARK_PARENTS] + --parents-delimiter string The delimiter used for the parents list (default: "/") [$MARK_PARENTS_DELIMITER] + --mermaid-provider string defines the mermaid provider to use. Supported options are: cloudscript, mermaid-go. (default: "cloudscript") [$MARK_MERMAID_PROVIDER] + --mermaid-scale float defines the scaling factor for mermaid renderings. (default: 1) [$MARK_MERMAID_SCALE] + --include-path string Path for shared includes, used as a fallback if the include doesn't exist in the current directory. [$MARK_INCLUDE_PATH] + --changes-only Avoids re-uploading pages that haven't changed since the last run. (default: false) [$MARK_CHANGES_ONLY] + --d2-scale float defines the scaling factor for d2 renderings. (default: 1) [$MARK_D2_SCALE] + --features string [ --features string ] Enables optional features. Current features: d2, mermaid (default: "mermaid") [$MARK_FEATURES] + --help, -h show help + --version, -v print the version ``` You can store user credentials in the configuration file, which should be diff --git a/util/cli.go b/util/cli.go index 4aed017..3dbfaae 100644 --- a/util/cli.go +++ b/util/cli.go @@ -143,7 +143,7 @@ func processFile( } if meta.Title == "" { - fatalErrorHandler.Handle(nil, "page title is not set ('Title' header is not set and '--title-from-h1' option and 'h1_title' config is not set or there is no H1 in the file)") + fatalErrorHandler.Handle(nil, "page title is not set ('Title' header is not set and '--title-from-h1' option and 'h1-title' config is not set or there is no H1 in the file)") return nil } } @@ -481,7 +481,7 @@ func ConfigFilePath() string { if err != nil { log.Fatal(err) } - return filepath.Join(fp, "mark") + return filepath.Join(fp, "mark.toml") } func SetLogLevel(cmd *cli.Command) error { diff --git a/util/flags.go b/util/flags.go index 39fdde6..0cf01c6 100644 --- a/util/flags.go +++ b/util/flags.go @@ -6,9 +6,7 @@ import ( "github.com/urfave/cli/v3" ) -var filename = ConfigFilePath() - -var configFile = altsrc.NewStringPtrSourcer(&filename) +var filename string var Flags = []cli.Flag{ &cli.StringFlag{ @@ -17,82 +15,82 @@ var Flags = []cli.Flag{ Value: "", Usage: "use specified markdown file(s) for converting to html. Supports file globbing patterns (needs to be quoted).", TakesFile: true, - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FILES"), altsrctoml.TOML("files", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FILES"), altsrctoml.TOML("files", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "continue-on-error", Value: false, Usage: "don't exit if an error occurs while processing a file, continue processing remaining files.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_CONTINUE_ON_ERROR"), altsrctoml.TOML("continue-on-error", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_CONTINUE_ON_ERROR"), altsrctoml.TOML("continue-on-error", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "compile-only", Value: false, Usage: "show resulting HTML and don't update Confluence page content.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_COMPILE_ONLY"), altsrctoml.TOML("compile-only", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_COMPILE_ONLY"), altsrctoml.TOML("compile-only", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "dry-run", Value: false, Usage: "resolve page and ancestry, show resulting HTML and exit.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_DRY_RUN"), altsrctoml.TOML("dry-run", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_DRY_RUN"), altsrctoml.TOML("dry-run", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "edit-lock", Value: false, Aliases: []string{"k"}, Usage: "lock page editing to current user only to prevent accidental manual edits over Confluence Web UI.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_EDIT_LOCK"), altsrctoml.TOML("edit-lock", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_EDIT_LOCK"), altsrctoml.TOML("edit-lock", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "drop-h1", Value: false, Usage: "don't include the first H1 heading in Confluence output.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_DROP_H1"), altsrctoml.TOML("drop-h1", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_DROP_H1"), altsrctoml.TOML("drop-h1", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "strip-linebreaks", Value: false, Aliases: []string{"L"}, Usage: "remove linebreaks inside of tags, to accommodate non-standard Confluence behavior", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_STRIP_LINEBREAKS"), altsrctoml.TOML("strip-linebreaks", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_STRIP_LINEBREAKS"), altsrctoml.TOML("strip-linebreaks", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "title-from-h1", Value: false, Usage: "extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_FROM_H1"), altsrctoml.TOML("title-from-h1", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_FROM_H1"), altsrctoml.TOML("title-from-h1", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "title-append-generated-hash", Value: false, Usage: "appends a short hash generated from the path of the page (space, parents, and title) to the title", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_APPEND_GENERATED_HASH"), altsrctoml.TOML("title-append-generated-hash", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_APPEND_GENERATED_HASH"), altsrctoml.TOML("title-append-generated-hash", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "minor-edit", Value: false, Usage: "don't send notifications while updating Confluence page.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_MINOR_EDIT"), altsrctoml.TOML("minor-edit", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_MINOR_EDIT"), altsrctoml.TOML("minor-edit", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "version-message", Value: "", Usage: "add a message to the page version, to explain the edit (default: \"\")", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_VERSION_MESSAGE"), altsrctoml.TOML("version-message", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_VERSION_MESSAGE"), altsrctoml.TOML("version-message", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "color", Value: "auto", Usage: "display logs in color. Possible values: auto, never.", Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_COLOR"), - altsrctoml.TOML("color", configFile)), + altsrctoml.TOML("color", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "log-level", Value: "info", Usage: "set the log level. Possible values: TRACE, DEBUG, INFO, WARNING, ERROR, FATAL.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_LOG_LEVEL"), altsrctoml.TOML("log-level", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_LOG_LEVEL"), altsrctoml.TOML("log-level", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "username", @@ -100,21 +98,21 @@ var Flags = []cli.Flag{ Value: "", Usage: "use specified username for updating Confluence page.", Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_USERNAME"), - altsrctoml.TOML("username", configFile)), + altsrctoml.TOML("username", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "password", Aliases: []string{"p"}, Value: "", Usage: "use specified token for updating Confluence page. Specify - as password to read password from stdin, or your Personal access token. Username is not mandatory if personal access token is provided. For more info please see: https://developer.atlassian.com/server/confluence/confluence-server-rest-api/#authentication.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PASSWORD"), altsrctoml.TOML("password", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PASSWORD"), altsrctoml.TOML("password", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "target-url", Aliases: []string{"l"}, Value: "", Usage: "edit specified Confluence page. If -l is not specified, file should contain metadata (see above).", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TARGET_URL"), altsrctoml.TOML("target-url", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TARGET_URL"), altsrctoml.TOML("target-url", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "base-url", @@ -122,7 +120,7 @@ var Flags = []cli.Flag{ Value: "", Usage: "base URL for Confluence. Alternative option for base_url config field.", Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_BASE_URL"), - altsrctoml.TOML("base-url", configFile)), + altsrctoml.TOML("base-url", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "config", @@ -137,62 +135,62 @@ var Flags = []cli.Flag{ Name: "ci", Value: false, Usage: "run on CI mode. It won't fail if files are not found.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_CI"), altsrctoml.TOML("ci", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_CI"), altsrctoml.TOML("ci", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "space", Value: "", Usage: "use specified space key. If the space key is not specified, it must be set in the page metadata.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_SPACE"), altsrctoml.TOML("space", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_SPACE"), altsrctoml.TOML("space", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "parents", Value: "", Usage: "A list containing the parents of the document separated by parents-delimiter (default: '/'). These will be prepended to the ones defined in the document itself.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PARENTS"), altsrctoml.TOML("parents", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PARENTS"), altsrctoml.TOML("parents", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "parents-delimiter", Value: "/", Usage: "The delimiter used for the parents list", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PARENTS_DELIMITER"), altsrctoml.TOML("parents-delimiter", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PARENTS_DELIMITER"), altsrctoml.TOML("parents-delimiter", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "mermaid-provider", Value: "cloudscript", Usage: "defines the mermaid provider to use. Supported options are: cloudscript, mermaid-go.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_MERMAID_PROVIDER"), altsrctoml.TOML("mermaid-provider", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_MERMAID_PROVIDER"), altsrctoml.TOML("mermaid-provider", altsrc.NewStringPtrSourcer(&filename))), }, &cli.FloatFlag{ Name: "mermaid-scale", Value: 1.0, Usage: "defines the scaling factor for mermaid renderings.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_MERMAID_SCALE"), altsrctoml.TOML("mermaid-scale", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_MERMAID_SCALE"), altsrctoml.TOML("mermaid-scale", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringFlag{ Name: "include-path", Value: "", Usage: "Path for shared includes, used as a fallback if the include doesn't exist in the current directory.", TakesFile: true, - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_INCLUDE_PATH"), altsrctoml.TOML("include-path", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_INCLUDE_PATH"), altsrctoml.TOML("include-path", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "changes-only", Value: false, Usage: "Avoids re-uploading pages that haven't changed since the last run.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_CHANGES_ONLY"), altsrctoml.TOML("changes-only", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_CHANGES_ONLY"), altsrctoml.TOML("changes-only", altsrc.NewStringPtrSourcer(&filename))), }, &cli.FloatFlag{ Name: "d2-scale", Value: 1.0, Usage: "defines the scaling factor for d2 renderings.", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_D2_SCALE"), altsrctoml.TOML("d2-scale", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_D2_SCALE"), altsrctoml.TOML("d2-scale", altsrc.NewStringPtrSourcer(&filename))), }, &cli.StringSliceFlag{ Name: "features", Value: []string{"mermaid"}, Usage: "Enables optional features. Current features: d2, mermaid", - Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FEATURES"), altsrctoml.TOML("features", configFile)), + Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FEATURES"), altsrctoml.TOML("features", altsrc.NewStringPtrSourcer(&filename))), }, }