Feat: Add support for 'build: true' tag in frontmatter

This feature allows triggering the execution of the `build_action` command specified in
the `.ini` file when adding `build: true` to the frontmatter of the modified file. Upon
detecting this tag, the specified command will be executed automatically, facilitating
the automation of build processes in response to specific file modifications
main
Óscar M. Lage 2024-04-10 12:02:42 +02:00
parent af371dd02a
commit 6a56a2f9f2
3 changed files with 124 additions and 0 deletions

View File

@ -15,6 +15,7 @@ Configuration runs in `~/.config/obs2hugo/obs2hugo.ini` or `~/.config/obs2hugo.i
```ini
watcher_dirs = /Users/johndoe/vaults/obsidian/microposts-hugo:/Users/johndoe/vaults/obsidian/posts-hugo
hugo_dirs = /Users/johndoe/code/hugo/src/content/posts:/Users/johndoe/code/hugo/src/content/microposts
build_action = hugo build
```
Note: The `watcher_dirs` and `hugo_dirs` variables must have the same number of elements, taking into account that `:` acts as a separator. They are correlated so the first element in `watcher_dirs` corresponds to the first element in `hugo_dirs`, the second element in `watcher_dirs` corresponds to the second element in `hugo_dirs`, and so forth.
@ -29,6 +30,8 @@ Note: The `watcher_dirs` and `hugo_dirs` variables must have the same number of
$ go run main.go
```
If you add `build: true` in the frontmatter of the file you are modifying, it will force the execution of the `build_action` command specified in the `.ini` file.
## Requirements
- Go installed on your system.

120
main.go
View File

@ -8,6 +8,7 @@ import (
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
@ -32,6 +33,9 @@ func main() {
log.Fatalln(err)
}
}
// Hugo build action
buildAction := config.Section("").Key("build_action").String()
// Watcher directories
watcherDirs := config.Section("").Key("watcher_dirs").String()
@ -93,6 +97,28 @@ func main() {
continue
}
processModifiedFile(event.Name, triggerDir, newDestDir)
// Check if the file contains the "build: true" tag in the frontmatter
hasBuildTag, err := hasBuildTag(event.Name)
if err != nil {
fmt.Println("Error checking build tag in frontmatter:", err)
continue
}
// If the file contains the "build: true" tag, execute the build action specified in the .ini file
if hasBuildTag && buildAction != "" {
// Remove the "build: true" tag from the frontmatter
err = removeBuildTag(event.Name)
if err != nil {
fmt.Println("Error removing build tag from frontmatter:", err)
return
}
// Execute build action
err := executeBuildAction(buildAction)
if err != nil {
fmt.Println("Error executing build action:", err)
continue
}
}
case event.Op&fsnotify.Remove == fsnotify.Remove:
fmt.Println("File deleted:", event.Name)
// TBD
@ -217,6 +243,65 @@ func addFrontmatter(filePath, title string) error {
return nil
}
// Function to check if the file contains the "build: true" tag in the frontmatter
func hasBuildTag(filePath string) (bool, error) {
// Open the file
file, err := os.Open(filePath)
if err != nil {
return false, err
}
defer file.Close()
// Read the file line by line
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// Check for the start of the frontmatter
if line == "---" {
var frontmatter []string
// Read the frontmatter
for scanner.Scan() {
line := scanner.Text()
if line == "---" {
break
}
frontmatter = append(frontmatter, line)
}
// Check if the frontmatter contains the "build: true" tag
for _, tag := range frontmatter {
if strings.Contains(tag, "build: true") {
return true, nil
}
}
break // We're done checking frontmatter, so break out of the loop
}
}
return false, nil
}
// Function to execute the build action specified in the .ini file
func executeBuildAction(action string) error {
// Split the action into command and arguments
parts := strings.Fields(action)
cmd := parts[0]
args := parts[1:]
// Execute the command
out, err := exec.Command(cmd, args...).Output()
if err != nil {
return err
}
// Print the command output
fmt.Println(string(out))
return nil
}
func copyFile(src, dst string) error {
sourceFile, err := os.Open(src)
if err != nil {
@ -237,6 +322,41 @@ func copyFile(src, dst string) error {
return nil
}
func removeBuildTag(filePath string) error {
// Read file content
content, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
contentStr := string(content)
// Find frontmatter
start := strings.Index(contentStr, "---")
end := strings.Index(contentStr[start+3:], "---")
// Verify if frontmatter exists
if start != -1 && end != -1 {
frontmatter := contentStr[start : start+3+end+3]
// Look for "build: true" in the frontmatter
buildTagIndex := strings.Index(frontmatter, "build: true")
if buildTagIndex != -1 {
// Delete "build: true" from frontmatter
frontmatter = strings.ReplaceAll(frontmatter, "build: true\n", "")
contentStr = strings.Replace(contentStr, string(content[start:start+3+end+3]), frontmatter, 1)
err := ioutil.WriteFile(filePath, []byte(contentStr), 0644)
if err != nil {
return err
}
}
}
return nil
}
func moveImagesToGallery(filePath, destDir, directory string) error {
// Routes
destFilePath := filepath.Join(destDir, "index.md")

View File

@ -4,3 +4,4 @@
watcher_dirs = /Users/johndoe/vaults/obsidian/microposts-hugo:/Users/johndoe/vaults/obsidian/posts-hugo
hugo_dirs = /Users/johndoe/code/hugo/src/content/posts:/Users/johndoe/code/hugo/src/content/microposts
build_action = hugo build