diff --git a/.YetAnotherToDoList.yaml b/.YetAnotherToDoList.yaml
new file mode 100644
index 0000000..932fd84
--- /dev/null
+++ b/.YetAnotherToDoList.yaml
@@ -0,0 +1,3 @@
+log_file: "YetAnotherToDoList.log"
+log_UTC: false
+port: 4242
diff --git a/cmd/root.go b/cmd/root.go
index a908ccd..7971cce 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -18,24 +18,26 @@ package cmd
import (
"fmt"
+ "log"
"os"
+ "path/filepath"
+ "strings"
+ "time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
+var logger *log.Logger
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "YetAnotherToDoList",
- Short: "A brief description of your application",
- Long: `A longer description that spans multiple lines and likely contains
-examples and usage of using your application. For example:
-
-Cobra is a CLI library for Go that empowers applications.
-This application is a tool to generate the needed files
-to quickly create a Cobra application.`,
+ Short: "A simple To Do List Web Application with Go backend, Vue.js frontend and a GraphQL API",
+ Long: `YetAnotherToDoList 2023 by gilex-dev
+A simple To Do List Web Application with Go backend, Vue.js frontend and a GraphQL API
+`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
@@ -51,17 +53,18 @@ func Execute() {
}
func init() {
- cobra.OnInitialize(initConfig)
+ cobra.OnInitialize(initConfig, initLog)
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.YetAnotherToDoList.yaml)")
+ rootCmd.PersistentFlags().String("log_file", "", "Path to log file")
// Cobra also supports local flags, which will only run
// when this action is called directly.
- rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
+ // rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
// initConfig reads in config file and ENV variables if set.
@@ -74,8 +77,13 @@ func initConfig() {
home, err := os.UserHomeDir()
cobra.CheckErr(err)
+ wd, err := os.Getwd()
+ cobra.CheckErr(err)
+
// Search config in home directory with name ".YetAnotherToDoList" (without extension).
viper.AddConfigPath(home)
+ // Search config in working directory with name ".YetAnotherToDoList" (without extension).
+ viper.AddConfigPath(wd)
viper.SetConfigType("yaml")
viper.SetConfigName(".YetAnotherToDoList")
}
@@ -85,5 +93,64 @@ func initConfig() {
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
+ } else {
+ fmt.Fprintln(os.Stderr, "Unable to read in", viper.ConfigFileUsed(), err)
}
}
+
+func initLog() {
+ var utc = 0
+ var time_zone_use, time_zone_alt string
+
+ time_zone_local, _ := time.Now().Zone()
+ time_zone_offset := strings.Split(time.Now().In(time.Local).String(), " ")[2]
+
+ if viper.GetBool("log_UTC") {
+ utc = log.LUTC
+ time_zone_use = "UTC"
+ time_zone_alt = time_zone_local
+ time_zone_offset_rune := []rune(time_zone_offset)
+
+ if time_zone_offset_rune[0] == '+' {
+ time_zone_offset_rune[0] = '-'
+ }
+
+ time_zone_offset = string(time_zone_offset_rune)
+
+ } else {
+ time_zone_use = time_zone_local
+ time_zone_alt = "UTC"
+ }
+
+ logger_flags := log.Ldate | log.Ltime | utc
+ logger = log.New(os.Stdout, "", logger_flags)
+
+ if err := viper.BindPFlag("log_file", rootCmd.Flags().Lookup("log_file")); err != nil {
+ fmt.Println("Unable to bind flag:", err)
+ }
+
+ if viper.GetString("log_file") != "" {
+
+ log_path, err := filepath.Abs(viper.GetString("log_file"))
+
+ logger.SetOutput(os.Stdout)
+ if err != nil {
+ logger.Println("Invalid path for log file", log_path)
+ }
+
+ log_file, err := os.OpenFile(log_path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
+
+ if err != nil {
+ fmt.Println("Failed to write to log file:", err)
+ } else {
+ logger.Println("Switching to log file", log_path)
+ logger.SetOutput(log_file)
+ }
+ }
+
+ logger.SetFlags(0)
+ logger.Println()
+ logger.SetFlags(logger_flags)
+ logger.Printf("Started YetAnotherToDoList with pid: %v\n", os.Getpid())
+ logger.Printf("Using %v (%v %v) in logs", time_zone_use, time_zone_alt, time_zone_offset)
+}
diff --git a/cmd/server.go b/cmd/server.go
index 68e36a4..b5127d7 100644
--- a/cmd/server.go
+++ b/cmd/server.go
@@ -1,36 +1,33 @@
/*
-YetAnotherToDoList
-Copyright © 2023 gilex-dev gilex-dev@proton.me
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, version 3.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
+Copyright © 2023 NAME HERE
*/
package cmd
import (
"fmt"
- "github.com/spf13/cobra"
"somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/server"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
)
// serverCmd represents the server command
var serverCmd = &cobra.Command{
Use: "server",
- Short: "Start web server",
- Long: `Start the web server with a GraphQL playground`,
+ Short: "Start the http server",
+ Long: ``,
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println("server called")
- server.StartServer()
+
+ if err := viper.BindPFlag("debug", cmd.Flags().Lookup("debug")); err != nil {
+ fmt.Println("Unable to bind flag:", err)
+ }
+ if err := viper.BindPFlag("port", cmd.Flags().Lookup("port")); err != nil {
+ fmt.Println("Unable to bind flag:", err)
+ }
+
+ logger.Println("starting http server...")
+ server.StartServer(logger, viper.GetInt("port"))
},
}
@@ -46,4 +43,6 @@ func init() {
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// serverCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
+ serverCmd.Flags().BoolP("debug", "d", false, "Enable debugging")
+ serverCmd.Flags().IntP("port", "p", 4242, "The port to listen on")
}
diff --git a/server/main.go b/server/main.go
index 3c58dd2..5099640 100644
--- a/server/main.go
+++ b/server/main.go
@@ -19,26 +19,19 @@ package server
import (
"log"
"net/http"
- "os"
+ "strconv"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
"somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/graph"
)
-const defaultPort = "8080"
-
-func StartServer() {
- port := os.Getenv("PORT")
- if port == "" {
- port = defaultPort
- }
-
+func StartServer(logger *log.Logger, port int) {
srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}}))
- http.Handle("/", playground.Handler("GraphQL playground", "/query"))
- http.Handle("/query", srv)
+ http.Handle("/", playground.Handler("GraphQL playground", "/api"))
- log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
- log.Fatal(http.ListenAndServe(":"+port, nil))
+ http.Handle("/api", srv)
+ logger.Printf("connect to http://localhost:%v/ for GraphQL playground", port)
+ logger.Fatal(http.ListenAndServe(":"+strconv.FormatInt(int64(port), 10), nil))
}