From 7ee1f25e9ef3be8f99c171e8e7982f4f82c13e16 Mon Sep 17 00:00:00 2001 From: coderzh Date: Wed, 2 Mar 2016 08:06:02 +0800 Subject: [PATCH] hugo import jekyll support nested _posts directories Fixes #1890 Closes #1911 --- commands/import_jekyll.go | 109 +++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/commands/import_jekyll.go b/commands/import_jekyll.go index 26a41c82..3d89fee0 100644 --- a/commands/import_jekyll.go +++ b/commands/import_jekyll.go @@ -84,9 +84,17 @@ func importFromJekyll(cmd *cobra.Command, args []string) error { } forceImport, _ := cmd.Flags().GetBool("force") - site, err := createSiteFromJekyll(jekyllRoot, targetDir, forceImport) + + fs := afero.NewOsFs() + jekyllPostDirs, hasAnyPost := getJekyllDirInfo(fs, jekyllRoot) + if !hasAnyPost { + return errors.New("Your Jekyll root contains neither posts nor drafts, aborting.") + } + + site, err := createSiteFromJekyll(jekyllRoot, targetDir, jekyllPostDirs, forceImport) + if err != nil { - return err + return newUserError(err) } jww.FEEDBACK.Println("Importing...") @@ -110,10 +118,10 @@ func importFromJekyll(cmd *cobra.Command, args []string) error { draft := false switch { - case strings.HasPrefix(relPath, "_posts/"): - relPath = "content/post" + relPath[len("_posts"):] - case strings.HasPrefix(relPath, "_drafts/"): - relPath = "content/draft" + relPath[len("_drafts"):] + case strings.Contains(relPath, "_posts/"): + relPath = filepath.Join("content/post", strings.Replace(relPath, "_posts/", "", -1)) + case strings.Contains(relPath, "_drafts/"): + relPath = filepath.Join("content/draft", strings.Replace(relPath, "_drafts/", "", -1)) draft = true default: return nil @@ -123,11 +131,19 @@ func importFromJekyll(cmd *cobra.Command, args []string) error { return convertJekyllPost(site, path, relPath, targetDir, draft) } - err = helpers.SymbolicWalk(hugofs.Os, jekyllRoot, callback) - - if err != nil { - return err + for jekyllPostDir, hasAnyPostInDir := range jekyllPostDirs { + if hasAnyPostInDir { + if err = helpers.SymbolicWalk(hugofs.Os, filepath.Join(jekyllRoot, jekyllPostDir), callback); err != nil { + return err + } + } } + + jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!") + jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" + + "$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove") + jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove") + jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!") jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" + "$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove") @@ -136,15 +152,52 @@ func importFromJekyll(cmd *cobra.Command, args []string) error { return nil } -// TODO: Consider calling doNewSite() instead? -func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) (*hugolib.Site, error) { +func getJekyllDirInfo(fs afero.Fs, jekyllRoot string) (map[string]bool, bool) { + postDirs := make(map[string]bool) + hasAnyPost := false + if entries, err := ioutil.ReadDir(jekyllRoot); err == nil { + for _, entry := range entries { + if entry.IsDir() { + subDir := filepath.Join(jekyllRoot, entry.Name()) + if isPostDir, hasAnyPostInDir := retrieveJekyllPostDir(fs, subDir); isPostDir { + postDirs[entry.Name()] = hasAnyPostInDir + if hasAnyPostInDir { + hasAnyPost = true + } + } + } + } + } + return postDirs, hasAnyPost +} + +func retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) { + if strings.HasSuffix(dir, "_posts") || strings.HasSuffix(dir, "_drafts") { + isEmpty, _ := helpers.IsEmpty(dir, fs) + return true, !isEmpty + } + + if entries, err := ioutil.ReadDir(dir); err == nil { + for _, entry := range entries { + if entry.IsDir() { + subDir := filepath.Join(dir, entry.Name()) + if isPostDir, hasAnyPost := retrieveJekyllPostDir(fs, subDir); isPostDir { + return isPostDir, hasAnyPost + } + } + } + } + + return false, true +} + +func createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool, force bool) (*hugolib.Site, error) { s, err := hugolib.NewSiteDefaultLang() if err != nil { return nil, err } fs := s.Fs.Source - if exists, _ := helpers.Exists(targetDir, fs); exists { if isDir, _ := helpers.IsDir(targetDir, fs); !isDir { return nil, errors.New("Target path \"" + targetDir + "\" already exists but not a directory") @@ -159,24 +212,6 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) (*hugolib.Si jekyllConfig := loadJekyllConfig(fs, jekyllRoot) - // Crude test to make sure at least one of _drafts/ and _posts/ exists - // and is not empty. - hasPostsOrDrafts := false - postsDir := filepath.Join(jekyllRoot, "_posts") - draftsDir := filepath.Join(jekyllRoot, "_drafts") - for _, d := range []string{postsDir, draftsDir} { - if exists, _ := helpers.Exists(d, fs); exists { - if isDir, _ := helpers.IsDir(d, fs); isDir { - if isEmpty, _ := helpers.IsEmpty(d, fs); !isEmpty { - hasPostsOrDrafts = true - } - } - } - } - if !hasPostsOrDrafts { - return nil, errors.New("Your Jekyll root contains neither posts nor drafts, aborting.") - } - mkdir(targetDir, "layouts") mkdir(targetDir, "content") mkdir(targetDir, "archetypes") @@ -186,7 +221,7 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) (*hugolib.Si createConfigFromJekyll(fs, targetDir, "yaml", jekyllConfig) - copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static")) + copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"), jekyllPostDirs) return s, nil } @@ -318,7 +353,7 @@ func copyDir(source string, dest string) error { return nil } -func copyJekyllFilesAndFolders(jekyllRoot string, dest string) error { +func copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) { fi, err := os.Stat(jekyllRoot) if err != nil { return err @@ -336,9 +371,11 @@ func copyJekyllFilesAndFolders(jekyllRoot string, dest string) error { dfp := filepath.Join(dest, entry.Name()) if entry.IsDir() { if entry.Name()[0] != '_' && entry.Name()[0] != '.' { - err = copyDir(sfp, dfp) - if err != nil { - jww.ERROR.Println(err) + if _, ok := jekyllPostDirs[entry.Name()]; !ok { + err = copyDir(sfp, dfp) + if err != nil { + jww.ERROR.Println(err) + } } } } else { -- 2.30.2