Skip to content

feat: Implement hermit caching strategy#79

Merged
wsutina merged 10 commits intomainfrom
swipawiwat/hermit-caching
Feb 5, 2026
Merged

feat: Implement hermit caching strategy#79
wsutina merged 10 commits intomainfrom
swipawiwat/hermit-caching

Conversation

@wsutina
Copy link
Copy Markdown
Contributor

@wsutina wsutina commented Feb 3, 2026

✍️ Changes

The Hermit strategy accepts requests at /hermit/{host}/{path...} and acts as a smart router:

  1. GitHub releases (github.com + /releases/download/) are redirected to the existing github-releases strategy using an internal HTTP call with NoOpCache to avoid double caching
  2. All other sources (golang.org, npm, Maven, HashiCorp, etc.) are handled directly using the handler pattern with standard caching

🧪 Testing

GitHub releases (hermit install mk-6.0.1)

Cache miss
Screenshot 2026-02-03 at 5 20 01 pm

Cache hit
Screenshot 2026-02-03 at 4 43 25 pm

All other sources (hermit install go-1.17.3)

Cache Miss
Screenshot 2026-02-03 at 4 44 26 pm

Cache Hit
Screenshot 2026-02-03 at 4 45 55 pm

Comment thread internal/strategy/hermit.go Outdated
Comment thread internal/strategy/hermit.go Outdated
@js-murph
Copy link
Copy Markdown
Contributor

js-murph commented Feb 3, 2026

Looks great @wsutina!

Comment thread internal/strategy/hermit.go Outdated
@wsutina wsutina force-pushed the swipawiwat/hermit-caching branch from 2eeefdb to a6af831 Compare February 3, 2026 23:28
@wsutina wsutina marked this pull request as ready for review February 3, 2026 23:28
@wsutina wsutina requested a review from a team as a code owner February 3, 2026 23:28
@wsutina wsutina requested review from alecthomas, js-murph and nssherpa and removed request for a team February 3, 2026 23:28
Comment thread cachew.hcl Outdated
Comment thread internal/strategy/hermit_test.go Outdated
Comment thread internal/strategy/hermit.go Outdated
Comment thread internal/strategy/hermit.go Outdated
Comment thread internal/strategy/hermit.go Outdated
Comment thread internal/strategy/hermit.go Outdated
}

type HermitConfig struct {
BaseURL string `hcl:"base-url" help:"Base URL for internal redirects to github-releases strategy (e.g., http://localhost:8080)."`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
BaseURL string `hcl:"base-url" help:"Base URL for internal redirects to github-releases strategy (e.g., http://localhost:8080)."`
BaseURL string `hcl:"base-url" help:"Base URL for internal redirects to github-releases strategy (e.g., http://localhost:8080)." default:"${CACHEW_URL}"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we set this default, 99% of the time it won't need to be explicitly configured.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should have /github as the suffix too... I suspect that would be more flexible. ie. "${CACHEW_URL}/github"

Copy link
Copy Markdown
Contributor Author

@wsutina wsutina Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this what you mean?

My understanding is github-base-url will control where we redirect:

  • If it sets to ${CACHEW_URL}/github.com -- it will go to github-release strategy
  • If it sets to github.com -- it will go to github.com directly

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly!

Comment thread internal/strategy/hermit.go Outdated
Comment on lines +72 to +73
// redirectToGitHubReleases delegates to github-releases strategy using NoOpCache
// to avoid double caching (github-releases will cache the actual response).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaah, nice solution!

Comment thread internal/strategy/api.go Outdated
}

// expandStructStrings expands environment variables in string fields of a struct.
func expandStructStrings(v any, vars map[string]string) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for? The config package already expands envars in the HCL.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think config in envar expansion works only hcl file but not for default in struct. For example

	BaseURL string `hcl:"base-url" help:"Base URL for internal redirects to github-releases strategy" default:"$${CACHEW_URL}"`

results in

INF Hermit strategy initialized base_url=$${CACHEW_URL}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HCL library supports defaults, eg. here

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already works, you can see it used with github-release:

github-releases {
  token = "${GITHUB_TOKEN}"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The var expansion works but if we want the default to be set in the config only:

cachew.hcl

hermit { } <-- no value

hermit.go

type HermitConfig struct {
	GitHubBaseURL string `hcl:"github-base-url,optional" help:"Base URL for GitHub release redirects" default:"${CACHEW_URL}/github.com"`
}

and hcl is empty, the var expansion doesn't get called.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing the loop. To addressed this, a change is made to alecthomas/hcl#46 to accept default transformer + fa8bc7c

Comment thread internal/strategy/hermit.go Outdated
@wsutina wsutina force-pushed the swipawiwat/hermit-caching branch 2 times, most recently from 09dde54 to 62a9437 Compare February 5, 2026 06:07
@wsutina wsutina force-pushed the swipawiwat/hermit-caching branch from 62a9437 to fa8bc7c Compare February 5, 2026 06:10
@wsutina wsutina merged commit 1b643fa into main Feb 5, 2026
5 checks passed
@wsutina wsutina deleted the swipawiwat/hermit-caching branch February 5, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants