diff --git a/commands/hugo.go b/commands/hugo.go index 4d7c36105..64befed1d 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -55,7 +55,7 @@ Complete documentation is available at http://gohugo.io`, var hugoCmdV *cobra.Command //Flags that are to be added to commands. -var BuildWatch, Draft, Future, UglyUrls, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap, PluralizeListTitles, NoTimes bool +var BuildWatch, IgnoreCache, Draft, Future, UglyUrls, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap, PluralizeListTitles, NoTimes bool var Source, CacheDir, Destination, Theme, BaseUrl, CfgFile, LogFile, Editor string //Execute adds all child commands to the root command HugoCmd and sets flags appropriately. @@ -84,6 +84,7 @@ func init() { HugoCmd.PersistentFlags().BoolVar(&DisableSitemap, "disableSitemap", false, "Do not build Sitemap file") HugoCmd.PersistentFlags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from") HugoCmd.PersistentFlags().StringVarP(&CacheDir, "cacheDir", "", "$TMPDIR/hugo_cache/", "filesystem path to cache directory") + HugoCmd.PersistentFlags().BoolVarP(&IgnoreCache, "ignoreCache", "", false, "Ignores the cache directory for reading but still writes to it") HugoCmd.PersistentFlags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to") HugoCmd.PersistentFlags().StringVarP(&Theme, "theme", "t", "", "theme to use (located in /themes/THEMENAME/)") HugoCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") @@ -127,6 +128,7 @@ func InitializeConfig() { viper.SetDefault("BuildFuture", false) viper.SetDefault("UglyUrls", false) viper.SetDefault("Verbose", false) + viper.SetDefault("IgnoreCache", false) viper.SetDefault("CanonifyUrls", false) viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"}) viper.SetDefault("Permalinks", make(hugolib.PermalinkOverrides, 0)) @@ -204,10 +206,19 @@ func InitializeConfig() { viper.Set("WorkingDir", dir) } + if hugoCmdV.PersistentFlags().Lookup("ignoreCache").Changed { + viper.Set("IgnoreCache", IgnoreCache) + } + if CacheDir != "" { if helpers.FilePathSeparator != CacheDir[len(CacheDir)-1:] { CacheDir = CacheDir + helpers.FilePathSeparator } + isDir, err := helpers.DirExists(CacheDir, hugofs.SourceFs) + utils.CheckErr(err) + if isDir == false { + mkdir(CacheDir) + } viper.Set("CacheDir", CacheDir) } else { viper.Set("CacheDir", helpers.GetTempDir("hugo_cache", hugofs.SourceFs)) diff --git a/tpl/template_resources.go b/tpl/template_resources.go index d4e105fcb..4f198b40f 100644 --- a/tpl/template_resources.go +++ b/tpl/template_resources.go @@ -64,7 +64,10 @@ func getCacheFileID(id string) string { // resGetCache returns the content for an ID from the file cache or an error // if the file is not found returns nil,nil -func resGetCache(id string, fs afero.Fs) ([]byte, error) { +func resGetCache(id string, fs afero.Fs, ignoreCache bool) ([]byte, error) { + if ignoreCache { + return nil, nil + } fID := getCacheFileID(id) isExists, err := helpers.Exists(fID, fs) if err != nil { @@ -99,7 +102,7 @@ func resWriteCache(id string, c []byte, fs afero.Fs) error { // resGetRemote loads the content of a remote file. This method is thread safe. func resGetRemote(url string, fs afero.Fs, hc *http.Client) ([]byte, error) { - c, err := resGetCache(url, fs) + c, err := resGetCache(url, fs, viper.GetBool("IgnoreCache")) if c != nil && err == nil { return c, nil } @@ -112,7 +115,7 @@ func resGetRemote(url string, fs afero.Fs, hc *http.Client) ([]byte, error) { defer func() { remoteUrlLock.UrlUnlock(url) }() // avoid multiple locks due to calling resGetCache twice - c, err = resGetCache(url, fs) + c, err = resGetCache(url, fs, viper.GetBool("IgnoreCache")) if c != nil && err == nil { return c, nil } diff --git a/tpl/template_resources_test.go b/tpl/template_resources_test.go index 40ea1fc43..0222e558f 100644 --- a/tpl/template_resources_test.go +++ b/tpl/template_resources_test.go @@ -30,19 +30,21 @@ func TestScpCache(t *testing.T) { tests := []struct { path string content []byte + ignore bool }{ - {"http://Foo.Bar/foo_Bar-Foo", []byte(`T€st Content 123`)}, - {"fOO,bar:foo%bAR", []byte(`T€st Content 123 fOO,bar:foo%bAR`)}, - {"FOo/BaR.html", []byte(`FOo/BaR.html T€st Content 123`)}, - {"трям/трям", []byte(`T€st трям/трям Content 123`)}, - {"은행", []byte(`T€st C은행ontent 123`)}, - {"Банковский кассир", []byte(`Банковский кассир T€st Content 123`)}, + {"http://Foo.Bar/foo_Bar-Foo", []byte(`T€st Content 123`), false}, + {"fOO,bar:foo%bAR", []byte(`T€st Content 123 fOO,bar:foo%bAR`), false}, + {"FOo/BaR.html", []byte(`FOo/BaR.html T€st Content 123`), false}, + {"трям/трям", []byte(`T€st трям/трям Content 123`), false}, + {"은행", []byte(`T€st C은행ontent 123`), false}, + {"Банковский кассир", []byte(`Банковский кассир T€st Content 123`), false}, + {"Банковский кассир", []byte(`Банковский кассир T€st Content 456`), true}, } fs := new(afero.MemMapFs) for _, test := range tests { - c, err := resGetCache(test.path, fs) + c, err := resGetCache(test.path, fs, test.ignore) if err != nil { t.Errorf("Error getting cache: %s", err) } @@ -55,12 +57,18 @@ func TestScpCache(t *testing.T) { t.Errorf("Error writing cache: %s", err) } - c, err = resGetCache(test.path, fs) + c, err = resGetCache(test.path, fs, test.ignore) if err != nil { t.Errorf("Error getting cache after writing: %s", err) } - if bytes.Compare(c, test.content) != 0 { - t.Errorf("\nExpected: %s\nActual: %s\n", string(test.content), string(c)) + if test.ignore { + if c != nil { + t.Errorf("Cache ignored but content is not nil: %s", string(c)) + } + } else { + if bytes.Compare(c, test.content) != 0 { + t.Errorf("\nExpected: %s\nActual: %s\n", string(test.content), string(c)) + } } } } @@ -111,10 +119,12 @@ func TestScpGetRemote(t *testing.T) { tests := []struct { path string content []byte + ignore bool }{ - {"http://Foo.Bar/foo_Bar-Foo", []byte(`T€st Content 123`)}, - {"http://Doppel.Gänger/foo_Bar-Foo", []byte(`T€st Cont€nt 123`)}, - {"http://Doppel.Gänger/Fizz_Bazz-Foo", []byte(`T€st Банковский кассир Cont€nt 123`)}, + {"http://Foo.Bar/foo_Bar-Foo", []byte(`T€st Content 123`), false}, + {"http://Doppel.Gänger/foo_Bar-Foo", []byte(`T€st Cont€nt 123`), false}, + {"http://Doppel.Gänger/Fizz_Bazz-Foo", []byte(`T€st Банковский кассир Cont€nt 123`), false}, + {"http://Doppel.Gänger/Fizz_Bazz-Bar", []byte(`T€st Банковский кассир Cont€nt 456`), true}, } for _, test := range tests { @@ -131,12 +141,18 @@ func TestScpGetRemote(t *testing.T) { if bytes.Compare(c, test.content) != 0 { t.Errorf("\nNet Expected: %s\nNet Actual: %s\n", string(test.content), string(c)) } - cc, cErr := resGetCache(test.path, fs) + cc, cErr := resGetCache(test.path, fs, test.ignore) if cErr != nil { t.Error(cErr) } - if bytes.Compare(cc, test.content) != 0 { - t.Errorf("\nCache Expected: %s\nCache Actual: %s\n", string(test.content), string(c)) + if test.ignore { + if cc != nil { + t.Errorf("Cache ignored but content is not nil: %s", string(cc)) + } + } else { + if bytes.Compare(cc, test.content) != 0 { + t.Errorf("\nCache Expected: %s\nCache Actual: %s\n", string(test.content), string(cc)) + } } } }