Compare commits

...

11 Commits
v0.1.8 ... main

Author SHA1 Message Date
Nick Dumas e95c747899 restructuring subcommands for hugo tooling
continuous-integration/drone/tag Build is passing Details
2 years ago
Nick Dumas add10c2d1a Hugo bundle directory scaffolding
continuous-integration/drone/tag Build is passing Details
2 years ago
Nick Dumas 0dda41e3f8 Namespacing your viper binds is important 2 years ago
Nick Dumas b631b717b6 debugging viper 2 years ago
Nick Dumas 93fa411750 saving my work 2 years ago
Nick Dumas 4f76a1d571 First step: inventory posts in provided directory 2 years ago
Nick Dumas 94701a01b2 Cleaning up dockerfile 2 years ago
Nick Dumas 3252693509 more hugo command drafting 2 years ago
Nick Dumas 7271830829 drafting the hugo subcommand 2 years ago
Nick Dumas cff10a36ca starting on hugo command 2 years ago
Nick Dumas f479ba4d4c Proper error handling for the walkfunc
continuous-integration/drone/tag Build is passing Details
2 years ago

@ -1,24 +1,3 @@
DOCKER_CMD=docker --config ~/.docker/
.PHONY: docker
docker: docker-image docker-push
.PHONY: docker-push
docker-push:
$(DOCKER_CMD) tag code.ndumas.com/ndumas/obsidian-pipeline:$(VERSION) code.ndumas.com/ndumas/obsidian-pipeline:latest
$(DOCKER_CMD) push code.ndumas.com/ndumas/obsidian-pipeline:latest
$(DOCKER_CMD) push code.ndumas.com/ndumas/obsidian-pipeline:$(VERSION)
.PHONY: docker-image
docker-image:
$(DOCKER_CMD) build --build-arg VERSION=$(VERSION) -t code.ndumas.com/ndumas/obsidian-pipeline:$(VERSION) .
.PHONY: build-alpine
build-alpine:
# this version breaks build variable injection
# CGO_ENABLED=0 GOOS=linux go build -ldflags="buildmode=exe $(LDFLAGS) -linkmode external -w -extldflags '-static' " -o $(DISTDIR)/$(NAME)-$(VERSION)-alpine/obp cmd/obp/*.go
CGO_ENABLED=0 GOOS=linux go build -ldflags="$(LDFLAGS)" -o $(DISTDIR)/$(NAME)-$(VERSION)-alpine/obp cmd/obp/*.go
# This file is intended as a starting point for a customized makefile for a Go project. # This file is intended as a starting point for a customized makefile for a Go project.
# #
# Targets: # Targets:
@ -62,7 +41,7 @@ build-alpine:
# Parameters # Parameters
PKG = code.ndumas.com/ndumas/obsidian-pipeline PKG = code.ndumas.com/ndumas/obsidian-pipeline
NAME = obp NAME = obsidian-pipeline
DOC = README.md LICENSE DOC = README.md LICENSE
@ -109,6 +88,7 @@ ZIPCMD = zip
SHACMD = sha256sum SHACMD = sha256sum
SLOCCMD = cloc --by-file --xml --exclude-dir="vendor" --include-lang="Go" SLOCCMD = cloc --by-file --xml --exclude-dir="vendor" --include-lang="Go"
XUCMD = go2xunit XUCMD = go2xunit
DOCKER_CMD=docker --config ~/.docker/
# Dynamic Targets # Dynamic Targets
INSTALL_TARGETS := $(addprefix install-,$(CMDS)) INSTALL_TARGETS := $(addprefix install-,$(CMDS))
@ -202,6 +182,27 @@ dist: clean build
cd "$(DISTDIR)"; find . -maxdepth 1 -type f -printf "$(SHACMD) %P | tee \"./%P.sha\"\n" | sh cd "$(DISTDIR)"; find . -maxdepth 1 -type f -printf "$(SHACMD) %P | tee \"./%P.sha\"\n" | sh
$(info "Built v$(VERSION), build $(COMMIT_ID)") $(info "Built v$(VERSION), build $(COMMIT_ID)")
.PHONY: docker
docker: docker-image docker-push
.PHONY: docker-push
docker-push:
$(DOCKER_CMD) tag code.ndumas.com/ndumas/obsidian-pipeline:$(VERSION) code.ndumas.com/ndumas/obsidian-pipeline:latest
$(DOCKER_CMD) push code.ndumas.com/ndumas/obsidian-pipeline:latest
$(DOCKER_CMD) push code.ndumas.com/ndumas/obsidian-pipeline:$(VERSION)
.PHONY: docker-image
docker-image:
$(DOCKER_CMD) build --build-arg VERSION=$(VERSION) -t code.ndumas.com/ndumas/obsidian-pipeline:$(VERSION) .
.PHONY: build-alpine
build-alpine:
# this version breaks build variable injection
# CGO_ENABLED=0 GOOS=linux go build -ldflags="buildmode=exe $(LDFLAGS) -linkmode external -w -extldflags '-static' " -o $(DISTDIR)/$(NAME)-$(VERSION)-alpine/obp cmd/obp/*.go
CGO_ENABLED=0 GOOS=linux go build -ldflags="$(LDFLAGS)" -o $(DISTDIR)/$(NAME)-$(VERSION)-alpine/obp cmd/obp/*.go
debug: debug:
$(info MD=$(MD)) $(info MD=$(MD))
$(info WD=$(WD)) $(info WD=$(WD))

@ -4,40 +4,15 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
package cmd package cmd
import ( import (
// "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var (
source, target string
)
// rootCmd represents the base command when called without any subcommands
var hugoCmd = &cobra.Command{ var hugoCmd = &cobra.Command{
Use: "hugo", Use: "hugo",
Short: "convert a set of Obsidian notes into a Hugo compatible directory structure", Short: "manage your hugo blog using your vault as a source of truth",
Long: `long description`, Long: `manage your hugo blog using your vault as a source of truth`,
PreRunE: func(cmd *cobra.Command, args []string) error {
// here is where I validate arguments, open and parse config files, etc
return nil
},
} }
func init() { func init() {
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
hugoCmd.PersistentFlags().StringVar(&source, "source", "", "directory containing ready-to-publish posts")
hugoCmd.PersistentFlags().StringVar(&target, "target", "", "target Hugo directory (typically content/posts)")
// Cobra also supports local flags, which will only run
// when this action is called directly.
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
// rootCmd.SetHelpFunc(gloss.CharmHelp)
// rootCmd.SetUsageFunc(gloss.CharmUsage)
rootCmd.AddCommand(hugoCmd) rootCmd.AddCommand(hugoCmd)
} }

@ -0,0 +1,62 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"fmt"
"log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"code.ndumas.com/ndumas/obsidian-pipeline"
)
var hugoBundleCmd = &cobra.Command{
Use: "bundle",
Short: "convert a set of Obsidian notes into a Hugo compatible directory structure",
Long: `generate hugo content from your vault`,
PreRunE: func(cmd *cobra.Command, args []string) error {
// here is where I validate arguments, open and parse config files, etc
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
source := viper.GetString("hugo.source")
target := viper.GetString("hugo.target")
err := obp.CopyPosts(source, target)
if err != nil {
return fmt.Errorf("error copying posts in %q: %w", source, err)
}
err = obp.Sanitize(source)
if err != nil {
return fmt.Errorf("error sanitizing posts in %q: %w", source, err)
}
err = obp.GatherMedia(source)
if err != nil {
return fmt.Errorf("error gathering media in %q: %w", source, err)
}
return nil
},
}
func init() {
hugoBundleCmd.Flags().StringP("source", "s", "", "path to vault directory containing hugo posts")
err := viper.BindPFlag("hugo.source", hugoBundleCmd.Flags().Lookup("source"))
if err != nil {
log.Panicln("error binding viper to source flag:", err)
}
hugoBundleCmd.Flags().StringP("target", "t", "", "hugo content/ directory")
err = viper.BindPFlag("hugo.target", hugoBundleCmd.Flags().Lookup("target"))
if err != nil {
log.Panicln("error binding viper to target flag:", err)
}
hugoBundleCmd.MarkFlagsRequiredTogether("source", "target")
hugoCmd.AddCommand(hugoBundleCmd)
}

@ -25,8 +25,8 @@ var validateCmd = &cobra.Command{
Long: `Validate YAML frontmatter with jsonschema Long: `Validate YAML frontmatter with jsonschema
`, `,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
schema := viper.GetString("schema") schema := viper.GetString("validate.schema")
target := viper.GetString("target") target := viper.GetString("validate.target")
if target == "" { if target == "" {
return fmt.Errorf("target flag must not be empty") return fmt.Errorf("target flag must not be empty")
} }
@ -60,7 +60,9 @@ var validateCmd = &cobra.Command{
} }
return nil return nil
}) })
if err != nil {
return fmt.Errorf("walkfunc failed: %w", err)
}
return nil return nil
}, },
} }
@ -73,20 +75,21 @@ func init() {
validateCmd.Flags().StringP("target", "t", "", "directory containing validation targets") validateCmd.Flags().StringP("target", "t", "", "directory containing validation targets")
validateCmd.MarkFlagsRequiredTogether("schema", "target") validateCmd.MarkFlagsRequiredTogether("schema", "target")
validateCmd.PersistentFlags().StringVar(&format, "format", "markdown", "output format [markdown, json, csv]") validateCmd.PersistentFlags().StringVar(&format, "format", "markdown", "output format [markdown, json, csv]")
rootCmd.AddCommand(validateCmd)
err := viper.BindPFlag("schema", validateCmd.Flags().Lookup("schema")) err := viper.BindPFlag("schema", validateCmd.Flags().Lookup("schema"))
if err != nil { if err != nil {
log.Panicln("error binding viper to schema flag:", err) log.Panicln("error binding viper to schema flag:", err)
} }
err = viper.BindPFlag("target", validateCmd.Flags().Lookup("target")) err = viper.BindPFlag("validate.target", validateCmd.Flags().Lookup("target"))
if err != nil { if err != nil {
log.Panicln("error binding viper to target flag:", err) log.Panicln("error binding viper to target flag:", err)
} }
err = viper.BindPFlag("format", validateCmd.PersistentFlags().Lookup("format")) err = viper.BindPFlag("validate.format", validateCmd.PersistentFlags().Lookup("format"))
if err != nil { if err != nil {
log.Panicln("error binding viper to format flag:", err) log.Panicln("error binding viper to format flag:", err)
} }
rootCmd.AddCommand(validateCmd)
} }

@ -0,0 +1,92 @@
package obp
import (
"fmt"
"io"
"io/fs"
// "log"
"os"
"path/filepath"
"strings"
)
func copy(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}
func CopyPosts(src, dst string) error {
posts := make([]string, 0)
srcRoot := os.DirFS(src)
err := fs.WalkDir(srcRoot, ".", func(path string, d fs.DirEntry, err error) error {
// here's where I walk through the source directory and collect all the markdown notes
if err != nil {
return fmt.Errorf("could not walk %q: %w", path, err)
}
if d.IsDir() {
return nil
}
if strings.HasSuffix(path, ".md") {
posts = append(posts, filepath.Join(src, path))
}
return nil
})
if err != nil {
return fmt.Errorf("walkfunc failed: %w", err)
}
for _, post := range posts {
base := filepath.Base(post)
splitPostName := strings.Split(base, ".")
postName := strings.Join(splitPostName[:len(splitPostName)-1], ".")
postDir := filepath.Join(dst, postName)
err := os.MkdirAll(postDir, 0777)
if err != nil && !os.IsExist(err) {
return fmt.Errorf("error creating target directory %q: %w", dst, err)
}
_, err = copy(post, filepath.Join(postDir, "index.md"))
if err != nil {
return fmt.Errorf("error opening %q for copying: %w", post, err)
}
}
return nil
}
func Sanitize(src string) error {
return nil
}
func GatherMedia(src string) error {
return nil
}
Loading…
Cancel
Save