Go R1 Day 57
progress๐
- Did some adhoc work in this repo (the hugo repo that contains this blog) testing out Mage, which is a Go based Make alternative.
- Generated dynamic target directory for hugo posts using stringify for kebab case.
- Unexpected behavior when generating dynamic file path including date.
year, month, day := time.Now().Date()
str := stringy.New(title)
slugTitle := strings.Join([]string{string(year), string(month), string(day), str.KebabCase("?", "").ToLower()}, "-")
The output failed to handle the year, resulting in some odd \x18
path generation.
In reviewing the values from returned from time.Now().Date
, I realized it wasn't an int value being returned.
To work through the definition, I figured this would be a good chance to use the cli only to find the docs.
returned the following:
To get the source code for the function:
go doc -src 'time.Now'
go doc -src 'time.Date'
This shows the return value of Date()
is actually time
type, not int.
Still couldn't see where the multiple return parameters were defined so I ran:
Ok... Figured it out. I was looking at the func Date()
.
However, what I should have been looking at was the exported method func (Time) Date
.
This correctly shows:
I still couldn't figure this out until I tried running it in the playground.
:(fa-fas fa-play): Playground - Demonstrate Problem
./prog.go:11:37: conversion from int to string yields a string of one rune, not a string of digits (did you mean fmt.Sprint(x)?)
Runes. Strings. I know folks say it boils down to 1's and 0's, but dang it... seems like my life always boils down to strings. ๐
:(fa-fas fa-play): Playground - Fixed The Problem
Finally got it all working.
Strongly typed languages are awesome, but this type of behavior is not as easy to figure out coming from a background with dynamic languages. I
In contrast, PowerShell would be: Get-Date -Format 'yyyy'
.
Here's an example of the Mage command then to generate a blog post with a nice selection and prompt.
// calculatePostDir calculates the post directory based on the post title and the date.
func calculatePostDir(title string) string {
year, month, day := time.Now().Date()
str := stringy.New(title)
kebabTitle := str.KebabCase().ToLower()
slugTitle := strings.Join(string(year), string(month), string(day),kebabTitle, "-") ///stringy.ToKebabCase(title)
pterm.Success.Printf("Slugify Title: %s", slugTitle)
filepath := filepath.Join(contentDir, string(year), slugTitle)
pterm.Success.Printf("calculatePostDir: %s", slugTitle)
return filepath
}
Then creation of the post:
// New namespace groups the new post generatation commands.
type New mg.Namespace
// NewPost creates a new post in the Hugo format.
func (New) Post() error {
prompt := promptui.Select{
Label: "Select Type of Post j/k to navigate",
Items: []string{"100DaysOfCode", "microblog", "blog"},
}
_, result, err := prompt.Run()
if err != nil {
pterm.Success.Printf("Prompt failed %v\n", err)
return err
}
pterm.Success.Printf("New Post: [%s]", result)
promptTitle := promptui.Prompt{
Label: "Enter Title",
}
title, err := promptTitle.Run()
if err != nil {
pterm.Error.Printf("Prompt failed %v\n", err)
return err
}
// the archetype in archtytpes directory to use
var kind string
switch result {
case "100DaysOfCode":
kind = "code"
default:
kind = result
}
fileName := calculatePostDir(title)
if err := sh.RunV("hugo", "new", fileName, "--kind", kind); err != nil {
return err
}
return nil
}