diff --git a/deps/gocode/CMakeLists.txt b/deps/gocode/CMakeLists.txt index da89fa6de8..1d7a446de4 100644 --- a/deps/gocode/CMakeLists.txt +++ b/deps/gocode/CMakeLists.txt @@ -18,10 +18,9 @@ GoInstall (TARGET ns_godu PACKAGE godu GOVERSION 1.8.5 INSTALL_PATH bin/priv) -GoInstall (TARGET ns_minify PACKAGE minify - GOPATH "${CMAKE_CURRENT_SOURCE_DIR}" "${GODEPSDIR}" - GOVERSION 1.8.5 - INSTALL_PATH bin/priv) +GoModBuild (TARGET ns_minify PACKAGE github.com/couchbase/ns_server/deps/gocode/src/minify + GOVERSION 1.13 + OUTPUT minify) GoInstall (TARGET ns_gosecrets PACKAGE gosecrets GOPATH "${CMAKE_CURRENT_SOURCE_DIR}" "${GODEPSDIR}" diff --git a/deps/gocode/src/minify/main.go b/deps/gocode/src/minify/main.go new file mode 100644 index 0000000000..4d4a9219e4 --- /dev/null +++ b/deps/gocode/src/minify/main.go @@ -0,0 +1,70 @@ +// @author Couchbase +// @copyright 2016-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. +package main + +import ( + "flag" + "os" + "log" + "github.com/evanw/esbuild/pkg/api" +) + +func main() { + inDir := flag.String("in-dir", "", "path to js source dir (required)") + outDir := flag.String("out-dir", "", "path to js output dir (required)") + flag.Parse() + log.SetFlags(0) + + if *inDir == "" { + log.Printf("Error: path to js source dir must be specified\n") + flag.Usage() + os.Exit(1) + } + + if *outDir == "" { + log.Printf("Error: path to js source dir must be specified\n") + flag.Usage() + os.Exit(1) + } + + result := api.Build(api.BuildOptions{ + // MinifyWhitespace: true, + // // MinifyIdentifiers: true, + // MinifySyntax: true, + KeepNames: true, + + AbsWorkingDir: *inDir + "/app", + Outdir: *outDir, + + NodePaths: []string{ + *inDir + "/web_modules", + *inDir + "/libs", + *inDir + "/app", + }, + EntryPoints: []string{ + "main.js", + }, + Bundle: true, + Splitting: true, + Write: true, + Metafile: true, + Format: api.FormatESModule, + LogLevel: api.LogLevelInfo, + Engines: []api.Engine{ + {api.EngineChrome, "93"}, + {api.EngineFirefox, "92"}, + {api.EngineSafari, "14"}, + {api.EngineEdge, "93"}, + }, + }) + + if len(result.Errors) > 0 { + os.Exit(1) + } +} diff --git a/deps/gocode/src/minify/minify.go b/deps/gocode/src/minify/minify.go deleted file mode 100644 index 2bdec6963f..0000000000 --- a/deps/gocode/src/minify/minify.go +++ /dev/null @@ -1,220 +0,0 @@ -// @author Couchbase -// @copyright 2016-Present Couchbase, Inc. -// -// Use of this software is governed by the Business Source License included -// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified -// in that file, in accordance with the Business Source License, use of this -// software will be governed by the Apache License, Version 2.0, included in -// the file licenses/APL2.txt. -package main - -import ( - "bytes" - "flag" - "io" - "log" - "os" - "path/filepath" - "strings" - - "github.com/tdewolff/minify" - "github.com/tdewolff/minify/js" - "golang.org/x/net/html" - "golang.org/x/net/html/atom" -) - -func getHTMLNodeAttr(n *html.Node, tagName string, attrKey string) string { - if n.Type == html.ElementNode && n.Data == tagName { - for _, a := range n.Attr { - if a.Key == attrKey { - return a.Val - } - } - } - return "" -} - -func isPluggableUIInjectionComment(n *html.Node) bool { - return n.Type == html.CommentNode && - n.Data == " Inject head.frag.html file content for Pluggable UI components here " -} - -func isWhitespaceText(n *html.Node) bool { - return n.Type == html.TextNode && strings.TrimSpace(n.Data) == "" -} - -func makeAppMinJsNode(minJSName string) *html.Node { - attrs := []html.Attribute{{Key: "src", Val: minJSName}} - return &html.Node{Type: html.ElementNode, Data: "script", DataAtom: atom.Data, Attr: attrs} -} - -func replaceAttrValue(node *html.Node, name string, value string) { - for i := range node.Attr { - if node.Attr[i].Key == name { - node.Attr[i].Val = value - } - } -} - -func makeNewLine() *html.Node { - return &html.Node{Type: html.TextNode, Data: "\n"} -} - -type context struct { - BaseDir string - FoundFirstAppScript bool -} - -type result struct { - PluggableInjectionCount int - AppScripts []string - IndexHTMLBase string -} - -func (r1 *result) merge(r2 result) { - if r1.IndexHTMLBase == "" { - r1.IndexHTMLBase = r2.IndexHTMLBase - } - r1.AppScripts = append(r1.AppScripts, r2.AppScripts...) - r1.PluggableInjectionCount += r2.PluggableInjectionCount -} - -// Minifies node and returns a minification Result. -func doMinify(node *html.Node, ctx *context, minJSName string) result { - prevWasWhitespace := false - var next *html.Node - rv := result{} - for child := node.FirstChild; child != nil; child = next { - next = child.NextSibling - script := getHTMLNodeAttr(child, "script", "src") - if rv.IndexHTMLBase == "" { - rv.IndexHTMLBase = getHTMLNodeAttr(child, "base", "href") - } - switch { - case strings.Contains(script, "libs/") && strings.HasSuffix(script, ".js"): - minFile := script[:len(script)-3] + ".min.js" - if _, err := os.Stat(filepath.Join(ctx.BaseDir, minFile)); err == nil { - replaceAttrValue(child, "src", minFile) - } - prevWasWhitespace = false - case strings.HasSuffix(script, ".js"): - if !ctx.FoundFirstAppScript { - ctx.FoundFirstAppScript = true - node.InsertBefore(makeAppMinJsNode(minJSName), child) - node.InsertBefore(makeNewLine(), child) - } - rv.AppScripts = append(rv.AppScripts, script) - node.RemoveChild(child) - case isWhitespaceText(child) && node.Type == html.ElementNode && node.Data == "head": - if !prevWasWhitespace { - node.InsertBefore(makeNewLine(), child) - } - node.RemoveChild(child) - prevWasWhitespace = true - default: - if isPluggableUIInjectionComment(child) { - rv.PluggableInjectionCount++ - } else { - childResult := doMinify(child, ctx, minJSName) - rv.merge(childResult) - } - prevWasWhitespace = false - } - } - return rv -} - -func closeFile(file *os.File, sync bool) { - if sync { - err := file.Sync() - if err != nil { - log.Printf("Error flushing file: %v", err) - } - } - if err := file.Close(); err != nil { - panic(err) - } -} - -func createAppMinJsFile(appScripts []string, dir string, minJSName string) { - appMinJsWrtr, err := os.Create(filepath.Join(dir, minJSName)) - if err != nil { - log.Fatal(err) - } - defer closeFile(appMinJsWrtr, true) - var buffer bytes.Buffer - for _, script := range appScripts { - file, err := os.Open(filepath.Join(dir, script)) - if err != nil { - log.Fatal(err) - } - defer closeFile(file, false) - _, err = io.Copy(&buffer, file) - if err != nil { - log.Fatalf("Error copying script file '%v' to buffer: %v", script, err) - } - - } - mimetype := "text/javascript" - minifier := minify.New() - minifier.AddFunc(mimetype, js.Minify) - minified, err := minify.Bytes(minifier, mimetype, buffer.Bytes()) - if err != nil { - log.Fatalf("Error during minification: %v", err) - } - - _, err = io.Copy(appMinJsWrtr, bytes.NewReader(minified)) - if err != nil { - log.Fatalf("Error copying to file app.min.js: %v", err) - } -} - -func createIndexMinHTMLFile(document *html.Node, dir string, minHTMLName string) { - wrtr, err := os.Create(filepath.Join(dir, minHTMLName)) - if err != nil { - log.Fatalf("Error: could not open file for write: %v", err) - } - defer closeFile(wrtr, true) - html.Render(wrtr, document) -} - -func validateFlags(falgToCheck string, error string) { - if falgToCheck == "" { - log.Printf(error) - flag.Usage() - os.Exit(1) - } -} - -func main() { - indexHTML := flag.String("index-html", "", "path to index.html file (required)") - minJSName := flag.String("min-js-name", "", "output html file name (required)") - minHTMLName := flag.String("min-html-name", "", "output js file name (required)") - - flag.Parse() - log.SetFlags(0) - - validateFlags(*indexHTML, "Error: path to index.html file must be specified\n") - validateFlags(*minHTMLName, "Error: output html file name must be specified\n") - validateFlags(*minJSName, "Error: output js file name must be specified\n") - - rdr, err := os.Open(*indexHTML) - if err != nil { - log.Fatalf("Error: Can't open file: %v", err) - } - defer closeFile(rdr, false) - - dir := filepath.Dir(*indexHTML) - doc, err := html.Parse(rdr) - if err != nil { - log.Fatalf("Error during parse of '%v': %v", *indexHTML, err) - } - rv := doMinify(doc, &context{BaseDir: dir}, *minJSName) - if rv.PluggableInjectionCount != 1 { - log.Fatalf("Error: number of pluggable injection comments found was %v, should be 1", - rv.PluggableInjectionCount) - } - dirRelativeToBase := filepath.Join(dir, rv.IndexHTMLBase) - createAppMinJsFile(rv.AppScripts, dirRelativeToBase, *minJSName) - createIndexMinHTMLFile(doc, dir, *minHTMLName) -} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000000..b54e2b5fdf --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/couchbase/ns_server + +go 1.17 + +require github.com/evanw/esbuild v0.12.27 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000..f400bb605f --- /dev/null +++ b/go.sum @@ -0,0 +1,12 @@ +github.com/evanw/esbuild v0.12.27 h1:pWtTIKGO4Af2P2u6Jps5vmJy1wpUqdx4QmI1Y/fvxY8= +github.com/evanw/esbuild v0.12.27/go.mod h1:GG+zjdi59yh3ehDn4ZWfPcATxjPDUH53iU4ZJbp7dkY= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365 h1:6wSTsvPddg9gc/mVEEyk9oOAoxn+bT4Z9q1zx+4RwA4= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=