diff --git a/commands/check.go b/commands/check.go index 8430f4cc2..6ce8b8177 100644 --- a/commands/check.go +++ b/commands/check.go @@ -14,52 +14,18 @@ package commands import ( - "fmt" - "github.com/spf13/cobra" - "github.com/spf13/hugo/hugolib" - "syscall" + "github.com/spf13/cobra" + "github.com/spf13/hugo/hugolib" ) -func init() { - check.AddCommand(limit) -} - var check = &cobra.Command{ - Use: "check", - Short: "Check content in the source directory", - Long: `Hugo will perform some basic analysis on the + Use: "check", + Short: "Check content in the source directory", + Long: `Hugo will perform some basic analysis on the content provided and will give feedback.`, - Run: func(cmd *cobra.Command, args []string) { - InitializeConfig() - site := hugolib.Site{Config: *Config} - site.Analyze() - }, -} - -var limit = &cobra.Command{ - Use: "ulimit", - Short: "Check system ulimit settings", - Long: `Hugo will inspect the current ulimit settings on the system. - This is primarily to ensure that Hugo can watch enough files on some OSs`, - Run: func(cmd *cobra.Command, args []string) { - var rLimit syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println("Error Getting Rlimit ", err) - } - fmt.Println("Current rLimit:", rLimit) - - fmt.Println("Attempting to increase limit") - rLimit.Max = 999999 - rLimit.Cur = 999999 - err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println("Error Setting rLimit ", err) - } - err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println("Error Getting rLimit ", err) - } - fmt.Println("rLimit after change:", rLimit) - }, + Run: func(cmd *cobra.Command, args []string) { + InitializeConfig() + site := hugolib.Site{Config: *Config} + site.Analyze() + }, } diff --git a/commands/hugo.go b/commands/hugo.go index ef5477fe0..2c4b00bb1 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -14,34 +14,33 @@ package commands import ( - "fmt" - "github.com/mostafah/fsync" - "github.com/spf13/cobra" - "github.com/spf13/hugo/hugolib" - "github.com/spf13/hugo/utils" - "github.com/spf13/hugo/watcher" - "github.com/spf13/nitro" - "os" - "path/filepath" - "runtime" - "strings" - "sync" - "syscall" - "time" + "fmt" + "github.com/mostafah/fsync" + "github.com/spf13/cobra" + "github.com/spf13/hugo/hugolib" + "github.com/spf13/hugo/utils" + "github.com/spf13/hugo/watcher" + "github.com/spf13/nitro" + "os" + "path/filepath" + "runtime" + "strings" + "sync" + "time" ) var Config *hugolib.Config var HugoCmd = &cobra.Command{ - Use: "hugo", - Short: "Hugo is a very fast static site generator", - Long: `A Fast and Flexible Static Site Generator built with + Use: "hugo", + Short: "Hugo is a very fast static site generator", + Long: `A Fast and Flexible Static Site Generator built with love by spf13 and friends in Go. Complete documentation is available at http://hugo.spf13.com`, - Run: func(cmd *cobra.Command, args []string) { - InitializeConfig() - build() - }, + Run: func(cmd *cobra.Command, args []string) { + InitializeConfig() + build() + }, } var hugoCmdV *cobra.Command @@ -49,203 +48,191 @@ var BuildWatch, Draft, UglyUrls, Verbose bool var Source, Destination, BaseUrl, CfgFile string func Execute() { - AddCommands() - utils.StopOnErr(HugoCmd.Execute()) + AddCommands() + utils.StopOnErr(HugoCmd.Execute()) } func AddCommands() { - HugoCmd.AddCommand(serverCmd) - HugoCmd.AddCommand(version) - HugoCmd.AddCommand(check) - HugoCmd.AddCommand(benchmark) + HugoCmd.AddCommand(serverCmd) + HugoCmd.AddCommand(version) + HugoCmd.AddCommand(check) + HugoCmd.AddCommand(benchmark) } func init() { - HugoCmd.PersistentFlags().BoolVarP(&Draft, "build-drafts", "D", false, "include content marked as draft") - HugoCmd.PersistentFlags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from") - HugoCmd.PersistentFlags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to") - HugoCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") - HugoCmd.PersistentFlags().BoolVar(&UglyUrls, "uglyurls", false, "if true, use /filename.html instead of /filename/") - HugoCmd.PersistentFlags().StringVarP(&BaseUrl, "base-url", "b", "", "hostname (and path) to the root eg. http://spf13.com/") - HugoCmd.PersistentFlags().StringVar(&CfgFile, "config", "", "config file (default is path/config.yaml|json|toml)") - HugoCmd.PersistentFlags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") - HugoCmd.Flags().BoolVarP(&BuildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") - hugoCmdV = HugoCmd + HugoCmd.PersistentFlags().BoolVarP(&Draft, "build-drafts", "D", false, "include content marked as draft") + HugoCmd.PersistentFlags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from") + HugoCmd.PersistentFlags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to") + HugoCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") + HugoCmd.PersistentFlags().BoolVar(&UglyUrls, "uglyurls", false, "if true, use /filename.html instead of /filename/") + HugoCmd.PersistentFlags().StringVarP(&BaseUrl, "base-url", "b", "", "hostname (and path) to the root eg. http://spf13.com/") + HugoCmd.PersistentFlags().StringVar(&CfgFile, "config", "", "config file (default is path/config.yaml|json|toml)") + HugoCmd.PersistentFlags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") + HugoCmd.Flags().BoolVarP(&BuildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") + hugoCmdV = HugoCmd } func InitializeConfig() { - Config = hugolib.SetupConfig(&CfgFile, &Source) + Config = hugolib.SetupConfig(&CfgFile, &Source) - if hugoCmdV.PersistentFlags().Lookup("build-drafts").Changed { - Config.BuildDrafts = Draft - } + if hugoCmdV.PersistentFlags().Lookup("build-drafts").Changed { + Config.BuildDrafts = Draft + } - if hugoCmdV.PersistentFlags().Lookup("uglyurls").Changed { - Config.UglyUrls = UglyUrls - } + if hugoCmdV.PersistentFlags().Lookup("uglyurls").Changed { + Config.UglyUrls = UglyUrls + } - if hugoCmdV.PersistentFlags().Lookup("verbose").Changed { - Config.Verbose = Verbose - } - if BaseUrl != "" { - Config.BaseUrl = BaseUrl - } - if Destination != "" { - Config.PublishDir = Destination - } + if hugoCmdV.PersistentFlags().Lookup("verbose").Changed { + Config.Verbose = Verbose + } + if BaseUrl != "" { + Config.BaseUrl = BaseUrl + } + if Destination != "" { + Config.PublishDir = Destination + } } func build(watches ...bool) { - utils.CheckErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", Config.GetAbsPath(Config.PublishDir))) - watch := false - if len(watches) > 0 && watches[0] { - watch = true - } - utils.StopOnErr(buildSite(BuildWatch || watch)) + utils.CheckErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", Config.GetAbsPath(Config.PublishDir))) + watch := false + if len(watches) > 0 && watches[0] { + watch = true + } + utils.StopOnErr(buildSite(BuildWatch || watch)) - if BuildWatch { - fmt.Println("Watching for changes in", Config.GetAbsPath(Config.ContentDir)) - fmt.Println("Press ctrl+c to stop") - utils.CheckErr(NewWatcher(0)) - } + if BuildWatch { + fmt.Println("Watching for changes in", Config.GetAbsPath(Config.ContentDir)) + fmt.Println("Press ctrl+c to stop") + utils.CheckErr(NewWatcher(0)) + } } func copyStatic() error { - staticDir := Config.GetAbsPath(Config.StaticDir + "/") - if _, err := os.Stat(staticDir); os.IsNotExist(err) { - return nil - } + staticDir := Config.GetAbsPath(Config.StaticDir + "/") + if _, err := os.Stat(staticDir); os.IsNotExist(err) { + return nil + } - // Copy Static to Destination - return fsync.Sync(Config.GetAbsPath(Config.PublishDir+"/"), Config.GetAbsPath(Config.StaticDir+"/")) + // Copy Static to Destination + return fsync.Sync(Config.GetAbsPath(Config.PublishDir+"/"), Config.GetAbsPath(Config.StaticDir+"/")) } func getDirList() []string { - var a []string - walker := func(path string, fi os.FileInfo, err error) error { - if err != nil { - fmt.Println("Walker: ", err) - return nil - } + var a []string + walker := func(path string, fi os.FileInfo, err error) error { + if err != nil { + fmt.Println("Walker: ", err) + return nil + } - if fi.IsDir() { - a = append(a, path) - } - return nil - } + if fi.IsDir() { + a = append(a, path) + } + return nil + } - filepath.Walk(Config.GetAbsPath(Config.ContentDir), walker) - filepath.Walk(Config.GetAbsPath(Config.LayoutDir), walker) - filepath.Walk(Config.GetAbsPath(Config.StaticDir), walker) + filepath.Walk(Config.GetAbsPath(Config.ContentDir), walker) + filepath.Walk(Config.GetAbsPath(Config.LayoutDir), walker) + filepath.Walk(Config.GetAbsPath(Config.StaticDir), walker) - return a + return a } func buildSite(watching ...bool) (err error) { - startTime := time.Now() - site := &hugolib.Site{Config: *Config} - if len(watching) > 0 && watching[0] { - site.RunMode.Watching = true - } - err = site.Build() - if err != nil { - return - } - site.Stats() - fmt.Printf("in %v ms\n", int(1000*time.Since(startTime).Seconds())) - return nil + startTime := time.Now() + site := &hugolib.Site{Config: *Config} + if len(watching) > 0 && watching[0] { + site.RunMode.Watching = true + } + err = site.Build() + if err != nil { + return + } + site.Stats() + fmt.Printf("in %v ms\n", int(1000*time.Since(startTime).Seconds())) + return nil } func NewWatcher(port int) error { - if runtime.GOOS == "darwin" { - var rLimit syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println("Unable to obtain rLimit", err) - } - if rLimit.Cur < rLimit.Max { - rLimit.Max = 999999 - rLimit.Cur = 999999 - err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - fmt.Println("Unable to increase number of open files limit", err) - } - } - } + if runtime.GOOS == "darwin" { + tweakLimit() + } - watcher, err := watcher.New(1 * time.Second) - var wg sync.WaitGroup + watcher, err := watcher.New(1 * time.Second) + var wg sync.WaitGroup - if err != nil { - fmt.Println(err) - return err - } + if err != nil { + fmt.Println(err) + return err + } - defer watcher.Close() + defer watcher.Close() - wg.Add(1) + wg.Add(1) - for _, d := range getDirList() { - if d != "" { - _ = watcher.Watch(d) - } - } + for _, d := range getDirList() { + if d != "" { + _ = watcher.Watch(d) + } + } - go func() { - for { - select { - case evs := <-watcher.Event: - if Verbose { - fmt.Println(evs) - } + go func() { + for { + select { + case evs := <-watcher.Event: + if Verbose { + fmt.Println(evs) + } - static_changed := false - dynamic_changed := false + static_changed := false + dynamic_changed := false - for _, ev := range evs { - ext := filepath.Ext(ev.Name) - istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || (ext == ".tmp") - if istemp { - continue - } - // renames are always followed with Create/Modify - if ev.IsRename() { - continue - } + for _, ev := range evs { + ext := filepath.Ext(ev.Name) + istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || (ext == ".tmp") + if istemp { + continue + } + // renames are always followed with Create/Modify + if ev.IsRename() { + continue + } - isstatic := strings.HasPrefix(ev.Name, Config.GetAbsPath(Config.StaticDir)) - static_changed = static_changed || isstatic - dynamic_changed = dynamic_changed || !isstatic + isstatic := strings.HasPrefix(ev.Name, Config.GetAbsPath(Config.StaticDir)) + static_changed = static_changed || isstatic + dynamic_changed = dynamic_changed || !isstatic - // add new directory to watch list - if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() { - if ev.IsCreate() { - watcher.Watch(ev.Name) - } - } - } + // add new directory to watch list + if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() { + if ev.IsCreate() { + watcher.Watch(ev.Name) + } + } + } - if static_changed { - fmt.Println("Static file changed, syncing\n") - utils.CheckErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", Config.GetAbsPath(Config.PublishDir))) - } + if static_changed { + fmt.Println("Static file changed, syncing\n") + utils.CheckErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", Config.GetAbsPath(Config.PublishDir))) + } - if dynamic_changed { - fmt.Println("Change detected, rebuilding site\n") - utils.StopOnErr(buildSite(true)) - } - case err := <-watcher.Error: - if err != nil { - fmt.Println("error:", err) - } - } - } - }() + if dynamic_changed { + fmt.Println("Change detected, rebuilding site\n") + utils.StopOnErr(buildSite(true)) + } + case err := <-watcher.Error: + if err != nil { + fmt.Println("error:", err) + } + } + } + }() - if port > 0 { - go serve(port) - } + if port > 0 { + go serve(port) + } - wg.Wait() - return nil + wg.Wait() + return nil } diff --git a/commands/limit_darwin.go b/commands/limit_darwin.go new file mode 100644 index 000000000..507dd1ce5 --- /dev/null +++ b/commands/limit_darwin.go @@ -0,0 +1,63 @@ +// +build darwin +// Copyright © 2013 Steve Francia . +// +// Licensed under the Simple Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://opensource.org/licenses/Simple-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package commands + +func init() { + check.AddCommand(limit) +} + +var limit = &cobra.Command{ + Use: "ulimit", + Short: "Check system ulimit settings", + Long: `Hugo will inspect the current ulimit settings on the system. + This is primarily to ensure that Hugo can watch enough files on some OSs`, + Run: func(cmd *cobra.Command, args []string) { + var rLimit syscall.Rlimit + err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println("Error Getting Rlimit ", err) + } + fmt.Println("Current rLimit:", rLimit) + + fmt.Println("Attempting to increase limit") + rLimit.Max = 999999 + rLimit.Cur = 999999 + err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println("Error Setting rLimit ", err) + } + err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println("Error Getting rLimit ", err) + } + fmt.Println("rLimit after change:", rLimit) + }, +} + +func tweakLimit() { + var rLimit syscall.Rlimit + err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println("Unable to obtain rLimit", err) + } + if rLimit.Cur < rLimit.Max { + rLimit.Max = 999999 + rLimit.Cur = 999999 + err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + fmt.Println("Unable to increase number of open files limit", err) + } + } +} diff --git a/commands/limit_others.go b/commands/limit_others.go new file mode 100644 index 000000000..752ed95d7 --- /dev/null +++ b/commands/limit_others.go @@ -0,0 +1,19 @@ +// +build !darwin +// Copyright © 2013 Steve Francia . +// +// Licensed under the Simple Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://opensource.org/licenses/Simple-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package commands + +func tweakLimit() { + // nothing to do +}