Date Front Matter From Git with Nushell

My website sources are Markdown files, which Hugo translates to static webpage files.
I had many page files without a date.
The date is defined by setting the date front matter.
But how can I do that for 322 files en-mass?

I used Nushell to get the file creation dates from Git, and inserted the date front matter into the page files.

ls | where type == 'dir' | get name | each {|| path parse | select stem } | upsert path {|x| $"($x.stem)/index.md" } | reject stem | upsert date {|x| git log '--follow' '--diff-filter=A' '--format=%ad' '--date=iso' '--' $x.path | into datetime } | save dates.json

open dates.json | each {|x| $x.path | open --raw | str replace "\r\n+++\r\n" $"\r\ndate = \"($x.date | format date '%Y-%m-%d %H:%M:%S')\"\r\n+++\r\n" | collect | save -f $x.path }
  1. Inside all folders
  2. For index.md
  3. Use git log to determine versioned file creation date
    • --follow to follow renames
    • --diff-filter=A only file add
    • --format=%ad author date that respects --date date format and --date=iso for a well-defined date format
  4. Intermediate save in dates.json
  5. Open dates.json
  6. Open index.md
  7. Insert the date front matter before the closing +++

Querying the Git information takes a while. Inserting the date front matter took only 1.2 seconds for 322 files.

Note that this inserting before +++ only works for front matter without category/namespace blocks.

For less uniform/localized Markdown page files, there’s an opportunity to make use of the Nu glob command.


To find out which .md files do not contain date = :

glob **/*.md | where {|x| $x | open | not ($in | str contains 'date = ') } | collect | length

glob **/*.md | where {|x| $x | open | not ($in | str contains 'date = ') }

Fixups:

glob **/*.md | where {|x| $x | open | not ($in | str contains 'date = ') } | save missing.json

open missing.json | wrap path | upsert date {|x| git log '--follow' '--diff-filter=A' '--format=%ad' '--date=iso' '--' $x.path | into datetime } | save dates.json

open dates.json | each {|x| $x.path | open --raw | str replace "\r\n+++\r\n" $"\r\ndate = \"($x.date | format date '%Y-%m-%d %H:%M:%S')\"\r\n+++\r\n" | collect | save -f $x.path }

Another 120 pages fixed. :)

If you have RSS enabled, which Hugo has enabled by default, you can check the feed under /index.xml for old/minimum date values 2001. I’m using the Firefox Browser Extension RSSPreview to view it directly in Firefox.