Skip to content

Add Page.GitInfo support for content mounted from other GitHub repos #14431

@bep

Description

@bep

This is somewhat related to #5533.

Creating a version site example using Go Modules version queries to import different versions of the same GitHub repo content into the same site, I was mostly really happy with how it turned out, see
https://github.com/bep/hugo-testing-git-versions

But for these use cases, I think many value having .Page.GitInfo to print version info + last commit message etc.

While that actually works in the example above (because it imports itself), it fails in some very common cases:

  • Having content stored in a separate GitHub repo.
  • Having content spread out into multiple GitHub repos.

I have restricted this first iteration to GitHub only, but if this works, we can add some of the other popular ones.

This is an example of the information we have for a downloaded Hugo Module:

{
	"Path": "github.com/bep/hugo-testing-git-versions",
	"Version": "v3.0.1+incompatible",
	"Query": "\u003cv4.0.0",
	"Info": "/Users/bep/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/cache/download/github.com/bep/hugo-testing-git-versions/@v/v3.0.1+incompatible.info",
	"GoMod": "/Users/bep/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/cache/download/github.com/bep/hugo-testing-git-versions/@v/v3.0.1+incompatible.mod",
	"Zip": "/Users/bep/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/cache/download/github.com/bep/hugo-testing-git-versions/@v/v3.0.1+incompatible.zip",
	"Dir": "/Users/bep/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/bep/[email protected]+incompatible",
	"Sum": "h1:Szd59GuESt7Oe9Qm6Or59J012xdjrSFBj59vl0sfobA=",
	"GoModSum": "h1:Jd6Vz6328GvDOM6Jano/Kywt2EOo+a8C2xOlPCLIlDM=",
	"Origin": {
		"VCS": "git",
		"URL": "https://github.com/bep/hugo-testing-git-versions",
		"Hash": "3e0f3930f1ec9a29a7442da5f1bfc0b7e58f167a",
		"TagSum": "t1:LsA8ttFO7sEn4AQZHyrljn1DE2YXbCZ4HNynFYEVUoA=",
		"Ref": "refs/tags/v3.0.1"
	}
}

This is the struct we return in .Page.GitInfo:

type GitInfo struct {
	Hash            string    `json:"hash"`            // Commit hash
	AbbreviatedHash string    `json:"abbreviatedHash"` // Abbreviated commit hash
	Subject         string    `json:"subject"`         // The commit message's subject/title line
	AuthorName      string    `json:"authorName"`      // The author name, respecting .mailmap
	AuthorEmail     string    `json:"authorEmail"`     // The author email address, respecting .mailmap
	AuthorDate      time.Time `json:"authorDate"`      // The author date
	CommitDate      time.Time `json:"commitDate"`      // The commit date
	Body            string    `json:"body"`            // The commit message body
	Parent          *GitInfo  `json:"-"`               // The file-filtered ancestor commit, if any
}

For this use case, we can use the Origin:

  • If VCS is git and URL starts with https://github.com/ load and cache the commit history of the given repo. Cache it to disk in a new cache called modulegitinfo as sibling to modulequeries, maxAge=24h.
  • Using the Hash we should be able to then construct a GitInfo object.
  • I think it makes sense to follow the same basic strategy used when reading git log on disk: Read it into a map on first access, but note: There may be multiple versions of the same file (different Hash) and also potentially multiple GitHub repos.
  • It should be possible to resolve the repo-relative filename by trimming ´.Dirfrom.Page.File.Filename`.
  • I don't think the module info above is exposed, but that should not be too hard; but I don't want all that info available to the end user, so make an internal func or something (we do have some module info on .Page.File so the wring of this is prepared).

I suspect that we need to pass a Bearer token to GitHub to make this work. I don't want us to whitelist GITHUB_TOKEN so I suggest we look for a HUGO_GITHUB_TOKEN.

Since we probably want to add e.g. GitLab to the mix soonish, the implementation needs to leave room for that. I suggest adding this to ./hugolib/gitinfo.

Note that we will still respect the enableGitInfo setting.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions