Go R1 Day 57

  • 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.
1
2
3
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.

1
go doc 'time.Now'

returned the following:

1
2
3
4
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:

1
2
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:

1
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.

Playground - Demonstrate Problem

1
./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. 😆

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 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
}

Webmentions

Likes  (1) Reposts  (2)