Skip to content

Commit 7ee1f25

Browse files
coderzhbep
authored andcommitted
hugo import jekyll support nested _posts directories
Fixes #1890 Closes #1911
1 parent 3aa0e16 commit 7ee1f25

File tree

1 file changed

+73
-36
lines changed

1 file changed

+73
-36
lines changed

‎commands/import_jekyll.go‎

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,17 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
8484
}
8585

8686
forceImport, _ := cmd.Flags().GetBool("force")
87-
site, err := createSiteFromJekyll(jekyllRoot, targetDir, forceImport)
87+
88+
fs := afero.NewOsFs()
89+
jekyllPostDirs, hasAnyPost := getJekyllDirInfo(fs, jekyllRoot)
90+
if !hasAnyPost {
91+
return errors.New("Your Jekyll root contains neither posts nor drafts, aborting.")
92+
}
93+
94+
site, err := createSiteFromJekyll(jekyllRoot, targetDir, jekyllPostDirs, forceImport)
95+
8896
if err != nil {
89-
return err
97+
return newUserError(err)
9098
}
9199

92100
jww.FEEDBACK.Println("Importing...")
@@ -110,10 +118,10 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
110118
draft := false
111119

112120
switch {
113-
case strings.HasPrefix(relPath, "_posts/"):
114-
relPath = "content/post" + relPath[len("_posts"):]
115-
case strings.HasPrefix(relPath, "_drafts/"):
116-
relPath = "content/draft" + relPath[len("_drafts"):]
121+
case strings.Contains(relPath, "_posts/"):
122+
relPath = filepath.Join("content/post", strings.Replace(relPath, "_posts/", "", -1))
123+
case strings.Contains(relPath, "_drafts/"):
124+
relPath = filepath.Join("content/draft", strings.Replace(relPath, "_drafts/", "", -1))
117125
draft = true
118126
default:
119127
return nil
@@ -123,11 +131,19 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
123131
return convertJekyllPost(site, path, relPath, targetDir, draft)
124132
}
125133

126-
err = helpers.SymbolicWalk(hugofs.Os, jekyllRoot, callback)
127-
128-
if err != nil {
129-
return err
134+
for jekyllPostDir, hasAnyPostInDir := range jekyllPostDirs {
135+
if hasAnyPostInDir {
136+
if err = helpers.SymbolicWalk(hugofs.Os, filepath.Join(jekyllRoot, jekyllPostDir), callback); err != nil {
137+
return err
138+
}
139+
}
130140
}
141+
142+
jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!")
143+
jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" +
144+
"$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove")
145+
jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
146+
131147
jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!")
132148
jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" +
133149
"$ 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 {
136152
return nil
137153
}
138154

139-
// TODO: Consider calling doNewSite() instead?
140-
func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) (*hugolib.Site, error) {
155+
func getJekyllDirInfo(fs afero.Fs, jekyllRoot string) (map[string]bool, bool) {
156+
postDirs := make(map[string]bool)
157+
hasAnyPost := false
158+
if entries, err := ioutil.ReadDir(jekyllRoot); err == nil {
159+
for _, entry := range entries {
160+
if entry.IsDir() {
161+
subDir := filepath.Join(jekyllRoot, entry.Name())
162+
if isPostDir, hasAnyPostInDir := retrieveJekyllPostDir(fs, subDir); isPostDir {
163+
postDirs[entry.Name()] = hasAnyPostInDir
164+
if hasAnyPostInDir {
165+
hasAnyPost = true
166+
}
167+
}
168+
}
169+
}
170+
}
171+
return postDirs, hasAnyPost
172+
}
173+
174+
func retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) {
175+
if strings.HasSuffix(dir, "_posts") || strings.HasSuffix(dir, "_drafts") {
176+
isEmpty, _ := helpers.IsEmpty(dir, fs)
177+
return true, !isEmpty
178+
}
179+
180+
if entries, err := ioutil.ReadDir(dir); err == nil {
181+
for _, entry := range entries {
182+
if entry.IsDir() {
183+
subDir := filepath.Join(dir, entry.Name())
184+
if isPostDir, hasAnyPost := retrieveJekyllPostDir(fs, subDir); isPostDir {
185+
return isPostDir, hasAnyPost
186+
}
187+
}
188+
}
189+
}
190+
191+
return false, true
192+
}
193+
194+
func createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool, force bool) (*hugolib.Site, error) {
141195
s, err := hugolib.NewSiteDefaultLang()
142196
if err != nil {
143197
return nil, err
144198
}
145199

146200
fs := s.Fs.Source
147-
148201
if exists, _ := helpers.Exists(targetDir, fs); exists {
149202
if isDir, _ := helpers.IsDir(targetDir, fs); !isDir {
150203
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
159212

160213
jekyllConfig := loadJekyllConfig(fs, jekyllRoot)
161214

162-
// Crude test to make sure at least one of _drafts/ and _posts/ exists
163-
// and is not empty.
164-
hasPostsOrDrafts := false
165-
postsDir := filepath.Join(jekyllRoot, "_posts")
166-
draftsDir := filepath.Join(jekyllRoot, "_drafts")
167-
for _, d := range []string{postsDir, draftsDir} {
168-
if exists, _ := helpers.Exists(d, fs); exists {
169-
if isDir, _ := helpers.IsDir(d, fs); isDir {
170-
if isEmpty, _ := helpers.IsEmpty(d, fs); !isEmpty {
171-
hasPostsOrDrafts = true
172-
}
173-
}
174-
}
175-
}
176-
if !hasPostsOrDrafts {
177-
return nil, errors.New("Your Jekyll root contains neither posts nor drafts, aborting.")
178-
}
179-
180215
mkdir(targetDir, "layouts")
181216
mkdir(targetDir, "content")
182217
mkdir(targetDir, "archetypes")
@@ -186,7 +221,7 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) (*hugolib.Si
186221

187222
createConfigFromJekyll(fs, targetDir, "yaml", jekyllConfig)
188223

189-
copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"))
224+
copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"), jekyllPostDirs)
190225

191226
return s, nil
192227
}
@@ -318,7 +353,7 @@ func copyDir(source string, dest string) error {
318353
return nil
319354
}
320355

321-
func copyJekyllFilesAndFolders(jekyllRoot string, dest string) error {
356+
func copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) {
322357
fi, err := os.Stat(jekyllRoot)
323358
if err != nil {
324359
return err
@@ -336,9 +371,11 @@ func copyJekyllFilesAndFolders(jekyllRoot string, dest string) error {
336371
dfp := filepath.Join(dest, entry.Name())
337372
if entry.IsDir() {
338373
if entry.Name()[0] != '_' && entry.Name()[0] != '.' {
339-
err = copyDir(sfp, dfp)
340-
if err != nil {
341-
jww.ERROR.Println(err)
374+
if _, ok := jekyllPostDirs[entry.Name()]; !ok {
375+
err = copyDir(sfp, dfp)
376+
if err != nil {
377+
jww.ERROR.Println(err)
378+
}
342379
}
343380
}
344381
} else {

0 commit comments

Comments
 (0)