General refactor of the cmd package (#3328)

* General refactor of the cmd package

* Address breakage in runCreateUser

* Place "common" functions into cmd.go
This commit is contained in:
Morgan Bazalgette 2018-01-12 23:16:49 +01:00 committed by Kim "BKC" Carlbäcker
parent 079273e2ff
commit 2b52f77e1b
6 changed files with 92 additions and 79 deletions

View File

@ -20,9 +20,7 @@ var (
// CmdAdmin represents the available admin sub-command. // CmdAdmin represents the available admin sub-command.
CmdAdmin = cli.Command{ CmdAdmin = cli.Command{
Name: "admin", Name: "admin",
Usage: "Perform admin operations on command line", Usage: "Command line interface to perform common administrative operations",
Description: `Allow using internal logic of Gitea without hacking into the source code
to make automatic initialization process more smoothly`,
Subcommands: []cli.Command{ Subcommands: []cli.Command{
subcmdCreateUser, subcmdCreateUser,
subcmdChangePassword, subcmdChangePassword,
@ -37,17 +35,14 @@ to make automatic initialization process more smoothly`,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "name", Name: "name",
Value: "",
Usage: "Username", Usage: "Username",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "password", Name: "password",
Value: "",
Usage: "User password", Usage: "User password",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "email", Name: "email",
Value: "",
Usage: "User email address", Usage: "User email address",
}, },
cli.BoolFlag{ cli.BoolFlag{
@ -88,56 +83,42 @@ to make automatic initialization process more smoothly`,
) )
func runChangePassword(c *cli.Context) error { func runChangePassword(c *cli.Context) error {
if !c.IsSet("password") { if err := argsSet(c, "username", "password"); err != nil {
return fmt.Errorf("Password is not specified") return err
} else if !c.IsSet("username") {
return fmt.Errorf("Username is not specified")
} }
setting.NewContext() if err := initDB(); err != nil {
models.LoadConfigs() return err
setting.NewXORMLogService(false)
if err := models.SetEngine(); err != nil {
return fmt.Errorf("models.SetEngine: %v", err)
} }
uname := c.String("username") uname := c.String("username")
user, err := models.GetUserByName(uname) user, err := models.GetUserByName(uname)
if err != nil { if err != nil {
return fmt.Errorf("%v", err) return err
} }
if user.Salt, err = models.GetUserSalt(); err != nil { if user.Salt, err = models.GetUserSalt(); err != nil {
return fmt.Errorf("%v", err) return err
} }
user.HashPassword(c.String("password")) user.HashPassword(c.String("password"))
if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil { 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 return nil
} }
func runCreateUser(c *cli.Context) error { func runCreateUser(c *cli.Context) error {
if !c.IsSet("name") { if err := argsSet(c, "name", "password", "email"); err != nil {
return fmt.Errorf("Username is not specified") return err
} 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 c.IsSet("config") { if c.IsSet("config") {
setting.CustomConf = c.String("config") setting.CustomConf = c.String("config")
} }
setting.NewContext() if err := initDB(); err != nil {
models.LoadConfigs() return err
setting.NewXORMLogService(false)
if err := models.SetEngine(); err != nil {
return fmt.Errorf("models.SetEngine: %v", err)
} }
if err := models.CreateUser(&models.User{ if err := models.CreateUser(&models.User{
@ -155,13 +136,8 @@ func runCreateUser(c *cli.Context) error {
} }
func runRepoSyncReleases(c *cli.Context) error { func runRepoSyncReleases(c *cli.Context) error {
if err := initDB(); err != nil {
setting.NewContext() return err
models.LoadConfigs()
setting.NewXORMLogService(false)
if err := models.SetEngine(); err != nil {
return fmt.Errorf("models.SetEngine: %v", err)
} }
log.Trace("Synchronizing repository releases (this may take a while)") log.Trace("Synchronizing repository releases (this may take a while)")
@ -172,8 +148,7 @@ func runRepoSyncReleases(c *cli.Context) error {
Private: true, Private: true,
}) })
if err != nil { if err != nil {
log.Fatal(4, "SearchRepositoryByName: %v", err) return fmt.Errorf("SearchRepositoryByName: %v", err)
return err
} }
if len(repos) == 0 { if len(repos) == 0 {
break break
@ -187,11 +162,7 @@ func runRepoSyncReleases(c *cli.Context) error {
continue continue
} }
oldnum, err := models.GetReleaseCountByRepoID(repo.ID, oldnum, err := getReleaseCount(repo.ID)
models.FindReleasesOptions{
IncludeDrafts: false,
IncludeTags: true,
})
if err != nil { if err != nil {
log.Warn(" GetReleaseCountByRepoID: %v", err) log.Warn(" GetReleaseCountByRepoID: %v", err)
} }
@ -202,11 +173,7 @@ func runRepoSyncReleases(c *cli.Context) error {
continue continue
} }
count, err = models.GetReleaseCountByRepoID(repo.ID, count, err = getReleaseCount(repo.ID)
models.FindReleasesOptions{
IncludeDrafts: false,
IncludeTags: true,
})
if err != nil { if err != nil {
log.Warn(" GetReleaseCountByRepoID: %v", err) log.Warn(" GetReleaseCountByRepoID: %v", err)
continue continue
@ -219,3 +186,12 @@ func runRepoSyncReleases(c *cli.Context) error {
return nil return nil
} }
func getReleaseCount(id int64) (int64, error) {
return models.GetReleaseCountByRepoID(
id,
models.FindReleasesOptions{
IncludeTags: true,
},
)
}

View File

@ -90,16 +90,16 @@ func pemBlockForKey(priv interface{}) *pem.Block {
} }
} }
func runCert(ctx *cli.Context) error { func runCert(c *cli.Context) error {
if len(ctx.String("host")) == 0 { if err := argsSet(c, "host"); err != nil {
log.Fatal("Missing required --host parameter") return err
} }
var priv interface{} var priv interface{}
var err error var err error
switch ctx.String("ecdsa-curve") { switch c.String("ecdsa-curve") {
case "": case "":
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits")) priv, err = rsa.GenerateKey(rand.Reader, c.Int("rsa-bits"))
case "P224": case "P224":
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
case "P256": case "P256":
@ -109,23 +109,23 @@ func runCert(ctx *cli.Context) error {
case "P521": case "P521":
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
default: default:
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve")) log.Fatalf("Unrecognized elliptic curve: %q", c.String("ecdsa-curve"))
} }
if err != nil { if err != nil {
log.Fatalf("Failed to generate private key: %v", err) log.Fatalf("Failed to generate private key: %v", err)
} }
var notBefore time.Time var notBefore time.Time
if len(ctx.String("start-date")) == 0 { if startDate := c.String("start-date"); startDate != "" {
notBefore = time.Now() notBefore, err = time.Parse("Jan 2 15:04:05 2006", startDate)
} else {
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date"))
if err != nil { if err != nil {
log.Fatalf("Failed to parse creation date: %v", err) 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) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
@ -147,7 +147,7 @@ func runCert(ctx *cli.Context) error {
BasicConstraintsValid: true, BasicConstraintsValid: true,
} }
hosts := strings.Split(ctx.String("host"), ",") hosts := strings.Split(c.String("host"), ",")
for _, h := range hosts { for _, h := range hosts {
if ip := net.ParseIP(h); ip != nil { if ip := net.ParseIP(h); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip) 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.IsCA = true
template.KeyUsage |= x509.KeyUsageCertSign template.KeyUsage |= x509.KeyUsageCertSign
} }

38
cmd/cmd.go Normal file
View File

@ -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
}

View File

@ -68,19 +68,19 @@ func runDump(ctx *cli.Context) error {
if _, err := os.Stat(tmpDir); os.IsNotExist(err) { if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
log.Fatalf("Path does not exist: %s", tmpDir) 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 { if err != nil {
log.Fatalf("Failed to create tmp work directory: %v", err) 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 // work-around #1103
if os.Getenv("TMPDIR") == "" { if os.Getenv("TMPDIR") == "" {
os.Setenv("TMPDIR", TmpWorkDir) os.Setenv("TMPDIR", tmpWorkDir)
} }
reposDump := path.Join(TmpWorkDir, "gitea-repo.zip") reposDump := path.Join(tmpWorkDir, "gitea-repo.zip")
dbDump := path.Join(TmpWorkDir, "gitea-db.sql") dbDump := path.Join(tmpWorkDir, "gitea-db.sql")
log.Printf("Dumping local repositories...%s", setting.RepoRootPath) log.Printf("Dumping local repositories...%s", setting.RepoRootPath)
zip.Verbose = ctx.Bool("verbose") 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("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 { if err := os.RemoveAll(tmpWorkDir); err != nil {
log.Fatalf("Failed to remove %s: %v", TmpWorkDir, err) log.Fatalf("Failed to remove %s: %v", tmpWorkDir, err)
} }
log.Printf("Finish dumping in file %s", fileName) log.Printf("Finish dumping in file %s", fileName)

View File

@ -37,7 +37,7 @@ var (
}, },
Subcommands: []cli.Command{ Subcommands: []cli.Command{
subcmdHookPreReceive, subcmdHookPreReceive,
subcmdHookUpadte, subcmdHookUpdate,
subcmdHookPostReceive, subcmdHookPostReceive,
}, },
} }
@ -48,7 +48,7 @@ var (
Description: "This command should only be called by Git", Description: "This command should only be called by Git",
Action: runHookPreReceive, Action: runHookPreReceive,
} }
subcmdHookUpadte = cli.Command{ subcmdHookUpdate = cli.Command{
Name: "update", Name: "update",
Usage: "Delegate update Git hook", Usage: "Delegate update Git hook",
Description: "This command should only be called by Git", Description: "This command should only be called by Git",

View File

@ -121,11 +121,9 @@ func runWeb(ctx *cli.Context) error {
} }
} }
var listenAddr string listenAddr := setting.HTTPAddr
if setting.Protocol == setting.UnixSocket { if setting.Protocol != setting.UnixSocket {
listenAddr = fmt.Sprintf("%s", setting.HTTPAddr) listenAddr += ":" + setting.HTTPPort
} else {
listenAddr = fmt.Sprintf("%s:%s", setting.HTTPAddr, setting.HTTPPort)
} }
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL) log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
@ -135,6 +133,7 @@ func runWeb(ctx *cli.Context) error {
if setting.EnablePprof { if setting.EnablePprof {
go func() { go func() {
log.Info("Starting pprof server on localhost:6060")
log.Info("%v", http.ListenAndServe("localhost:6060", nil)) log.Info("%v", http.ListenAndServe("localhost:6060", nil))
}() }()
} }