From 8d0d7bc28d517acc9ca98f0468d7ff2a4fdaf139 Mon Sep 17 00:00:00 2001 From: zeripath Date: Mon, 29 Apr 2019 19:08:21 +0100 Subject: [PATCH] Make CustomPath, CustomConf and AppWorkPath configurable at build (#6631) --- Makefile | 12 +- cmd/admin.go | 76 ------------- cmd/dump.go | 8 -- cmd/hook.go | 26 ----- cmd/keys.go | 10 -- cmd/migrate.go | 11 -- cmd/serv.go | 8 -- cmd/web.go | 9 -- contrib/pr/checkout.go | 1 + docker/Makefile | 3 +- .../doc/advanced/customizing-gitea.en-us.md | 24 ++-- .../doc/installation/from-source.en-us.md | 23 ++++ docs/content/doc/usage/command-line.en-us.md | 22 ++-- integrations/integration_test.go | 1 + main.go | 103 ++++++++++++++++++ models/ssh_key_test.go | 1 + modules/setting/setting.go | 39 ++++--- 17 files changed, 184 insertions(+), 193 deletions(-) diff --git a/Makefile b/Makefile index ab5519726d..d8c2b8166e 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,9 @@ SHASUM ?= shasum -a 256 export PATH := $($(GO) env GOPATH)/bin:$(PATH) ifeq ($(OS), Windows_NT) - EXECUTABLE := gitea.exe + EXECUTABLE ?= gitea.exe else - EXECUTABLE := gitea + EXECUTABLE ?= gitea UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) SED_INPLACE := sed -i '' @@ -39,7 +39,7 @@ else GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//') endif -LDFLAGS := -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" +LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell $(GO) list ./... | grep -v /vendor/))) SOURCES ?= $(shell find . -name "*.go" -type f) @@ -70,12 +70,6 @@ TEST_MSSQL_DBNAME ?= gitea TEST_MSSQL_USERNAME ?= sa TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1 -ifeq ($(OS), Windows_NT) - EXECUTABLE := gitea.exe -else - EXECUTABLE := gitea -endif - # $(call strip-suffix,filename) strip-suffix = $(firstword $(subst ., ,$(1))) diff --git a/cmd/admin.go b/cmd/admin.go index b46eb2871e..be21ec0f36 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -60,11 +60,6 @@ var ( Name: "admin", Usage: "User is an admin", }, - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, cli.BoolFlag{ Name: "random-password", Usage: "Generate a random password for the user", @@ -96,11 +91,6 @@ var ( Value: "", Usage: "New password to set for user", }, - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, }, } @@ -123,26 +113,12 @@ var ( Name: "hooks", Usage: "Regenerate git-hooks", Action: runRegenerateHooks, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, - }, } microcmdRegenKeys = cli.Command{ Name: "keys", Usage: "Regenerate authorized_keys file", Action: runRegenerateKeys, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, - }, } subcmdAuth = cli.Command{ @@ -160,13 +136,6 @@ var ( Name: "list", Usage: "List auth sources", Action: runListAuth, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, - }, } idFlag = cli.Int64Flag{ @@ -178,22 +147,9 @@ var ( Name: "delete", Usage: "Delete specific auth source", Action: runDeleteAuth, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, - idFlag, - }, } oauthCLIFlags = []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, cli.StringFlag{ Name: "name", Value: "", @@ -266,10 +222,6 @@ func runChangePassword(c *cli.Context) error { return err } - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if err := initDB(); err != nil { return err } @@ -331,10 +283,6 @@ func runCreateUser(c *cli.Context) error { return errors.New("must set either password or random-password flag") } - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if err := initDB(); err != nil { return err } @@ -430,10 +378,6 @@ func getReleaseCount(id int64) (int64, error) { } func runRegenerateHooks(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if err := initDB(); err != nil { return err } @@ -441,10 +385,6 @@ func runRegenerateHooks(c *cli.Context) error { } func runRegenerateKeys(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if err := initDB(); err != nil { return err } @@ -473,10 +413,6 @@ func parseOAuth2Config(c *cli.Context) *models.OAuth2Config { } func runAddOauth(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if err := initDB(); err != nil { return err } @@ -490,10 +426,6 @@ func runAddOauth(c *cli.Context) error { } func runUpdateOauth(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if !c.IsSet("id") { return fmt.Errorf("--id flag is missing") } @@ -561,10 +493,6 @@ func runUpdateOauth(c *cli.Context) error { } func runListAuth(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if err := initDB(); err != nil { return err } @@ -587,10 +515,6 @@ func runListAuth(c *cli.Context) error { } func runDeleteAuth(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if !c.IsSet("id") { return fmt.Errorf("--id flag is missing") } diff --git a/cmd/dump.go b/cmd/dump.go index 98e930f2fb..a9e83f36d9 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -30,11 +30,6 @@ var CmdDump = cli.Command{ It can be used for backup and capture Gitea server image to send to maintainer`, Action: runDump, Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, cli.StringFlag{ Name: "file, f", Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()), @@ -61,9 +56,6 @@ It can be used for backup and capture Gitea server image to send to maintainer`, } func runDump(ctx *cli.Context) error { - if ctx.IsSet("config") { - setting.CustomConf = ctx.String("config") - } setting.NewContext() setting.NewServices() // cannot access session settings otherwise models.LoadConfigs() diff --git a/cmd/hook.go b/cmd/hook.go index 88e61c61d1..46f97d5542 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -16,7 +16,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "github.com/urfave/cli" @@ -28,13 +27,6 @@ var ( Name: "hook", Usage: "Delegate commands to corresponding Git hooks", Description: "This should only be called by Git", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, - }, Subcommands: []cli.Command{ subcmdHookPreReceive, subcmdHookUpdate, @@ -67,12 +59,6 @@ func runHookPreReceive(c *cli.Context) error { return nil } - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } else if c.GlobalIsSet("config") { - setting.CustomConf = c.GlobalString("config") - } - setup("hooks/pre-receive.log") // the environment setted on serv command @@ -143,12 +129,6 @@ func runHookUpdate(c *cli.Context) error { return nil } - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } else if c.GlobalIsSet("config") { - setting.CustomConf = c.GlobalString("config") - } - setup("hooks/update.log") return nil @@ -159,12 +139,6 @@ func runHookPostReceive(c *cli.Context) error { return nil } - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } else if c.GlobalIsSet("config") { - setting.CustomConf = c.GlobalString("config") - } - setup("hooks/post-receive.log") // the environment setted on serv command diff --git a/cmd/keys.go b/cmd/keys.go index 66565cc563..39153c7cb7 100644 --- a/cmd/keys.go +++ b/cmd/keys.go @@ -10,7 +10,6 @@ import ( "strings" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/setting" "github.com/urfave/cli" ) @@ -41,19 +40,10 @@ var CmdKeys = cli.Command{ Value: "", Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)", }, - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, }, } func runKeys(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } - if !c.IsSet("username") { return errors.New("No username provided") } diff --git a/cmd/migrate.go b/cmd/migrate.go index 3e6bf907a4..dde50a455f 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -19,20 +19,9 @@ var CmdMigrate = cli.Command{ Usage: "Migrate the database", Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.", Action: runMigrate, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, - }, } func runMigrate(ctx *cli.Context) error { - if ctx.IsSet("config") { - setting.CustomConf = ctx.String("config") - } - if err := initDB(); err != nil { return err } diff --git a/cmd/serv.go b/cmd/serv.go index ebd71ad3c7..a30e02e7a2 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -39,11 +39,6 @@ var CmdServ = cli.Command{ Description: `Serv provide access auth for repositories`, Action: runServ, Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, cli.BoolFlag{ Name: "enable-pprof", }, @@ -109,9 +104,6 @@ func fail(userMessage, logMessage string, args ...interface{}) { } func runServ(c *cli.Context) error { - if c.IsSet("config") { - setting.CustomConf = c.String("config") - } setup("serv.log") if setting.SSH.Disabled { diff --git a/cmd/web.go b/cmd/web.go index 4641645ee4..6da6ec942e 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -40,11 +40,6 @@ and it takes care of all the other things for you`, Value: "3000", Usage: "Temporary port number to prevent conflict", }, - cli.StringFlag{ - Name: "config, c", - Value: "custom/conf/app.ini", - Usage: "Custom configuration file path", - }, cli.StringFlag{ Name: "pid, P", Value: "/var/run/gitea.pid", @@ -110,10 +105,6 @@ func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { } func runWeb(ctx *cli.Context) error { - if ctx.IsSet("config") { - setting.CustomConf = ctx.String("config") - } - if ctx.IsSet("pid") { setting.CustomPID = ctx.String("pid") } diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go index 9fe1eb573c..bc393da135 100644 --- a/contrib/pr/checkout.go +++ b/contrib/pr/checkout.go @@ -43,6 +43,7 @@ func runPR() { if err != nil { log.Fatal(err) } + setting.SetCustomPathAndConf("", "") setting.NewContext() setting.RepoRootPath, err = ioutil.TempDir(os.TempDir(), "repos") diff --git a/docker/Makefile b/docker/Makefile index 80e7ae34b3..99935023e3 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -4,7 +4,6 @@ DOCKER_IMAGE ?= gitea/gitea DOCKER_TAG ?= latest DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG) - .PHONY: docker docker: docker build --disable-content-trust=false -t $(DOCKER_REF) . @@ -12,4 +11,4 @@ docker: .PHONY: docker-build docker-build: - docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" webhippie/golang:edge make clean generate build + docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" webhippie/golang:edge make clean generate build diff --git a/docs/content/doc/advanced/customizing-gitea.en-us.md b/docs/content/doc/advanced/customizing-gitea.en-us.md index 983fe5f0c7..69cf58b3bf 100644 --- a/docs/content/doc/advanced/customizing-gitea.en-us.md +++ b/docs/content/doc/advanced/customizing-gitea.en-us.md @@ -15,19 +15,28 @@ menu: # Customizing Gitea -Customizing Gitea is typically done using the `custom` folder. This is the central -place to override configuration settings, templates, etc. +Customizing Gitea is typically done using the `CustomPath` folder - by default this is +the `custom` folder from the running directory, but may be different if your build has +set this differently. This is the central place to override configuration settings, +templates, etc. You can check the `CustomPath` using `gitea help`. You can override +the `CustomPath` by setting either the `GITEA_CUSTOM` environment variable or by +using the `--custom-path` option on the `gitea` binary. (The option will override the +environment variable.) If Gitea is deployed from binary, all default paths will be relative to the Gitea binary. If installed from a distribution, these paths will likely be modified to -the Linux Filesystem Standard. Gitea will create required folders, including `custom/`. -Application settings are configured in `custom/conf/app.ini`. Distributions may -provide a symlink for `custom` using `/etc/gitea/`. +the Linux Filesystem Standard. Gitea will attempt to create required folders, including +`custom/`. Distributions may provide a symlink for `custom` using `/etc/gitea/`. + +Application settings can be found in file `CustomConf` which is by default, +`CustomPath/conf/app.ini` but may be different if your build has set this differently. +Again `gitea help` will allow you review this variable and you can override it using the +`--config` option on the `gitea` binary. - [Quick Cheat Sheet](https://docs.gitea.io/en-us/config-cheat-sheet/) - [Complete List](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample) -If the `custom` folder can't be found next to the binary, check the `GITEA_CUSTOM` +If the `CustomPath` folder can't be found despite checking `gitea help`, check the `GITEA_CUSTOM` environment variable; this can be used to override the default path to something else. `GITEA_CUSTOM` might, for example, be set by an init script. @@ -38,7 +47,8 @@ environment variable; this can be used to override the default path to something ## Customizing /robots.txt To make Gitea serve a custom `/robots.txt` (default: empty 404), create a file called -`robots.txt` in the `custom` folder with [expected contents](http://www.robotstxt.org/). +`robots.txt` in the `custom` folder (or `CustomPath`) with +[expected contents](http://www.robotstxt.org/). ## Serving custom public files diff --git a/docs/content/doc/installation/from-source.en-us.md b/docs/content/doc/installation/from-source.en-us.md index 73e9501eb7..ce5915cc3f 100644 --- a/docs/content/doc/installation/from-source.en-us.md +++ b/docs/content/doc/installation/from-source.en-us.md @@ -117,3 +117,26 @@ launched manually from command line, it can be killed by pressing `Ctrl + C`. ```bash ./gitea web ``` + +## Changing the default CustomPath, CustomConf and AppWorkDir + +Gitea will search for a number of things from the `CustomPath`. By default this is +the `custom/` directory in the current working directory when running Gitea. It will also +look for its configuration file `CustomConf` in `$CustomPath/conf/app.ini`, and will use the +current working directory as the relative base path `AppWorkDir` for a number configurable +values. + +These values, although useful when developing, may conflict with downstream users preferences. + +One option is to use a script file to shadow the `gitea` binary and create an appropriate +environment before running Gitea. However, when building you can change these defaults +using the `LDFLAGS` environment variable for `make`. The appropriate settings are as follows + +* To set the `CustomPath` use `LDFLAGS="-X \"code.gitea.io/gitea/modules/setting.CustomPath=custom-path\""` +* For `CustomConf` you should use `-X \"code.gitea.io/gitea/modules/setting.CustomConf=conf.ini\"` +* For `AppWorkDir` you should use `-X \"code.gitea.io/gitea/modules/setting.AppWorkDir=working-directory\"` + +Add as many of the strings with their preceding `-X` to the `LDFLAGS` variable and run `make build` +with the appropriate `TAGS` as above. + +Running `gitea help` will allow you to review what the computed settings will be for your `gitea`. diff --git a/docs/content/doc/usage/command-line.en-us.md b/docs/content/doc/usage/command-line.en-us.md index df749ebe04..342af930a9 100644 --- a/docs/content/doc/usage/command-line.en-us.md +++ b/docs/content/doc/usage/command-line.en-us.md @@ -17,13 +17,16 @@ menu: ### Usage -`gitea [global options] command [command options] [arguments...]` +`gitea [global options] command [command or global options] [arguments...]` ### Global options - - `--help`, `-h`: Show help text and exit. Optional. This can be used with any of the - subcommands to see help text for it. - - `--version`, `-v`: Show version and exit. Optional. (example: `Gitea version - 1.1.0+218-g7b907ed built with: bindata, sqlite`). + +All global options can be placed at the command level. + +- `--help`, `-h`: Show help text and exit. Optional. +- `--version`, `-v`: Show version and exit. Optional. (example: `Gitea version 1.1.0+218-g7b907ed built with: bindata, sqlite`). +- `--custom-path path`, `-C path`: Location of the Gitea custom folder. Optional. (default: $PWD/custom). +- `--config path`, `-c path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). ### Commands @@ -33,7 +36,6 @@ Starts the server: - Options: - `--port number`, `-p number`: Port number. Optional. (default: 3000). Overrides configuration file. - - `--config path`, `-c path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - `--pid path`, `-P path`: Pidfile path. Optional. - Examples: - `gitea web` @@ -56,7 +58,6 @@ Admin operations: - `--password value`: Password. Required. - `--email value`: Email. Required. - `--admin`: If provided, this makes the user an admin. Optional. - - `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - `--must-change-password`: If provided, the created user will be required to choose a newer password after the initial login. Optional. (default: true). - ``--random-password``: If provided, a randomly generated password will be used as the password of @@ -69,7 +70,6 @@ Admin operations: - Options: - `--username value`, `-u value`: Username. Required. - `--password value`, `-p value`: New password. Required. - - `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - Examples: - `gitea admin change-password --username myname --password asecurepassword` - `regenerate` @@ -82,19 +82,15 @@ Admin operations: - `auth`: - `list`: - Description: lists all external authentication sources that exist - - Options: - - `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - Examples: - `gitea admin auth list` - `delete`: - Options: - `--id`: ID of source to be deleted. Required. - - `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - Examples: - `gitea admin auth delete --id 1` - `add-oauth`: - Options: - - `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - `--name`: Application Name. - `--provider`: OAuth2 Provider. - `--key`: Client ID (Key). @@ -110,7 +106,6 @@ Admin operations: - `update-oauth`: - Options: - `--id`: ID of source to be updated. Required. - - `--config path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - `--name`: Application Name. - `--provider`: OAuth2 Provider. - `--key`: Client ID (Key). @@ -148,7 +143,6 @@ Dumps all files and databases into a zip file. Outputs into a file like `gitea-d in the current directory. - Options: - - `--config path`, `-c path`: Gitea configuration file path. Optional. (default: custom/conf/app.ini). - `--file name`, `-f name`: Name of the dump file with will be created. Optional. (default: gitea-dump-[timestamp].zip). - `--tempdir path`, `-t path`: Path to the temporary directory used. Optional. (default: /tmp). - `--skip-repository`, `-R`: Skip the repository dumping. Optional. diff --git a/integrations/integration_test.go b/integrations/integration_test.go index 43c8179430..566859518a 100644 --- a/integrations/integration_test.go +++ b/integrations/integration_test.go @@ -118,6 +118,7 @@ func initIntegrationTest() { setting.CustomConf = giteaConf } + setting.SetCustomPathAndConf("", "") setting.NewContext() setting.CheckLFSVersion() models.LoadConfigs() diff --git a/main.go b/main.go index 989ae1c58c..102450f906 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ package main // import "code.gitea.io/gitea" import ( + "fmt" "os" "runtime" "strings" @@ -30,11 +31,20 @@ var ( Tags = "" // MakeVersion holds the current Make version if built with make MakeVersion = "" + + originalAppHelpTemplate = "" + originalCommandHelpTemplate = "" + originalSubcommandHelpTemplate = "" ) func init() { setting.AppVer = Version setting.AppBuiltWith = formatBuiltWith(Tags) + + // Grab the original help templates + originalAppHelpTemplate = cli.AppHelpTemplate + originalCommandHelpTemplate = cli.CommandHelpTemplate + originalSubcommandHelpTemplate = cli.SubcommandHelpTemplate } func main() { @@ -55,14 +65,107 @@ arguments - which can alternatively be run by running the subcommand web.` cmd.CmdMigrate, cmd.CmdKeys, } + // Now adjust these commands to add our global configuration options + + // First calculate the default paths and set the AppHelpTemplates in this context + setting.SetCustomPathAndConf("", "") + setAppHelpTemplates() + + // default configuration flags + defaultFlags := []cli.Flag{ + cli.StringFlag{ + Name: "custom-path, C", + Value: setting.CustomPath, + Usage: "Custom path file path", + }, + cli.StringFlag{ + Name: "config, c", + Value: setting.CustomConf, + Usage: "Custom configuration file path", + }, + cli.VersionFlag, + } + + // Set the default to be equivalent to cmdWeb and add the default flags app.Flags = append(app.Flags, cmd.CmdWeb.Flags...) + app.Flags = append(app.Flags, defaultFlags...) app.Action = cmd.CmdWeb.Action + + // Add functions to set these paths and these flags to the commands + app.Before = establishCustomPath + for i := range app.Commands { + setFlagsAndBeforeOnSubcommands(&app.Commands[i], defaultFlags, establishCustomPath) + } + err := app.Run(os.Args) if err != nil { log.Fatal("Failed to run app with %s: %v", os.Args, err) } } +func setFlagsAndBeforeOnSubcommands(command *cli.Command, defaultFlags []cli.Flag, before cli.BeforeFunc) { + command.Flags = append(command.Flags, defaultFlags...) + command.Before = establishCustomPath + for i := range command.Subcommands { + setFlagsAndBeforeOnSubcommands(&command.Subcommands[i], defaultFlags, before) + } +} + +func establishCustomPath(ctx *cli.Context) error { + var providedCustom string + var providedConf string + + currentCtx := ctx + for { + if len(providedCustom) != 0 && len(providedConf) != 0 { + break + } + if currentCtx == nil { + break + } + if currentCtx.IsSet("custom-path") && len(providedCustom) == 0 { + providedCustom = currentCtx.String("custom-path") + } + if currentCtx.IsSet("config") && len(providedConf) == 0 { + providedConf = currentCtx.String("config") + } + currentCtx = currentCtx.Parent() + + } + setting.SetCustomPathAndConf(providedCustom, providedConf) + + setAppHelpTemplates() + + if ctx.IsSet("version") { + cli.ShowVersion(ctx) + os.Exit(0) + } + + return nil +} + +func setAppHelpTemplates() { + cli.AppHelpTemplate = adjustHelpTemplate(originalAppHelpTemplate) + cli.CommandHelpTemplate = adjustHelpTemplate(originalCommandHelpTemplate) + cli.SubcommandHelpTemplate = adjustHelpTemplate(originalSubcommandHelpTemplate) +} + +func adjustHelpTemplate(originalTemplate string) string { + overrided := "" + if _, ok := os.LookupEnv("GITEA_CUSTOM"); ok { + overrided = "(GITEA_CUSTOM)" + } + + return fmt.Sprintf(`%s +DEFAULT CONFIGURATION: + CustomPath: %s %s + CustomConf: %s + AppPath: %s + AppWorkPath: %s + +`, originalTemplate, setting.CustomPath, overrided, setting.CustomConf, setting.AppPath, setting.AppWorkPath) +} + func formatBuiltWith(makeTags string) string { var version = runtime.Version() if len(MakeVersion) > 0 { diff --git a/models/ssh_key_test.go b/models/ssh_key_test.go index beb4556b8b..f310935a32 100644 --- a/models/ssh_key_test.go +++ b/models/ssh_key_test.go @@ -14,6 +14,7 @@ import ( ) func init() { + setting.SetCustomPathAndConf("", "") setting.NewContext() } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 85fcbac2b1..692fb9820a 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -391,12 +391,12 @@ func getAppPath() (string, error) { } func getWorkPath(appPath string) string { - workPath := "" - giteaWorkPath := os.Getenv("GITEA_WORK_DIR") + workPath := AppWorkPath - if len(giteaWorkPath) > 0 { + if giteaWorkPath, ok := os.LookupEnv("GITEA_WORK_DIR"); ok { workPath = giteaWorkPath - } else { + } + if len(workPath) == 0 { i := strings.LastIndex(appPath, "/") if i == -1 { workPath = appPath @@ -475,27 +475,40 @@ func CheckLFSVersion() { } } -// NewContext initializes configuration context. -// NOTE: do not print any log except error. -func NewContext() { - Cfg = ini.Empty() - - CustomPath = os.Getenv("GITEA_CUSTOM") +// SetCustomPathAndConf will set CustomPath and CustomConf with reference to the +// GITEA_CUSTOM environment variable and with provided overrides before stepping +// back to the default +func SetCustomPathAndConf(providedCustom, providedConf string) { + if giteaCustom, ok := os.LookupEnv("GITEA_CUSTOM"); ok { + CustomPath = giteaCustom + } + if len(providedCustom) != 0 { + CustomPath = providedCustom + } if len(CustomPath) == 0 { CustomPath = path.Join(AppWorkPath, "custom") } else if !filepath.IsAbs(CustomPath) { CustomPath = path.Join(AppWorkPath, CustomPath) } - if len(CustomPID) > 0 { - createPIDFile(CustomPID) + if len(providedConf) != 0 { + CustomConf = providedConf } - if len(CustomConf) == 0 { CustomConf = path.Join(CustomPath, "conf/app.ini") } else if !filepath.IsAbs(CustomConf) { CustomConf = path.Join(CustomPath, CustomConf) } +} + +// NewContext initializes configuration context. +// NOTE: do not print any log except error. +func NewContext() { + Cfg = ini.Empty() + + if len(CustomPID) > 0 { + createPIDFile(CustomPID) + } if com.IsFile(CustomConf) { if err := Cfg.Append(CustomConf); err != nil {