From b4075afefe4bd7e6ed48230e6478bf4391e4fb62 Mon Sep 17 00:00:00 2001 From: Sven Walter Date: Fri, 23 Sep 2022 08:03:46 +0200 Subject: [PATCH] add cdnmirror --- cmd/cdnmirror/main.go | 116 +++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 + pkg/webutil/cdnmirror.go | 43 +++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 cmd/cdnmirror/main.go create mode 100644 pkg/webutil/cdnmirror.go diff --git a/cmd/cdnmirror/main.go b/cmd/cdnmirror/main.go new file mode 100644 index 0000000..48a28b0 --- /dev/null +++ b/cmd/cdnmirror/main.go @@ -0,0 +1,116 @@ +package main + +import ( + "bytes" + "context" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "path" + "path/filepath" + + "github.com/evanw/esbuild/pkg/api" + "github.com/pkg/errors" + "github.com/rebuy-de/rebuy-go-sdk/v4/pkg/cmdutil" + "github.com/rebuy-de/rebuy-go-sdk/v4/pkg/webutil" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +const targetPathPrefix = `assets/cdnmirror` + +func main() { + defer cmdutil.HandleExit() + if err := NewRootCommand().Execute(); err != nil { + logrus.Fatal(err) + } +} + +func NewRootCommand() *cobra.Command { + return cmdutil.New( + "cdnmirror SOURCE_NAME..", "Downloads assets from CDNs so the server can serve them directly.", + cmdutil.WithLogVerboseFlag(), + cmdutil.WithRun(Generate), + ) +} + +func Generate(ctx context.Context, cmd *cobra.Command, args []string) { + err := os.MkdirAll(targetPathPrefix, 0755) + cmdutil.Must(err) + + writeGitignore() + + for _, name := range args { + source := resolve(name) + download(source) + } +} + +func writeGitignore() { + filename := path.Join(targetPathPrefix, ".gitignore") + + buf := new(bytes.Buffer) + fmt.Fprintln(buf, "*") + fmt.Fprintln(buf, "!.gitignore") + + err := ioutil.WriteFile(filename, buf.Bytes(), 0644) + cmdutil.Must(err) +} + +func resolve(name string) webutil.CDNMirrorSource { + switch name { + case "@hotwired/turbo": + return webutil.CDNMirrorSourceHotwiredTurbo() + case "bootstrap": + return webutil.CDNMirrorSourceBootstrap() + case "font-awesome-sprites": + return webutil.CDNMirrorSourceFontAwesomeSprites() + case "bulma": + return webutil.CDNMirrorSourceBulma() + default: + cmdutil.Must(errors.Errorf("invalid source name")) + return webutil.CDNMirrorSource{} + } +} + +func download(source webutil.CDNMirrorSource) { + targetFile := filepath.FromSlash(path.Join(targetPathPrefix, source.Target)) + + resp, err := http.Get(source.URL) + cmdutil.Must(err) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + cmdutil.Must(fmt.Errorf(resp.Status)) + } + + body, err := io.ReadAll(resp.Body) + cmdutil.Must(err) + + var code string + + switch source.Minify { + case webutil.CDNMirrorMinifyJS: + result := api.Transform(string(body), api.TransformOptions{ + MinifyWhitespace: true, + MinifyIdentifiers: true, + MinifySyntax: true, + }) + if len(result.Errors) != 0 { + cmdutil.Must(errors.Errorf("%#v", result.Errors)) + } + code = string(result.Code) + + default: + code = string(body) + } + + f, err := os.Create(targetFile) + cmdutil.Must(err) + defer f.Close() + + _, err = io.WriteString(f, code) + cmdutil.Must(err) +} diff --git a/go.mod b/go.mod index 92ec990..0588a39 100644 --- a/go.mod +++ b/go.mod @@ -69,6 +69,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/emirpasic/gods v1.12.0 // indirect + github.com/evanw/esbuild v0.15.9 // indirect github.com/fatih/color v1.13.0 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect diff --git a/go.sum b/go.sum index a241b5d..c454972 100644 --- a/go.sum +++ b/go.sum @@ -181,6 +181,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanw/esbuild v0.15.9 h1:1mjUDJqaSdVZJa6HXD5tyKDNZ2fym9lULLg+Ar2Nqzs= +github.com/evanw/esbuild v0.15.9/go.mod h1:iINY06rn799hi48UqEnaQvVfZWe6W9bET78LbvN8VWk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= diff --git a/pkg/webutil/cdnmirror.go b/pkg/webutil/cdnmirror.go new file mode 100644 index 0000000..25031b1 --- /dev/null +++ b/pkg/webutil/cdnmirror.go @@ -0,0 +1,43 @@ +package webutil + +type CDNMirrorSource struct { + URL string + Target string + Minify CDNMirrorMinifier +} + +type CDNMirrorMinifier string + +const ( + CDNMirrorMinifyJS = "js" + CDNMirrorMinifyCSS = "css" +) + +func CDNMirrorSourceHotwiredTurbo() CDNMirrorSource { + return CDNMirrorSource{ + URL: "https://unpkg.com/@hotwired/turbo@7.1.0/dist/turbo.es2017-umd.js", + Target: "hotwired-turbo-7.1.0-min.js", + Minify: CDNMirrorMinifyJS, + } +} + +func CDNMirrorSourceBootstrap() CDNMirrorSource { + return CDNMirrorSource{ + URL: "https://unpkg.com/bootstrap@5.1.3/dist/css/bootstrap.min.css", + Target: "bootstrap-5.1.3-min.css", + } +} + +func CDNMirrorSourceFontAwesomeSprites() CDNMirrorSource { + return CDNMirrorSource{ + URL: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/sprites/solid.svg", + Target: "font-awesome-6.1.2-sprites-solid.svg", + } +} + +func CDNMirrorSourceBulma() CDNMirrorSource { + return CDNMirrorSource{ + URL: "https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css", + Target: "bulma-0.7.4.min.css", + } +}