mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
add external/internal data options
"make all" will build with internal data, whereas "make debug"/"make all-external" will make an external "data/" directory.
This commit is contained in:
parent
815bdc35ac
commit
72cf3e2240
@ -141,13 +141,13 @@ depends_on:
|
|||||||
- arm64-docker
|
- arm64-docker
|
||||||
- armhf-docker
|
- armhf-docker
|
||||||
---
|
---
|
||||||
name: jfa-go-git
|
name: jfa-go-1.16-git
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build
|
- name: build
|
||||||
image: golang:latest
|
image: golang:1.16rc
|
||||||
commands:
|
commands:
|
||||||
- apt update -y
|
- apt update -y
|
||||||
- apt install build-essential python3-pip curl software-properties-common sed upx -y
|
- apt install build-essential python3-pip curl software-properties-common sed upx -y
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@ dist/
|
|||||||
build/
|
build/
|
||||||
data/
|
data/
|
||||||
version.go
|
version.go
|
||||||
|
embed.go
|
||||||
notes
|
notes
|
||||||
docs/*
|
docs/*
|
||||||
lang/langtostruct.py
|
lang/langtostruct.py
|
||||||
|
55
Makefile
55
Makefile
@ -16,31 +16,31 @@ npm:
|
|||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
$(info Fixing config-base)
|
$(info Fixing config-base)
|
||||||
-mkdir -p build/data
|
-mkdir -p data
|
||||||
python3 config/fixconfig.py -i config/config-base.json -o build/data/config-base.json
|
python3 config/fixconfig.py -i config/config-base.json -o data/config-base.json
|
||||||
$(info Generating config-default.ini)
|
$(info Generating config-default.ini)
|
||||||
python3 config/generate_ini.py -i config/config-base.json -o build/data/config-default.ini
|
python3 config/generate_ini.py -i config/config-base.json -o data/config-default.ini
|
||||||
|
|
||||||
email:
|
email:
|
||||||
$(info Generating email html)
|
$(info Generating email html)
|
||||||
python3 mail/generate.py -o build/data/
|
python3 mail/generate.py -o data/
|
||||||
|
|
||||||
typescript:
|
typescript:
|
||||||
$(info compiling typescript)
|
$(info compiling typescript)
|
||||||
-mkdir -p build/data/web/js
|
-mkdir -p data/web/js
|
||||||
-$(ESBUILD) --bundle ts/admin.ts --outfile=./build/data/web/js/admin.js --minify
|
-$(ESBUILD) --bundle ts/admin.ts --outfile=./data/web/js/admin.js --minify
|
||||||
-$(ESBUILD) --bundle ts/form.ts --outfile=./build/data/web/js/form.js --minify
|
-$(ESBUILD) --bundle ts/form.ts --outfile=./data/web/js/form.js --minify
|
||||||
-$(ESBUILD) --bundle ts/setup.ts --outfile=./build/data/web/js/setup.js --minify
|
-$(ESBUILD) --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify
|
||||||
|
|
||||||
ts-debug:
|
ts-debug:
|
||||||
$(info compiling typescript w/ sourcemaps)
|
$(info compiling typescript w/ sourcemaps)
|
||||||
-mkdir -p build/data/web/js
|
-mkdir -p data/web/js
|
||||||
-$(ESBUILD) --bundle ts/admin.ts --sourcemap --outfile=./build/data/web/js/admin.js
|
-$(ESBUILD) --bundle ts/admin.ts --sourcemap --outfile=./data/web/js/admin.js
|
||||||
-$(ESBUILD) --bundle ts/form.ts --sourcemap --outfile=./build/data/web/js/form.js
|
-$(ESBUILD) --bundle ts/form.ts --sourcemap --outfile=./data/web/js/form.js
|
||||||
-$(ESBUILD) --bundle ts/setup.ts --sourcemap --outfile=./build/data/web/js/setup.js
|
-$(ESBUILD) --bundle ts/setup.ts --sourcemap --outfile=./data/web/js/setup.js
|
||||||
-rm -r build/data/web/js/ts
|
-rm -r data/web/js/ts
|
||||||
$(info copying typescript)
|
$(info copying typescript)
|
||||||
cp -r ts build/data/web/js
|
cp -r ts data/web/js
|
||||||
|
|
||||||
swagger:
|
swagger:
|
||||||
go1.16rc1 get github.com/swaggo/swag/cmd/swag
|
go1.16rc1 get github.com/swaggo/swag/cmd/swag
|
||||||
@ -60,24 +60,33 @@ compress:
|
|||||||
upx --lzma build/jfa-go
|
upx --lzma build/jfa-go
|
||||||
|
|
||||||
bundle-css:
|
bundle-css:
|
||||||
-mkdir -p build/data/web/css
|
-mkdir -p data/web/css
|
||||||
$(info bundling css)
|
$(info bundling css)
|
||||||
$(ESBUILD) --bundle css/base.css --outfile=build/data/web/css/bundle.css --external:remixicon.css --minify
|
$(ESBUILD) --bundle css/base.css --outfile=data/web/css/bundle.css --external:remixicon.css --minify
|
||||||
|
|
||||||
copy:
|
copy:
|
||||||
$(info copying fonts)
|
$(info copying fonts)
|
||||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 build/data/web/css/
|
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 data/web/css/
|
||||||
$(info copying html)
|
$(info copying html)
|
||||||
cp -r html build/data/
|
cp -r html data/
|
||||||
$(info copying static data)
|
$(info copying static data)
|
||||||
-mkdir -p build/data/web
|
-mkdir -p data/web
|
||||||
cp -r static/* build/data/web/
|
cp -r static/* data/web/
|
||||||
$(info copying language files)
|
$(info copying language files)
|
||||||
cp -r lang build/data/
|
cp -r lang data/
|
||||||
|
|
||||||
|
embed:
|
||||||
|
python embed.py internal
|
||||||
|
|
||||||
|
noembed:
|
||||||
|
python embed.py external
|
||||||
|
-mkdir -p build
|
||||||
|
$(info copying internal data into build/)
|
||||||
|
cp -r data build/
|
||||||
|
|
||||||
install:
|
install:
|
||||||
cp -r build $(DESTDIR)/jfa-go
|
cp -r build $(DESTDIR)/jfa-go
|
||||||
|
|
||||||
all: configuration npm email version typescript bundle-css swagger copy compile
|
all: configuration npm email version typescript bundle-css swagger copy embed compile
|
||||||
debug: configuration npm email version ts-debug bundle-css swagger copy compile
|
all-external: configuration npm email version ts-debug bundle-css swagger copy noembed compile
|
||||||
|
debug: configuration npm email version ts-debug bundle-css swagger copy noembed compile
|
||||||
|
@ -15,7 +15,7 @@ var emailEnabled = false
|
|||||||
func (app *appContext) GetPath(sect, key string) (fs.FS, string) {
|
func (app *appContext) GetPath(sect, key string) (fs.FS, string) {
|
||||||
val := app.config.Section(sect).Key(key).MustString("")
|
val := app.config.Section(sect).Key(key).MustString("")
|
||||||
if strings.HasPrefix(val, "jfa-go:") {
|
if strings.HasPrefix(val, "jfa-go:") {
|
||||||
return localFS, "build/data/" + strings.TrimPrefix(val, "jfa-go:")
|
return localFS, "data/" + strings.TrimPrefix(val, "jfa-go:")
|
||||||
}
|
}
|
||||||
return app.systemFS, val
|
return app.systemFS, val
|
||||||
}
|
}
|
||||||
|
46
embed.py
Executable file
46
embed.py
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("embed", metavar="<true/false>|<internal/external>|<yes/no>", type=str)
|
||||||
|
trues = ["true", "internal", "yes", "y"]
|
||||||
|
falses = ["false", "external", "no", "n"]
|
||||||
|
|
||||||
|
EMBED = parser.parse_args().embed
|
||||||
|
|
||||||
|
with open("embed.go", "w") as f:
|
||||||
|
if EMBED in trues:
|
||||||
|
f.write("""package main
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed data data/html data/web data/web/css data/web/js
|
||||||
|
var localFS embed.FS
|
||||||
|
|
||||||
|
//go:embed lang/common lang/admin lang/email lang/form lang/setup
|
||||||
|
var langFS embed.FS
|
||||||
|
|
||||||
|
func loadLocalFS() {
|
||||||
|
log.Println("Using internal storage")
|
||||||
|
}""")
|
||||||
|
elif EMBED in falses:
|
||||||
|
f.write("""package main
|
||||||
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"log"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
var localFS fs.FS
|
||||||
|
var langFS fs.FS
|
||||||
|
|
||||||
|
func loadLocalFS() {
|
||||||
|
log.Println("Using external storage")
|
||||||
|
executable, _ := os.Executable()
|
||||||
|
localFS = os.DirFS(filepath.Dir(executable))
|
||||||
|
langFS = os.DirFS(filepath.Join(filepath.Dir(executable), "data"))
|
||||||
|
}""")
|
18
main.go
18
main.go
@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"embed"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
@ -52,13 +51,7 @@ type User struct {
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:embed build/data build/data/html build/data/web build/data/web/css build/data/web/js build/data/web/js/ts
|
// contains (almost) everything the application needs, essentially. This was a dumb design decision imo.
|
||||||
var localFS embed.FS
|
|
||||||
|
|
||||||
//go:embed lang/common lang/admin lang/email lang/form lang/setup
|
|
||||||
var langFS embed.FS
|
|
||||||
|
|
||||||
// contains everything the application needs, essentially. Wouldn't do this in the future.
|
|
||||||
type appContext struct {
|
type appContext struct {
|
||||||
// defaults *Config
|
// defaults *Config
|
||||||
config *ini.File
|
config *ini.File
|
||||||
@ -91,7 +84,7 @@ type appContext struct {
|
|||||||
|
|
||||||
func (app *appContext) loadHTML(router *gin.Engine) {
|
func (app *appContext) loadHTML(router *gin.Engine) {
|
||||||
customPath := app.config.Section("files").Key("html_templates").MustString("")
|
customPath := app.config.Section("files").Key("html_templates").MustString("")
|
||||||
templatePath := "build/data/html"
|
templatePath := "data/html"
|
||||||
htmlFiles, err := fs.ReadDir(localFS, templatePath)
|
htmlFiles, err := fs.ReadDir(localFS, templatePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Fatalf("Couldn't access template directory: \"%s\"", templatePath)
|
app.err.Fatalf("Couldn't access template directory: \"%s\"", templatePath)
|
||||||
@ -201,7 +194,7 @@ func start(asDaemon, firstCall bool) {
|
|||||||
/*
|
/*
|
||||||
set default config, data and local paths
|
set default config, data and local paths
|
||||||
also, confusing naming here. data_path is not the internal 'data' directory, rather the users .config/jfa-go folder.
|
also, confusing naming here. data_path is not the internal 'data' directory, rather the users .config/jfa-go folder.
|
||||||
local_path is the internal 'data' directory.
|
localFS/data is the internal 'data' directory.
|
||||||
*/
|
*/
|
||||||
userConfigDir, _ := os.UserConfigDir()
|
userConfigDir, _ := os.UserConfigDir()
|
||||||
app.dataPath = filepath.Join(userConfigDir, "jfa-go")
|
app.dataPath = filepath.Join(userConfigDir, "jfa-go")
|
||||||
@ -271,7 +264,7 @@ func start(asDaemon, firstCall bool) {
|
|||||||
}
|
}
|
||||||
if _, err := os.Stat(app.configPath); os.IsNotExist(err) {
|
if _, err := os.Stat(app.configPath); os.IsNotExist(err) {
|
||||||
firstRun = true
|
firstRun = true
|
||||||
dConfig, err := fs.ReadFile(localFS, "build/data/config-default.ini")
|
dConfig, err := fs.ReadFile(localFS, "data/config-default.ini")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Fatalf("Couldn't find default config file")
|
app.err.Fatalf("Couldn't find default config file")
|
||||||
}
|
}
|
||||||
@ -435,7 +428,7 @@ func start(asDaemon, firstCall bool) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.configBasePath = "build/data/config-base.json"
|
app.configBasePath = "data/config-base.json"
|
||||||
configBase, _ := fs.ReadFile(localFS, app.configBasePath)
|
configBase, _ := fs.ReadFile(localFS, app.configBasePath)
|
||||||
json.Unmarshal(configBase, &app.configBase)
|
json.Unmarshal(configBase, &app.configBase)
|
||||||
|
|
||||||
@ -782,6 +775,7 @@ func main() {
|
|||||||
if flagPassed("test") {
|
if flagPassed("test") {
|
||||||
TEST = true
|
TEST = true
|
||||||
}
|
}
|
||||||
|
loadLocalFS()
|
||||||
if flagPassed("start") {
|
if flagPassed("start") {
|
||||||
args := []string{}
|
args := []string{}
|
||||||
for i, f := range os.Args {
|
for i, f := range os.Args {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@ -15,13 +14,12 @@ type httpFS struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f httpFS) Open(name string) (http.File, error) {
|
func (f httpFS) Open(name string) (http.File, error) {
|
||||||
fmt.Println("build/data/web" + name)
|
return f.hfs.Open("data/web" + name)
|
||||||
return f.hfs.Open("build/data/web" + name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f httpFS) Exists(prefix string, filepath string) bool {
|
func (f httpFS) Exists(prefix string, filepath string) bool {
|
||||||
if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
|
if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
|
||||||
stats, err := fs.Stat(f.fs, "build/data/web/"+p)
|
stats, err := fs.Stat(f.fs, "data/web/"+p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
try:
|
try:
|
||||||
version = sys.argv[1].replace('v', '')
|
version = sys.argv[1].replace('v', '')
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
Loading…
Reference in New Issue
Block a user