use alecthomas/kingpin for parsing CLI arguments. Closes #7

This commit is contained in:
Danny van Kooten 2017-01-24 20:28:22 +01:00
parent 6161442487
commit 8a0657b977
5 changed files with 62 additions and 84 deletions

36
ana.go
View File

@ -1,16 +1,30 @@
package main
import (
"log"
"github.com/dannyvankooten/ana/commands"
"github.com/dannyvankooten/ana/count"
"github.com/dannyvankooten/ana/db"
"github.com/joho/godotenv"
"github.com/robfig/cron"
"gopkg.in/alecthomas/kingpin.v2"
"log"
"os"
)
var (
app = kingpin.New("ana", "Open-source web analytics.")
register = app.Command("register", "Register a new user.")
registerEmail = register.Arg("email", "Email for user.").Required().String()
registerPassword = register.Arg("password", "Password for user.").Required().String()
server = app.Command("server", "Start webserver.").Default()
serverPort = server.Flag("port", "Port to listen on.").Default("8080").Int()
archive = app.Command("archive", "Process unarchived data.")
seed = app.Command("seed", "Seed the database.")
seedN = seed.Flag("n", "Number of records to seed.").Int()
)
func main() {
// load .env file
err := godotenv.Load()
if err != nil {
@ -30,6 +44,20 @@ func main() {
c.Start()
// parse & run cli commands
commands.Parse()
commands.Run()
app.Version("1.0")
app.UsageTemplate(kingpin.CompactUsageTemplate)
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
case "register":
commands.Register(*registerEmail, *registerPassword)
case "server":
commands.Server(*serverPort)
case "archive":
commands.Archive()
case "seed":
commands.Seed(*seedN)
}
}

View File

@ -1,52 +0,0 @@
package commands
import (
"flag"
"github.com/dannyvankooten/ana/count"
"github.com/dannyvankooten/ana/db"
)
var (
runCreateUserCommand bool
runDeleteUserCommand bool
runStartServerCommand bool
runSeedDataCommand bool
runArchiveDataCommand bool
idArg int
emailArg string
passwordArg string
nArg int
portArg int
)
// Parse CLI arguments
func Parse() {
// parse commands
flag.BoolVar(&runCreateUserCommand, "create_user", false, "Create a new user")
flag.BoolVar(&runDeleteUserCommand, "delete_user", false, "Deletes a user")
flag.BoolVar(&runStartServerCommand, "start_server", true, "Start the API web server, listen on -port")
flag.BoolVar(&runSeedDataCommand, "db_seed", false, "Seed the database -n times")
flag.BoolVar(&runArchiveDataCommand, "archive_data", false, "Aggregates data into daily totals")
flag.StringVar(&emailArg, "email", "", "Email address")
flag.StringVar(&passwordArg, "password", "", "Password")
flag.IntVar(&idArg, "id", 0, "Object ID")
flag.IntVar(&nArg, "n", 0, "Number")
flag.IntVar(&portArg, "port", 8080, "Port")
flag.Parse()
}
// Run parsed CLI command. Defaults to starting the HTTP server.
func Run() {
if runCreateUserCommand {
createUser()
} else if runDeleteUserCommand {
deleteUser()
} else if runSeedDataCommand {
db.Seed(nArg)
} else if runArchiveDataCommand {
count.Archive()
} else if runStartServerCommand {
startServer(portArg)
}
}

16
commands/data.go Normal file
View File

@ -0,0 +1,16 @@
package commands
import (
"github.com/dannyvankooten/ana/count"
"github.com/dannyvankooten/ana/db"
)
// Seed creates n database records with dummy data
func Seed(n int) {
db.Seed(n)
}
// Archive processes unarchived data (pageviews to aggeegated count tables)
func Archive() {
count.Archive()
}

View File

@ -2,16 +2,16 @@ package commands
import (
"fmt"
"log"
"net/http"
"os"
"github.com/dannyvankooten/ana/api"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"net/http"
"os"
)
func startServer(port int) {
// Server starts the HTTP server, listening on the given port
func Server(port int) {
// register routes
r := mux.NewRouter()
r.HandleFunc("/collect", api.CollectHandler).Methods("GET")
@ -33,6 +33,7 @@ func startServer(port int) {
r.Path("/tracker.js").Handler(http.FileServer(http.Dir("./static/js/")))
r.Handle("/", http.FileServer(http.Dir("./views/")))
log.Printf("API server is now listening on :%d", port)
http.ListenAndServe(fmt.Sprintf(":%d", port), handlers.LoggingHandler(os.Stdout, r))
fmt.Printf("HTTP server will now start listening on :%d\n", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), handlers.LoggingHandler(os.Stdout, r))
fmt.Println(err)
}

View File

@ -1,35 +1,20 @@
package commands
import (
"log"
"fmt"
"github.com/dannyvankooten/ana/db"
"github.com/dannyvankooten/ana/models"
"golang.org/x/crypto/bcrypt"
)
func createUser() {
if emailArg == "" || passwordArg == "" {
log.Fatal("Please supply -email and -password values")
}
hash, _ := bcrypt.GenerateFromPassword([]byte(passwordArg), 10)
// Register creates a new user with the given email & password
func Register(email string, password string) {
hash, _ := bcrypt.GenerateFromPassword([]byte(password), 10)
user := models.User{
Email: emailArg,
Email: email,
Password: string(hash),
}
user.Save(db.Conn)
log.Printf("User %s #%d created", emailArg, user.ID)
}
func deleteUser() {
if emailArg == "" && idArg == 0 {
log.Fatal("Please supply an -email or -id value")
}
stmt2, _ := db.Conn.Prepare("DELETE FROM users WHERE email = ? OR id = ?")
stmt2.Exec(emailArg, idArg)
log.Printf("User with email %s or ID %d deleted", emailArg, idArg)
fmt.Printf("User %s #%d created.\n", email, user.ID)
}