mirror of
https://github.com/facundoolano/jorge.git
synced 2024-11-16 07:47:40 +01:00
adb17ad9d2
* run linter in github actions * try fixing go mod * no install go * again * maybe this? * separate install * no v * fix lint errors
120 lines
3 KiB
Go
120 lines
3 KiB
Go
package commands
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"io"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/alecthomas/kong"
|
|
"github.com/facundoolano/jorge/site"
|
|
)
|
|
|
|
//go:embed all:initfiles
|
|
var initfiles embed.FS
|
|
|
|
var INIT_CONFIG string = `name: "%s"
|
|
author: "%s"
|
|
url: "%s"
|
|
`
|
|
var INIT_README string = `
|
|
# %s
|
|
|
|
A jorge blog by %s.
|
|
`
|
|
|
|
type Init struct {
|
|
ProjectDir string `arg:"" name:"path" help:"Directory where to initialize the website project."`
|
|
}
|
|
|
|
// Initialize a new jorge project in the given directory,
|
|
// prompting for basic site config and creating default files.
|
|
func (cmd *Init) Run(ctx *kong.Context) error {
|
|
if err := ensureEmptyProjectDir(cmd.ProjectDir); err != nil {
|
|
return err
|
|
}
|
|
|
|
siteName := Prompt("site name")
|
|
siteUrl := Prompt("site url")
|
|
siteAuthor := Prompt("author")
|
|
fmt.Println()
|
|
|
|
// creating config and readme files manually, since I want to use the supplied config values in their
|
|
// contents. (I don't want to render liquid templates in the WalkDir below since some of the initfiles
|
|
// are actual templates that should be left as is).
|
|
configPath := filepath.Join(cmd.ProjectDir, "config.yml")
|
|
configFile := fmt.Sprintf(INIT_CONFIG, siteName, siteAuthor, siteUrl)
|
|
os.WriteFile(configPath, []byte(configFile), site.FILE_RW_MODE)
|
|
fmt.Println("added", configPath)
|
|
|
|
readmePath := filepath.Join(cmd.ProjectDir, "README.md")
|
|
readmeFile := fmt.Sprintf(INIT_README, siteName, siteAuthor)
|
|
os.WriteFile(readmePath, []byte(readmeFile), site.FILE_RW_MODE)
|
|
fmt.Println("added", readmePath)
|
|
|
|
// walk over initfiles fs
|
|
// copy create directories and copy files at target
|
|
|
|
initfilesRoot := "initfiles"
|
|
return fs.WalkDir(initfiles, initfilesRoot, func(path string, entry fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if path == initfilesRoot {
|
|
return nil
|
|
}
|
|
subpath, _ := filepath.Rel(initfilesRoot, path)
|
|
targetPath := filepath.Join(cmd.ProjectDir, subpath)
|
|
|
|
// if it's a directory create it at the same location
|
|
if entry.IsDir() {
|
|
return os.MkdirAll(targetPath, DIR_RWE_MODE)
|
|
}
|
|
|
|
// TODO duplicated in site, extract to somewhere else
|
|
// if its a file, copy it over
|
|
targetFile, err := os.Create(targetPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer targetFile.Close()
|
|
|
|
source, err := initfiles.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer source.Close()
|
|
|
|
_, err = io.Copy(targetFile, source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println("added", targetPath)
|
|
return targetFile.Sync()
|
|
})
|
|
}
|
|
|
|
func ensureEmptyProjectDir(projectDir string) error {
|
|
if err := os.Mkdir(projectDir, DIR_RWE_MODE); err != nil {
|
|
// if it fails with dir already exist, check if it's empty
|
|
// https://stackoverflow.com/a/30708914/993769
|
|
if os.IsExist(err) {
|
|
// check if empty
|
|
dir, err := os.Open(projectDir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dir.Close()
|
|
|
|
// if directory is non empty, fail
|
|
_, err = dir.Readdirnames(1)
|
|
if err == nil {
|
|
return fmt.Errorf("non empty directory %s", projectDir)
|
|
}
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|