From 4cc5f68f0b5685168f8241a2f75562850f695b10 Mon Sep 17 00:00:00 2001 From: Nevkontakte Date: Sat, 19 Feb 2022 21:05:26 +0000 Subject: [PATCH 1/3] Introduce logrus as a logging library for the gopherjs compiler. By default only error-level messages are printed to the terminal, controlled by the new --log_level flag. Use it to log errors build cache library swallows. --- build/cache/cache.go | 17 ++++++++++++++++- compiler/gopherjspkg/fs.go | 2 +- compiler/natives/fs.go | 2 +- go.mod | 1 + go.sum | 3 +++ tool.go | 15 ++++++++++++++- 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/build/cache/cache.go b/build/cache/cache.go index 728962eb0..79e0471cf 100644 --- a/build/cache/cache.go +++ b/build/cache/cache.go @@ -11,6 +11,7 @@ import ( "path/filepath" "github.com/gopherjs/gopherjs/compiler" + log "github.com/sirupsen/logrus" ) // cacheRoot is the base path for GopherJS's own build cache. @@ -95,21 +96,28 @@ func (bc *BuildCache) StoreArchive(a *compiler.Archive) { } path := cachedPath(bc.archiveKey(a.ImportPath)) if err := os.MkdirAll(filepath.Dir(path), 0750); err != nil { + log.Warningf("Failed to create build cache directory: %v", err) return } // Write the archive in a temporary file first to avoid concurrency errors. f, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)) if err != nil { + log.Warningf("Failed to temporary build cache file: %v", err) return } defer f.Close() if err := compiler.WriteArchive(a, f); err != nil { + log.Warningf("Failed to write build cache archive %q: %v", a, err) // Make sure we don't leave a half-written archive behind. os.Remove(f.Name()) + return } f.Close() // Rename fully written file into its permanent name. - os.Rename(f.Name(), path) + if err := os.Rename(f.Name(), path); err != nil { + log.Warningf("Failed to rename build cache archive to %q: %v", path, err) + } + log.Infof("Successfully stored build archive %q as %q.", a, path) } // LoadArchive returns a previously cached archive of the given package or nil @@ -124,13 +132,20 @@ func (bc *BuildCache) LoadArchive(importPath string) *compiler.Archive { path := cachedPath(bc.archiveKey(importPath)) f, err := os.Open(path) if err != nil { + if os.IsNotExist(err) { + log.Infof("No cached package archive for %q.", importPath) + } else { + log.Warningf("Failed to open cached package archive for %q: %v", importPath, err) + } return nil // Cache miss. } defer f.Close() a, err := compiler.ReadArchive(importPath, f) if err != nil { + log.Warningf("Failed to read cached package archive for %q: %v", importPath, err) return nil // Invalid/corrupted archive, cache miss. } + log.Infof("Found cached package archive for %q, built at %v.", importPath, a.BuildTime) return a } diff --git a/compiler/gopherjspkg/fs.go b/compiler/gopherjspkg/fs.go index 9450599a7..d89057148 100644 --- a/compiler/gopherjspkg/fs.go +++ b/compiler/gopherjspkg/fs.go @@ -5,12 +5,12 @@ package gopherjspkg import ( "go/build" - "log" "net/http" "os" pathpkg "path" "github.com/shurcooL/httpfs/filter" + log "github.com/sirupsen/logrus" ) // FS is a virtual filesystem that contains core GopherJS packages. diff --git a/compiler/natives/fs.go b/compiler/natives/fs.go index 0afc6c2c5..cbc6f1e96 100644 --- a/compiler/natives/fs.go +++ b/compiler/natives/fs.go @@ -5,12 +5,12 @@ package natives import ( "go/build" - "log" "net/http" "os" "strings" "github.com/shurcooL/httpfs/filter" + log "github.com/sirupsen/logrus" ) // FS is a virtual filesystem that contains native packages. diff --git a/go.mod b/go.mod index fe517f1c2..995aae96d 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect + github.com/sirupsen/logrus v1.8.1 // indirect golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) diff --git a/go.sum b/go.sum index 301b83448..e439ab2e7 100644 --- a/go.sum +++ b/go.sum @@ -211,6 +211,8 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -365,6 +367,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/tool.go b/tool.go index dcae56119..6d114f5c3 100644 --- a/tool.go +++ b/tool.go @@ -13,7 +13,6 @@ import ( "go/types" "io" "io/ioutil" - "log" "net" "net/http" "os" @@ -35,6 +34,7 @@ import ( "github.com/gopherjs/gopherjs/compiler" "github.com/gopherjs/gopherjs/internal/sysutil" "github.com/neelance/sourcemap" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" "golang.org/x/crypto/ssh/terminal" @@ -595,6 +595,19 @@ func main() { Long: "GopherJS is a tool for compiling Go source code to JavaScript.", } rootCmd.AddCommand(cmdBuild, cmdGet, cmdInstall, cmdRun, cmdTest, cmdServe, cmdVersion, cmdDoc) + + { + var logLevel string + rootCmd.PersistentFlags().StringVar(&logLevel, "log_level", log.ErrorLevel.String(), "Compiler log level (debug, info, warn, error, fatal, panic).") + rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + lvl, err := log.ParseLevel(logLevel) + if err != nil { + return fmt.Errorf("invalid --log_level value %q: %w", logLevel, err) + } + log.SetLevel(lvl) + return nil + } + } err := rootCmd.Execute() if err != nil { os.Exit(2) From eaa9b9774dbb88017f1471178cff915dd1cb754b Mon Sep 17 00:00:00 2001 From: Nevkontakte Date: Sat, 19 Feb 2022 21:13:04 +0000 Subject: [PATCH 2/3] Add -a flag to ignore build cache during the build. The flag behaves similar to the Go tool, any existing cached archives are ignored by the compiler and all packages are rebuilt from scratch. However, the resulting archives are still written back into the cache. --- build/build.go | 19 +++++++++++-------- tool.go | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/build/build.go b/build/build.go index a43f79d9b..f343d1b69 100644 --- a/build/build.go +++ b/build/build.go @@ -332,6 +332,7 @@ type Options struct { Color bool BuildTags []string TestedPackage string + NoCache bool } // PrintError message to the terminal. @@ -606,14 +607,16 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { } } - archive := s.buildCache.LoadArchive(pkg.ImportPath) - if archive != nil && !pkg.SrcModTime.After(archive.BuildTime) { - if err := archive.RegisterTypes(s.Types); err != nil { - panic(fmt.Errorf("Failed to load type information from %v: %w", archive, err)) + if !s.options.NoCache { + archive := s.buildCache.LoadArchive(pkg.ImportPath) + if archive != nil && !pkg.SrcModTime.After(archive.BuildTime) { + if err := archive.RegisterTypes(s.Types); err != nil { + panic(fmt.Errorf("Failed to load type information from %v: %w", archive, err)) + } + s.UpToDateArchives[pkg.ImportPath] = archive + // Existing archive is up to date, no need to build it from scratch. + return archive, nil } - s.UpToDateArchives[pkg.ImportPath] = archive - // Existing archive is up to date, no need to build it from scratch. - return archive, nil } // Existing archive is out of date or doesn't exist, let's build the package. @@ -627,7 +630,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { Packages: s.Types, Import: s.ImportResolverFor(pkg), } - archive, err = compiler.Compile(pkg.ImportPath, files, fileSet, importContext, s.options.Minify) + archive, err := compiler.Compile(pkg.ImportPath, files, fileSet, importContext, s.options.Minify) if err != nil { return nil, err } diff --git a/tool.go b/tool.go index 6d114f5c3..539b64a41 100644 --- a/tool.go +++ b/tool.go @@ -85,6 +85,7 @@ func main() { compilerFlags.BoolVar(&options.Color, "color", terminal.IsTerminal(int(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb", "colored output") compilerFlags.StringVar(&tags, "tags", "", "a list of build tags to consider satisfied during the build") compilerFlags.BoolVar(&options.MapToLocalDisk, "localmap", false, "use local paths for sourcemap") + compilerFlags.BoolVarP(&options.NoCache, "no_cache", "a", false, "rebuild all packages from scratch") flagWatch := pflag.NewFlagSet("", 0) flagWatch.BoolVarP(&options.Watch, "watch", "w", false, "watch for changes to the source files") From d07ae1fee58d60a25f386e4bd4a00c059917c1f1 Mon Sep 17 00:00:00 2001 From: Nevkontakte Date: Sat, 19 Feb 2022 21:19:09 +0000 Subject: [PATCH 3/3] Add `gopherjs clean` subcommand to clean build cache. --- tool.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tool.go b/tool.go index 539b64a41..b32857266 100644 --- a/tool.go +++ b/tool.go @@ -31,6 +31,7 @@ import ( "unicode/utf8" gbuild "github.com/gopherjs/gopherjs/build" + "github.com/gopherjs/gopherjs/build/cache" "github.com/gopherjs/gopherjs/compiler" "github.com/gopherjs/gopherjs/internal/sysutil" "github.com/neelance/sourcemap" @@ -591,11 +592,19 @@ func main() { fmt.Printf("GopherJS %s\n", compiler.Version) } + cmdClean := &cobra.Command{ + Use: "clean", + Short: "clean GopherJS build cache", + } + cmdClean.RunE = func(cmd *cobra.Command, args []string) error { + return cache.Clear() + } + rootCmd := &cobra.Command{ Use: "gopherjs", Long: "GopherJS is a tool for compiling Go source code to JavaScript.", } - rootCmd.AddCommand(cmdBuild, cmdGet, cmdInstall, cmdRun, cmdTest, cmdServe, cmdVersion, cmdDoc) + rootCmd.AddCommand(cmdBuild, cmdGet, cmdInstall, cmdRun, cmdTest, cmdServe, cmdVersion, cmdDoc, cmdClean) { var logLevel string