Merge pull request #842 from 0xJacky/feat/cli

feat: new command system
This commit is contained in:
Jacky 2025-02-04 22:23:46 +08:00 committed by GitHub
commit d2e7dd500d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 192 additions and 53 deletions

View file

@ -142,6 +142,18 @@ jobs:
with:
go-version: ^1.23.0
- name: Download app artifacts
uses: actions/download-artifact@v4
with:
name: app-dist
path: app/dist
- name: Generate files
env:
GOOS: linux
GOARCH: amd64
run: go generate
- name: Setup compiler environment
id: info
run: |
@ -182,12 +194,6 @@ jobs:
echo "CXX=${{ env.ARCH_NAME }}-clang++" >> $GITHUB_ENV
echo "LD_FLAGS=-w" >> $GITHUB_ENV
- name: Download app artifacts
uses: actions/download-artifact@v4
with:
name: app-dist
path: app/dist
- name: Build
run: |
mkdir -p dist

1
.gitignore vendored
View file

@ -14,6 +14,7 @@ app/.env
app/.status_hash
.idea/deployment.xml
.idea/webServers.xml
*.gen.go
.devcontainer/go-path
.devcontainer/data
.devcontainer/casdoor.pem

View file

@ -1,14 +1,16 @@
package cluster
import (
"net/http"
"github.com/0xJacky/Nginx-UI/api"
analytic2 "github.com/0xJacky/Nginx-UI/internal/analytic"
"github.com/0xJacky/Nginx-UI/internal/upgrader"
"github.com/0xJacky/Nginx-UI/internal/version"
"github.com/dustin/go-humanize"
"github.com/gin-gonic/gin"
"github.com/shirou/gopsutil/v4/cpu"
"github.com/shirou/gopsutil/v4/disk"
"net/http"
)
func GetCurrentNode(c *gin.Context) {
@ -26,7 +28,7 @@ func GetCurrentNode(c *gin.Context) {
}
cpuInfo, _ := cpu.Info()
memory, _ := analytic2.GetMemoryStat()
ver, _ := upgrader.GetCurrentVersion()
ver := version.GetVersionInfo()
diskUsage, _ := disk.Usage(".")
nodeInfo := analytic2.NodeInfo{

View file

@ -1,14 +1,16 @@
package system
import (
"net/http"
"os"
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/upgrader"
"github.com/0xJacky/Nginx-UI/internal/version"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/uozi-tech/cosy/logger"
"net/http"
"os"
)
func GetRelease(c *gin.Context) {
@ -32,13 +34,7 @@ func GetRelease(c *gin.Context) {
}
func GetCurrentVersion(c *gin.Context) {
curVer, err := upgrader.GetCurrentVersion()
if err != nil {
api.ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, curVer)
c.JSON(http.StatusOK, version.GetVersionInfo())
}
const (

View file

@ -8,5 +8,3 @@ import (
//go:embed i18n.json dist/* dist/*/* src/language/* src/language/*/*
var DistFS embed.FS
var VersionPath = "dist/version.json"

View file

@ -4,7 +4,5 @@ package app
import "embed"
//go:embed i18n.json src/language/* src/language/*/* src/version.json
//go:embed i18n.json src/language/* src/language/*/*
var DistFS embed.FS
var VersionPath = "src/version.json"

81
cmd/version/generate.go Normal file
View file

@ -0,0 +1,81 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"log"
"os"
"path"
"runtime"
)
type VersionInfo struct {
Version string `json:"version"`
BuildId int `json:"build_id"`
TotalBuild int `json:"total_build"`
}
func main() {
_, file, _, ok := runtime.Caller(0)
if !ok {
log.Print("Unable to get the current file")
return
}
basePath := path.Join(path.Dir(file), "../../")
versionFile, err := os.Open(path.Join(basePath, "app/dist/version.json"))
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
log.Print("\"dist/version.json\" not found, load from src instead")
versionFile, err = os.Open(path.Join(basePath, "app/src/version.json"))
}
if err != nil {
log.Fatal(err)
return
}
}
defer func(versionFile fs.File) {
err := versionFile.Close()
if err != nil {
log.Fatal(err)
}
}(versionFile)
// Read the version.json file
data, err := io.ReadAll(versionFile)
if err != nil {
log.Fatalf("Failed to read version.json: %v", err)
}
// Parse the JSON data
var versionInfo VersionInfo
err = json.Unmarshal(data, &versionInfo)
if err != nil {
log.Fatalf("Failed to parse JSON: %v", err)
}
// Generate the version.gen.go file content
genContent := fmt.Sprintf(`// Code generated by cmd/version/generate.go; DO NOT EDIT.
package version
func init() {
Version = "%s"
BuildId = %d
TotalBuild = %d
}
`, versionInfo.Version, versionInfo.BuildId, versionInfo.TotalBuild)
genPath := path.Join(basePath, "internal/version/version.gen.go")
err = os.WriteFile(genPath, []byte(genContent), 0644)
if err != nil {
log.Fatalf("Failed to write version.gen.go: %v", err)
}
fmt.Println("version.gen.go has been generated successfully.")
}

9
go.mod
View file

@ -11,7 +11,6 @@ require (
github.com/dgraph-io/ristretto/v2 v2.1.0
github.com/dustin/go-humanize v1.0.1
github.com/elliotchance/orderedmap/v3 v3.1.0
github.com/fatih/color v1.18.0
github.com/gin-contrib/static v1.1.3
github.com/gin-gonic/gin v1.10.0
github.com/go-acme/lego/v4 v4.21.0
@ -31,13 +30,13 @@ require (
github.com/pretty66/websocketproxy v0.0.0-20220507015215-930b3a686308
github.com/samber/lo v1.49.1
github.com/sashabaranov/go-openai v1.36.1
github.com/shirou/gopsutil/v4 v4.25.1
github.com/shirou/gopsutil/v4 v4.24.12
github.com/spf13/cast v1.7.1
github.com/stretchr/testify v1.10.0
github.com/tufanbarisyildirim/gonginx v0.0.0-20250120210832-12a9c7ae0c8a
github.com/uozi-tech/cosy v1.14.3
github.com/uozi-tech/cosy-driver-sqlite v0.2.1
go.uber.org/zap v1.27.0
github.com/uozi-tech/cosy-driver-sqlite v0.2.0
github.com/urfave/cli/v3 v3.0.0-beta1
golang.org/x/crypto v0.32.0
golang.org/x/net v0.34.0
gopkg.in/ini.v1 v1.67.0
@ -107,6 +106,7 @@ require (
github.com/dnsimple/dnsimple-go v1.7.0 // indirect
github.com/ebitengine/purego v0.8.2 // indirect
github.com/exoscale/egoscale/v3 v3.1.9 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
@ -253,6 +253,7 @@ require (
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/ratelimit v0.3.1 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/arch v0.13.0 // indirect
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect
golang.org/x/mod v0.22.0 // indirect

6
go.sum
View file

@ -1658,8 +1658,6 @@ github.com/selectel/go-selvpcclient/v3 v3.2.1 h1:ny6WIAMiHzKxOgOEnwcWE79wIQij1AH
github.com/selectel/go-selvpcclient/v3 v3.2.1/go.mod h1:3EfSf8aEWyhspOGbvZ6mvnFg7JN5uckxNyBFPGWsXNQ=
github.com/shirou/gopsutil/v4 v4.24.12 h1:qvePBOk20e0IKA1QXrIIU+jmk+zEiYVVx06WjBRlZo4=
github.com/shirou/gopsutil/v4 v4.24.12/go.mod h1:DCtMPAad2XceTeIAbGyVfycbYQNBGk2P8cvDi7/VN9o=
github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs=
github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
@ -1783,9 +1781,9 @@ github.com/uozi-tech/cosy-driver-postgres v0.2.1 h1:OICakGuT+omva6QOJCxTJ5Lfr7CG
github.com/uozi-tech/cosy-driver-postgres v0.2.1/go.mod h1:eAy1A89yHbAEfjkhNAifaJQk172NqrNoRyRtFcZc9Go=
github.com/uozi-tech/cosy-driver-sqlite v0.2.0 h1:eTpIMyGoFUK4JcaiKfJHD5AyiM6vtCwN98c7Bz5n25o=
github.com/uozi-tech/cosy-driver-sqlite v0.2.0/go.mod h1:87a6mzn5IuEtIR4z7U4Ey8eKLGfNEOSkv7kPQlbNQgM=
github.com/uozi-tech/cosy-driver-sqlite v0.2.1 h1:W+Z4pY25PSJCeReqroG7LIBeffsqotbpHzgqSMqZDIM=
github.com/uozi-tech/cosy-driver-sqlite v0.2.1/go.mod h1:2ya7Z5P3HzFi1ktfL8gvwaAGx0DDV0bmWxNSNpaLlwo=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ=
github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q=
github.com/volcengine/volc-sdk-golang v1.0.194 h1:3o0INQzdtYJWvdGrtX02booCqPL5TsWSq2W1Ur7Bzlo=

50
internal/cmd/main.go Normal file
View file

@ -0,0 +1,50 @@
package cmd
import (
"context"
"fmt"
"log"
"os"
"github.com/0xJacky/Nginx-UI/internal/version"
"github.com/urfave/cli/v3"
)
func NewAppCmd() *cli.Command {
serve := false
cmd := &cli.Command{
Name: "nginx-ui",
Usage: "Yet another Nginx Web UI",
Commands: []*cli.Command{
{
Name: "serve",
Usage: "Start the Nginx-UI server",
Action: func(ctx context.Context, command *cli.Command) error {
serve = true
return nil
},
},
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "config",
Value: "app.ini",
Usage: "configuration file path",
},
},
DefaultCommand: "serve",
Version: version.Version,
}
cli.VersionPrinter = func(cmd *cli.Command) {
fmt.Printf("%s (%d)\n", cmd.Root().Version, version.BuildId)
}
if err := cmd.Run(context.Background(), os.Args); err != nil {
log.Fatal(err)
} else if !serve {
os.Exit(0)
}
return cmd
}

View file

@ -1,12 +1,10 @@
package upgrader
import (
"encoding/json"
"os"
"path/filepath"
"runtime"
"github.com/0xJacky/Nginx-UI/app"
"github.com/pkg/errors"
)
@ -42,19 +40,3 @@ func GetRuntimeInfo() (r RuntimeInfo, err error) {
return
}
func GetCurrentVersion() (c CurVersion, err error) {
verJson, err := app.DistFS.ReadFile(app.VersionPath)
if err != nil {
err = errors.Wrap(err, "service.GetCurrentVersion ReadFile err")
return
}
err = json.Unmarshal(verJson, &c)
if err != nil {
err = errors.Wrap(err, "service.GetCurrentVersion json.Unmarshal err")
return
}
return
}

View file

@ -0,0 +1,26 @@
package version
var (
Version = ""
BuildId = 0
TotalBuild = 0
)
type Info struct {
Version string `json:"version"`
BuildId int `json:"build_id"`
TotalBuild int `json:"total_build"`
}
var versionInfo *Info
func GetVersionInfo() *Info {
if versionInfo == nil {
versionInfo = &Info{
Version: Version,
BuildId: BuildId,
TotalBuild: TotalBuild,
}
}
return versionInfo
}

10
main.go
View file

@ -2,11 +2,11 @@ package main
import (
"errors"
"flag"
"fmt"
"net/http"
"time"
"github.com/0xJacky/Nginx-UI/internal/cmd"
"github.com/0xJacky/Nginx-UI/internal/kernel"
"github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/router"
@ -20,6 +20,8 @@ import (
cSettings "github.com/uozi-tech/cosy/settings"
)
//go:generate go run cmd/version/generate.go
func Program(confPath string) func(state overseer.State) {
return func(state overseer.State) {
defer logger.Sync()
@ -59,12 +61,10 @@ func Program(confPath string) func(state overseer.State) {
}
func main() {
var confPath string
flag.StringVar(&confPath, "config", "app.ini", "Specify the configuration file")
flag.Parse()
appCmd := cmd.NewAppCmd()
confPath := appCmd.String("config")
settings.Init(confPath)
overseer.Run(overseer.Config{
Program: Program(confPath),
Address: fmt.Sprintf("%s:%d", cSettings.ServerSettings.Host, cSettings.ServerSettings.Port),