* General refactor of the cmd package * Address breakage in runCreateUser * Place "common" functions into cmd.gotags/v1.4.0-rc1
@@ -20,9 +20,7 @@ var ( | |||
// CmdAdmin represents the available admin sub-command. | |||
CmdAdmin = cli.Command{ | |||
Name: "admin", | |||
Usage: "Perform admin operations on command line", | |||
Description: `Allow using internal logic of Gitea without hacking into the source code | |||
to make automatic initialization process more smoothly`, | |||
Usage: "Command line interface to perform common administrative operations", | |||
Subcommands: []cli.Command{ | |||
subcmdCreateUser, | |||
subcmdChangePassword, | |||
@@ -37,17 +35,14 @@ to make automatic initialization process more smoothly`, | |||
Flags: []cli.Flag{ | |||
cli.StringFlag{ | |||
Name: "name", | |||
Value: "", | |||
Usage: "Username", | |||
}, | |||
cli.StringFlag{ | |||
Name: "password", | |||
Value: "", | |||
Usage: "User password", | |||
}, | |||
cli.StringFlag{ | |||
Name: "email", | |||
Value: "", | |||
Usage: "User email address", | |||
}, | |||
cli.BoolFlag{ | |||
@@ -88,56 +83,42 @@ to make automatic initialization process more smoothly`, | |||
) | |||
func runChangePassword(c *cli.Context) error { | |||
if !c.IsSet("password") { | |||
return fmt.Errorf("Password is not specified") | |||
} else if !c.IsSet("username") { | |||
return fmt.Errorf("Username is not specified") | |||
if err := argsSet(c, "username", "password"); err != nil { | |||
return err | |||
} | |||
setting.NewContext() | |||
models.LoadConfigs() | |||
setting.NewXORMLogService(false) | |||
if err := models.SetEngine(); err != nil { | |||
return fmt.Errorf("models.SetEngine: %v", err) | |||
if err := initDB(); err != nil { | |||
return err | |||
} | |||
uname := c.String("username") | |||
user, err := models.GetUserByName(uname) | |||
if err != nil { | |||
return fmt.Errorf("%v", err) | |||
return err | |||
} | |||
if user.Salt, err = models.GetUserSalt(); err != nil { | |||
return fmt.Errorf("%v", err) | |||
return err | |||
} | |||
user.HashPassword(c.String("password")) | |||
if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil { | |||
return fmt.Errorf("%v", err) | |||
return err | |||
} | |||
fmt.Printf("User '%s' password has been successfully updated!\n", uname) | |||
fmt.Printf("%s's password has been successfully updated!\n", user.Name) | |||
return nil | |||
} | |||
func runCreateUser(c *cli.Context) error { | |||
if !c.IsSet("name") { | |||
return fmt.Errorf("Username is not specified") | |||
} else if !c.IsSet("password") { | |||
return fmt.Errorf("Password is not specified") | |||
} else if !c.IsSet("email") { | |||
return fmt.Errorf("Email is not specified") | |||
if err := argsSet(c, "name", "password", "email"); err != nil { | |||
return err | |||
} | |||
if c.IsSet("config") { | |||
setting.CustomConf = c.String("config") | |||
} | |||
setting.NewContext() | |||
models.LoadConfigs() | |||
setting.NewXORMLogService(false) | |||
if err := models.SetEngine(); err != nil { | |||
return fmt.Errorf("models.SetEngine: %v", err) | |||
if err := initDB(); err != nil { | |||
return err | |||
} | |||
if err := models.CreateUser(&models.User{ | |||
@@ -155,13 +136,8 @@ func runCreateUser(c *cli.Context) error { | |||
} | |||
func runRepoSyncReleases(c *cli.Context) error { | |||
setting.NewContext() | |||
models.LoadConfigs() | |||
setting.NewXORMLogService(false) | |||
if err := models.SetEngine(); err != nil { | |||
return fmt.Errorf("models.SetEngine: %v", err) | |||
if err := initDB(); err != nil { | |||
return err | |||
} | |||
log.Trace("Synchronizing repository releases (this may take a while)") | |||
@@ -172,8 +148,7 @@ func runRepoSyncReleases(c *cli.Context) error { | |||
Private: true, | |||
}) | |||
if err != nil { | |||
log.Fatal(4, "SearchRepositoryByName: %v", err) | |||
return err | |||
return fmt.Errorf("SearchRepositoryByName: %v", err) | |||
} | |||
if len(repos) == 0 { | |||
break | |||
@@ -187,11 +162,7 @@ func runRepoSyncReleases(c *cli.Context) error { | |||
continue | |||
} | |||
oldnum, err := models.GetReleaseCountByRepoID(repo.ID, | |||
models.FindReleasesOptions{ | |||
IncludeDrafts: false, | |||
IncludeTags: true, | |||
}) | |||
oldnum, err := getReleaseCount(repo.ID) | |||
if err != nil { | |||
log.Warn(" GetReleaseCountByRepoID: %v", err) | |||
} | |||
@@ -202,11 +173,7 @@ func runRepoSyncReleases(c *cli.Context) error { | |||
continue | |||
} | |||
count, err = models.GetReleaseCountByRepoID(repo.ID, | |||
models.FindReleasesOptions{ | |||
IncludeDrafts: false, | |||
IncludeTags: true, | |||
}) | |||
count, err = getReleaseCount(repo.ID) | |||
if err != nil { | |||
log.Warn(" GetReleaseCountByRepoID: %v", err) | |||
continue | |||
@@ -219,3 +186,12 @@ func runRepoSyncReleases(c *cli.Context) error { | |||
return nil | |||
} | |||
func getReleaseCount(id int64) (int64, error) { | |||
return models.GetReleaseCountByRepoID( | |||
id, | |||
models.FindReleasesOptions{ | |||
IncludeTags: true, | |||
}, | |||
) | |||
} |
@@ -90,16 +90,16 @@ func pemBlockForKey(priv interface{}) *pem.Block { | |||
} | |||
} | |||
func runCert(ctx *cli.Context) error { | |||
if len(ctx.String("host")) == 0 { | |||
log.Fatal("Missing required --host parameter") | |||
func runCert(c *cli.Context) error { | |||
if err := argsSet(c, "host"); err != nil { | |||
return err | |||
} | |||
var priv interface{} | |||
var err error | |||
switch ctx.String("ecdsa-curve") { | |||
switch c.String("ecdsa-curve") { | |||
case "": | |||
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits")) | |||
priv, err = rsa.GenerateKey(rand.Reader, c.Int("rsa-bits")) | |||
case "P224": | |||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) | |||
case "P256": | |||
@@ -109,23 +109,23 @@ func runCert(ctx *cli.Context) error { | |||
case "P521": | |||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) | |||
default: | |||
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve")) | |||
log.Fatalf("Unrecognized elliptic curve: %q", c.String("ecdsa-curve")) | |||
} | |||
if err != nil { | |||
log.Fatalf("Failed to generate private key: %v", err) | |||
} | |||
var notBefore time.Time | |||
if len(ctx.String("start-date")) == 0 { | |||
notBefore = time.Now() | |||
} else { | |||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date")) | |||
if startDate := c.String("start-date"); startDate != "" { | |||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", startDate) | |||
if err != nil { | |||
log.Fatalf("Failed to parse creation date: %v", err) | |||
} | |||
} else { | |||
notBefore = time.Now() | |||
} | |||
notAfter := notBefore.Add(ctx.Duration("duration")) | |||
notAfter := notBefore.Add(c.Duration("duration")) | |||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) | |||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) | |||
@@ -147,7 +147,7 @@ func runCert(ctx *cli.Context) error { | |||
BasicConstraintsValid: true, | |||
} | |||
hosts := strings.Split(ctx.String("host"), ",") | |||
hosts := strings.Split(c.String("host"), ",") | |||
for _, h := range hosts { | |||
if ip := net.ParseIP(h); ip != nil { | |||
template.IPAddresses = append(template.IPAddresses, ip) | |||
@@ -156,7 +156,7 @@ func runCert(ctx *cli.Context) error { | |||
} | |||
} | |||
if ctx.Bool("ca") { | |||
if c.Bool("ca") { | |||
template.IsCA = true | |||
template.KeyUsage |= x509.KeyUsageCertSign | |||
} |
@@ -0,0 +1,38 @@ | |||
// Copyright 2018 The Gitea Authors. All rights reserved. | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
// Package cmd provides subcommands to the gitea binary - such as "web" or | |||
// "admin". | |||
package cmd | |||
import ( | |||
"errors" | |||
"fmt" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/setting" | |||
"github.com/urfave/cli" | |||
) | |||
// argsSet checks that all the required arguments are set. args is a list of | |||
// arguments that must be set in the passed Context. | |||
func argsSet(c *cli.Context, args ...string) error { | |||
for _, a := range args { | |||
if !c.IsSet(a) { | |||
return errors.New(a + " is not set") | |||
} | |||
} | |||
return nil | |||
} | |||
func initDB() error { | |||
setting.NewContext() | |||
models.LoadConfigs() | |||
setting.NewXORMLogService(false) | |||
if err := models.SetEngine(); err != nil { | |||
return fmt.Errorf("models.SetEngine: %v", err) | |||
} | |||
return nil | |||
} |
@@ -68,19 +68,19 @@ func runDump(ctx *cli.Context) error { | |||
if _, err := os.Stat(tmpDir); os.IsNotExist(err) { | |||
log.Fatalf("Path does not exist: %s", tmpDir) | |||
} | |||
TmpWorkDir, err := ioutil.TempDir(tmpDir, "gitea-dump-") | |||
tmpWorkDir, err := ioutil.TempDir(tmpDir, "gitea-dump-") | |||
if err != nil { | |||
log.Fatalf("Failed to create tmp work directory: %v", err) | |||
} | |||
log.Printf("Creating tmp work dir: %s", TmpWorkDir) | |||
log.Printf("Creating tmp work dir: %s", tmpWorkDir) | |||
// work-around #1103 | |||
if os.Getenv("TMPDIR") == "" { | |||
os.Setenv("TMPDIR", TmpWorkDir) | |||
os.Setenv("TMPDIR", tmpWorkDir) | |||
} | |||
reposDump := path.Join(TmpWorkDir, "gitea-repo.zip") | |||
dbDump := path.Join(TmpWorkDir, "gitea-db.sql") | |||
reposDump := path.Join(tmpWorkDir, "gitea-repo.zip") | |||
dbDump := path.Join(tmpWorkDir, "gitea-db.sql") | |||
log.Printf("Dumping local repositories...%s", setting.RepoRootPath) | |||
zip.Verbose = ctx.Bool("verbose") | |||
@@ -146,10 +146,10 @@ func runDump(ctx *cli.Context) error { | |||
log.Printf("Can't change file access permissions mask to 0600: %v", err) | |||
} | |||
log.Printf("Removing tmp work dir: %s", TmpWorkDir) | |||
log.Printf("Removing tmp work dir: %s", tmpWorkDir) | |||
if err := os.RemoveAll(TmpWorkDir); err != nil { | |||
log.Fatalf("Failed to remove %s: %v", TmpWorkDir, err) | |||
if err := os.RemoveAll(tmpWorkDir); err != nil { | |||
log.Fatalf("Failed to remove %s: %v", tmpWorkDir, err) | |||
} | |||
log.Printf("Finish dumping in file %s", fileName) | |||
@@ -37,7 +37,7 @@ var ( | |||
}, | |||
Subcommands: []cli.Command{ | |||
subcmdHookPreReceive, | |||
subcmdHookUpadte, | |||
subcmdHookUpdate, | |||
subcmdHookPostReceive, | |||
}, | |||
} | |||
@@ -48,7 +48,7 @@ var ( | |||
Description: "This command should only be called by Git", | |||
Action: runHookPreReceive, | |||
} | |||
subcmdHookUpadte = cli.Command{ | |||
subcmdHookUpdate = cli.Command{ | |||
Name: "update", | |||
Usage: "Delegate update Git hook", | |||
Description: "This command should only be called by Git", |
@@ -121,11 +121,9 @@ func runWeb(ctx *cli.Context) error { | |||
} | |||
} | |||
var listenAddr string | |||
if setting.Protocol == setting.UnixSocket { | |||
listenAddr = fmt.Sprintf("%s", setting.HTTPAddr) | |||
} else { | |||
listenAddr = fmt.Sprintf("%s:%s", setting.HTTPAddr, setting.HTTPPort) | |||
listenAddr := setting.HTTPAddr | |||
if setting.Protocol != setting.UnixSocket { | |||
listenAddr += ":" + setting.HTTPPort | |||
} | |||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL) | |||
@@ -135,6 +133,7 @@ func runWeb(ctx *cli.Context) error { | |||
if setting.EnablePprof { | |||
go func() { | |||
log.Info("Starting pprof server on localhost:6060") | |||
log.Info("%v", http.ListenAndServe("localhost:6060", nil)) | |||
}() | |||
} |