diff --git a/.gitignore b/.gitignore index a8e850119..e8b0b0555 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ web/public/css/*.* web/public/html/**/*.* web/public/fonts/*.* web/.nyc_output -web/dist/**/* +api/public/**/* /config.json /.dredd/config.json /database.boltdb @@ -18,7 +18,6 @@ node_modules/ /semaphore.iml /bin/ -*-packr.go util/version.go /vendor/ /coverage.out @@ -30,4 +29,4 @@ util/version.go .vscode __debug_bin* -.task/ \ No newline at end of file +.task/ diff --git a/Taskfile.yml b/Taskfile.yml index 394f6b70c..2bff19b8b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -56,7 +56,6 @@ tasks: GORELEASER_VERSION: "0.183.0" GOLINTER_VERSION: "1.46.2" cmds: - - go install github.com/gobuffalo/packr/...@v1.10.4 - go install github.com/snikch/goodman/cmd/goodman@latest - go install github.com/go-swagger/go-swagger/cmd/swagger@v0.29.0 - '{{ if ne OS "windows" }} sh -c "curl -L https://github.com/goreleaser/goreleaser/releases/download/v{{ .GORELEASER_VERSION }}/goreleaser_$(uname -s)_$(uname -m).tar.gz | tar -xz -C $(go env GOPATH)/bin goreleaser"{{ else }} {{ end }}' @@ -84,25 +83,17 @@ tasks: - babel.config.js - vue.config.js generates: - - dist/css/*.css - - dist/js/*.js - - dist/index.html - - dist/favicon.ico + - ../api/public/css/*.css + - ../api/public/js/*.js + - ../api/public/index.html + - ../api/public/favicon.ico cmds: - npm run build compile:be: - desc: Runs Packr for static assets - sources: - - web/dist/* - - db/migrations/* - generates: - - db/db-packr.go - - api/api-packr.go + desc: Generate the version cmds: - - mkdir -p web/dist - go run util/version_gen/generator.go {{ if .TAG }}{{ .TAG }}{{ else }}{{ if .SEMAPHORE_VERSION }}{{ .SEMAPHORE_VERSION }}{{ else }}{{ .BRANCH }}-{{ .SHA }}-{{ .TIMESTAMP }}{{ if .DIRTY }}-dirty{{ end }}{{ end }}{{end}} - - packr vars: TAG: sh: git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed -n 's/^\([^^~]\{1,\}\)\(\^0\)\{0,1\}$/\1/p' @@ -148,7 +139,7 @@ tasks: lint:be: # --errors cmds: - - golangci-lint run --skip-files "\w*(-packr.go)" --disable goconst --timeout 240s ./... + - golangci-lint run --disable goconst --timeout 240s ./... test: cmds: diff --git a/Taskfile_windows.yml b/Taskfile_windows.yml index 46e3690f2..7315f6be4 100644 --- a/Taskfile_windows.yml +++ b/Taskfile_windows.yml @@ -2,7 +2,6 @@ version: '2' tasks: compile:be: cmds: - - packr - go run util/version_gen/generator.go 1 build:local: dir: cli diff --git a/api/router.go b/api/router.go index 63c8cc396..960206105 100644 --- a/api/router.go +++ b/api/router.go @@ -1,10 +1,14 @@ package api import ( + "bytes" + "embed" "fmt" "net/http" "os" + "path" "strings" + "time" "github.com/ansible-semaphore/semaphore/api/helpers" "github.com/ansible-semaphore/semaphore/api/projects" @@ -12,11 +16,13 @@ import ( "github.com/ansible-semaphore/semaphore/api/sockets" "github.com/ansible-semaphore/semaphore/db" "github.com/ansible-semaphore/semaphore/util" - "github.com/gobuffalo/packr" "github.com/gorilla/mux" ) -var publicAssets2 = packr.NewBox("../web/dist") +var startTime = time.Now().UTC() + +//go:embed public/* +var publicAssets embed.FS // StoreMiddleware WTF? func StoreMiddleware(next http.Handler) http.Handler { @@ -51,15 +57,6 @@ func pongHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) } -func notFoundHandler(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) - w.Header().Set("Access-Control-Allow-Credentials", "true") - w.WriteHeader(http.StatusNotFound) - //nolint: errcheck - w.Write([]byte("404 not found")) - fmt.Println(r.Method, ":", r.URL.String(), "--> 404 Not Found") -} - // Route declares all routes func Route() *mux.Router { r := mux.NewRouter() @@ -311,75 +308,86 @@ func debugPrintRoutes(r *mux.Router) { } } -// nolint: gocyclo func servePublic(w http.ResponseWriter, r *http.Request) { webPath := "/" if util.WebHostURL != nil { - webPath = util.WebHostURL.RequestURI() + webPath = util.WebHostURL.Path + if !strings.HasSuffix(webPath, "/") { + webPath += "/" + } } - path := r.URL.Path + reqPath := r.URL.Path + apiPath := path.Join(webPath, "api") - if path == webPath+"api" || strings.HasPrefix(path, webPath+"api/") { - w.WriteHeader(http.StatusNotFound) + if reqPath == apiPath || strings.HasPrefix(reqPath, apiPath) { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } - if !strings.Contains(path, ".") { - path = "/index.html" + if !strings.Contains(reqPath, ".") { + serveFile(w, r, "index.html") + return } - path = strings.Replace(path, webPath, "", 1) - split := strings.Split(path, ".") - suffix := split[len(split)-1] + newPath := strings.Replace( + reqPath, + webPath, + "", + 1, + ) - var res []byte - var err error + serveFile(w, r, newPath) +} - res, err = publicAssets2.MustBytes(path) +func serveFile(w http.ResponseWriter, r *http.Request, name string) { + res, err := publicAssets.ReadFile( + fmt.Sprintf("public/%s", name), + ) if err != nil { - notFoundHandler(w, r) + http.Error( + w, + http.StatusText(http.StatusNotFound), + http.StatusNotFound, + ) + return } - // replace base path - if util.WebHostURL != nil && path == "/index.html" { + if util.WebHostURL != nil && name == "index.html" { baseURL := util.WebHostURL.String() + if !strings.HasSuffix(baseURL, "/") { baseURL += "/" } - res = []byte(strings.Replace(string(res), - "", - "", - 1)) + + res = []byte( + strings.Replace( + string(res), + ``, + fmt.Sprintf(``, baseURL), + 1, + ), + ) } - contentType := "text/plain" - switch suffix { - case "png": - contentType = "image/png" - case "jpg", "jpeg": - contentType = "image/jpeg" - case "gif": - contentType = "image/gif" - case "js": - contentType = "application/javascript" - case "css": - contentType = "text/css" - case "woff": - contentType = "application/x-font-woff" - case "ttf": - contentType = "application/x-font-ttf" - case "otf": - contentType = "application/x-font-otf" - case "html": - contentType = "text/html" + if !strings.HasSuffix(name, ".html") { + w.Header().Add( + "Cache-Control", + fmt.Sprintf("max-age=%d, public, must-revalidate, proxy-revalidate", 24*time.Hour), + ) } - w.Header().Set("content-type", contentType) - _, err = w.Write(res) - util.LogWarning(err) + http.ServeContent( + w, + r, + name, + startTime, + bytes.NewReader( + res, + ), + ) } func getSystemInfo(w http.ResponseWriter, r *http.Request) { diff --git a/db/sql/SqlDb.go b/db/sql/SqlDb.go index cbf1b956b..d4b58aae7 100644 --- a/db/sql/SqlDb.go +++ b/db/sql/SqlDb.go @@ -2,19 +2,20 @@ package sql import ( "database/sql" + "embed" "fmt" - log "github.com/sirupsen/logrus" + "reflect" + "regexp" + "strconv" + "strings" + "github.com/ansible-semaphore/semaphore/db" "github.com/ansible-semaphore/semaphore/util" "github.com/go-gorp/gorp/v3" _ "github.com/go-sql-driver/mysql" // imports mysql driver - "github.com/gobuffalo/packr" _ "github.com/lib/pq" "github.com/Masterminds/squirrel" - "reflect" - "regexp" - "strconv" - "strings" + log "github.com/sirupsen/logrus" ) type SqlDb struct { @@ -28,7 +29,9 @@ create table ` + "`migrations`" + ` ( ` + "`notes`" + ` text null ); ` -var dbAssets = packr.NewBox("./migrations") + +//go:embed migrations/*.sql +var dbAssets embed.FS func containsStr(arr []string, str string) bool { for _, a := range arr { diff --git a/db/sql/migration.go b/db/sql/migration.go index 9032e457f..8139dafa0 100644 --- a/db/sql/migration.go +++ b/db/sql/migration.go @@ -2,12 +2,14 @@ package sql import ( "fmt" - log "github.com/sirupsen/logrus" - "github.com/ansible-semaphore/semaphore/db" - "github.com/go-gorp/gorp/v3" + "path" "regexp" "strings" "time" + + "github.com/ansible-semaphore/semaphore/db" + "github.com/go-gorp/gorp/v3" + log "github.com/sirupsen/logrus" ) var ( @@ -32,14 +34,14 @@ func getVersionErrPath(version db.Migration) string { return version.HumanoidVersion() + ".err.sql" } -// getVersionSQL takes a path to an SQL file and returns it from packr as +// getVersionSQL takes a path to an SQL file and returns it from embed.FS // a slice of strings separated by newlines -func getVersionSQL(path string) (queries []string) { - sql, err := dbAssets.MustString(path) +func getVersionSQL(name string) (queries []string) { + sql, err := dbAssets.ReadFile(path.Join("migrations", name)) if err != nil { panic(err) } - queries = strings.Split(strings.ReplaceAll(sql, ";\r\n", ";\n"), ";\n") + queries = strings.Split(strings.ReplaceAll(string(sql), ";\r\n", ";\n"), ";\n") for i := range queries { queries[i] = strings.Trim(queries[i], "\r\n\t ") } @@ -186,7 +188,7 @@ func (d *SqlDb) ApplyMigration(migration db.Migration) error { // TryRollbackMigration attempts to rollback the database to an earlier version if a rollback exists func (d *SqlDb) TryRollbackMigration(version db.Migration) { - data := dbAssets.Bytes(getVersionErrPath(version)) + data, _ := dbAssets.ReadFile(getVersionErrPath(version)) if len(data) == 0 { fmt.Println("Rollback SQL does not exist.") fmt.Println() diff --git a/deployment/semaphore.spec b/deployment/semaphore.spec index 789f0d6c3..58fadadd0 100644 --- a/deployment/semaphore.spec +++ b/deployment/semaphore.spec @@ -37,7 +37,6 @@ then PATH="$HOME/go/bin:$PATH" fi export PATH -##go install github.com/gobuffalo/packr/v2@latest go-task all cat > ansible-semaphore.service <