From 73171bd98fb8dfe6986d39f4417e7eff3336e3a8 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 | 115 +++++++++++++++++++++++++++++++++++++++ pkg/webutil/cdnmirror.go | 43 +++++++++++++++ 2 files changed, 158 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..af519d8 --- /dev/null +++ b/cmd/cdnmirror/main.go @@ -0,0 +1,115 @@ +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/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/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", + } +}