diff --git a/.drone.yml b/.drone.yml index 8bf6782..ce73661 100644 --- a/.drone.yml +++ b/.drone.yml @@ -23,13 +23,13 @@ steps: event: tag --- -name: jfa-go-git +name: jfa-go-1.16-git kind: pipeline type: docker steps: - name: build - image: golang:latest + image: golang:1.16rc commands: - apt update -y - apt install build-essential python3-pip curl software-properties-common sed upx -y diff --git a/.gitignore b/.gitignore index 71a8ff1..062b8b5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ dist/ build/ data/ version.go +embed.go notes docs/* lang/langtostruct.py diff --git a/Makefile b/Makefile index b6ecc72..27a0bca 100644 --- a/Makefile +++ b/Makefile @@ -4,31 +4,31 @@ npm: configuration: $(info Fixing config-base) - -mkdir -p build/data - python3 config/fixconfig.py -i config/config-base.json -o build/data/config-base.json + -mkdir -p data + python3 config/fixconfig.py -i config/config-base.json -o data/config-base.json $(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: $(info Generating email html) - python3 mail/generate.py -o build/data/ + python3 mail/generate.py -o data/ typescript: $(info compiling typescript) - -mkdir -p build/data/web/js - -npx esbuild --bundle ts/admin.ts --outfile=./build/data/web/js/admin.js --minify - -npx esbuild --bundle ts/form.ts --outfile=./build/data/web/js/form.js --minify - -npx esbuild --bundle ts/setup.ts --outfile=./build/data/web/js/setup.js --minify + -mkdir -p data/web/js + -npx esbuild --bundle ts/admin.ts --outfile=./data/web/js/admin.js --minify + -npx esbuild --bundle ts/form.ts --outfile=./data/web/js/form.js --minify + -npx esbuild --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify ts-debug: $(info compiling typescript w/ sourcemaps) - -mkdir -p build/data/web/js - -npx esbuild --bundle ts/admin.ts --sourcemap --outfile=./build/data/web/js/admin.js - -npx esbuild --bundle ts/form.ts --sourcemap --outfile=./build/data/web/js/form.js - -npx esbuild --bundle ts/setup.ts --sourcemap --outfile=./build/data/web/js/setup.js - -rm -r build/data/web/js/ts + -mkdir -p data/web/js + -npx esbuild --bundle ts/admin.ts --sourcemap --outfile=./data/web/js/admin.js + -npx esbuild --bundle ts/form.ts --sourcemap --outfile=./data/web/js/form.js + -npx esbuild --bundle ts/setup.ts --sourcemap --outfile=./data/web/js/setup.js + -rm -r data/web/js/ts $(info copying typescript) - cp -r ts build/data/web/js + cp -r ts data/web/js swagger: go1.16rc1 get github.com/swaggo/swag/cmd/swag @@ -48,24 +48,33 @@ compress: upx --lzma build/jfa-go bundle-css: - -mkdir -p build/data/web/css + -mkdir -p data/web/css $(info bundling css) - npx esbuild --bundle css/base.css --outfile=build/data/web/css/bundle.css --external:remixicon.css --minify + npx esbuild --bundle css/base.css --outfile=data/web/css/bundle.css --external:remixicon.css --minify copy: $(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) - cp -r html build/data/ + cp -r html data/ $(info copying static data) - -mkdir -p build/data/web - cp -r static/* build/data/web/ + -mkdir -p data/web + cp -r static/* data/web/ $(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: cp -r build $(DESTDIR)/jfa-go -all: configuration npm email version typescript bundle-css swagger copy compile -debug: configuration npm email version ts-debug bundle-css swagger copy compile +all: configuration npm email version typescript bundle-css swagger copy embed 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 diff --git a/config.go b/config.go index 07e2830..4c6a48e 100644 --- a/config.go +++ b/config.go @@ -15,7 +15,7 @@ var emailEnabled = false func (app *appContext) GetPath(sect, key string) (fs.FS, string) { val := app.config.Section(sect).Key(key).MustString("") 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 } @@ -47,7 +47,6 @@ func (app *appContext) loadConfig() error { app.config.Section("invite_emails").Key("email_text").SetValue(app.config.Section("invite_emails").Key("email_text").MustString("jfa-go:" + "invite-email.txt")) app.config.Section("email_confirmation").Key("email_html").SetValue(app.config.Section("email_confirmation").Key("email_html").MustString("jfa-go:" + "confirmation.html")) - fmt.Println(app.config.Section("email_confirmation").Key("email_html").String()) app.config.Section("email_confirmation").Key("email_text").SetValue(app.config.Section("email_confirmation").Key("email_text").MustString("jfa-go:" + "confirmation.txt")) app.config.Section("notifications").Key("expiry_html").SetValue(app.config.Section("notifications").Key("expiry_html").MustString("jfa-go:" + "expired.html")) diff --git a/embed.py b/embed.py new file mode 100755 index 0000000..21fd16f --- /dev/null +++ b/embed.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +import sys +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("embed", metavar="||", 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")) +}""") diff --git a/main.go b/main.go index 7791c6d..298fc7a 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "context" "crypto/rand" - "embed" "encoding/base64" "encoding/json" "flag" @@ -51,13 +50,7 @@ type User struct { 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 -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. +// contains (almost) everything the application needs, essentially. This was a dumb design decision imo. type appContext struct { // defaults *Config config *ini.File @@ -90,7 +83,7 @@ type appContext struct { func (app *appContext) loadHTML(router *gin.Engine) { customPath := app.config.Section("files").Key("html_templates").MustString("") - templatePath := "build/data/html" + templatePath := "data/html" htmlFiles, err := fs.ReadDir(localFS, templatePath) if err != nil { app.err.Fatalf("Couldn't access template directory: \"%s\"", templatePath) @@ -200,7 +193,7 @@ func start(asDaemon, firstCall bool) { /* 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. - local_path is the internal 'data' directory. + localFS/data is the internal 'data' directory. */ userConfigDir, _ := os.UserConfigDir() app.dataPath = filepath.Join(userConfigDir, "jfa-go") @@ -270,7 +263,7 @@ func start(asDaemon, firstCall bool) { } if _, err := os.Stat(app.configPath); os.IsNotExist(err) { firstRun = true - dConfig, err := fs.ReadFile(localFS, "build/data/config-default.ini") + dConfig, err := fs.ReadFile(localFS, "data/config-default.ini") if err != nil { app.err.Fatalf("Couldn't find default config file") } @@ -434,7 +427,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) json.Unmarshal(configBase, &app.configBase) @@ -759,6 +752,7 @@ func main() { if flagPassed("test") { TEST = true } + loadLocalFS() if flagPassed("start") { args := []string{} for i, f := range os.Args { diff --git a/static.go b/static.go index ea620f5..41c1c00 100644 --- a/static.go +++ b/static.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "io/fs" "net/http" "strings" @@ -15,13 +14,12 @@ type httpFS struct { } func (f httpFS) Open(name string) (http.File, error) { - fmt.Println("build/data/web" + name) - return f.hfs.Open("build/data/web" + name) + return f.hfs.Open("data/web" + name) } func (f httpFS) Exists(prefix string, filepath string) bool { 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 { return false } diff --git a/version.py b/version.py index 387e23e..3e9b9ed 100644 --- a/version.py +++ b/version.py @@ -1,6 +1,6 @@ import subprocess import sys -import os + try: version = sys.argv[1].replace('v', '') except IndexError: