Skip to content

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.

go doc 'time.Now'

returned the following:

package time // import "time"

func Now() Time
    Now returns the current local time.

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:

go install golang.org/x/tools/cmd/godoc@latest
godoc --http 127.0.0.1:3030

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:

func (t Time) Date() (year int, month Month, day int)

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
}