assets

package
v1.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package assets implements L2: download → sha256 verify → cache → extract. Features: mirror fallback chain, same-origin HTTP Range resume for the 420MB model, size/magic integrity gate, zip-slip rejection and protected-file extraction rules (§5.3).

Index

Constants

This section is empty.

Variables

View Source
var ResolveStableTag = func(ctx context.Context) string {
	m := &Manager{}
	for _, u := range stableTagCandidates(releasesAPIURL) {
		req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
		if err != nil {
			continue
		}
		req.Header.Set("Accept", "application/vnd.github+json")
		req.Header.Set("User-Agent", "ompinyin/"+catalog.Version)
		resp, err := m.client().Do(req)
		if err != nil {
			continue
		}
		var releases []releaseInfo
		err = json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&releases)
		resp.Body.Close()
		if err != nil {
			continue
		}
		for _, r := range releases {
			if r.Draft || r.Prerelease || r.TagName == "" || r.TagName == "nightly" {
				continue
			}
			return r.TagName
		}
	}
	return ""
}

ResolveStableTag resolves the newest STABLE release tag of rime-ice via the releases API (catalog.RimeIceReleasesAPI, newest first; the rolling nightly release is tagged "nightly" and skipped). Best-effort: tries the API directly, then via the ghproxy accelerators (CN reachability); returns "" when resolution is impossible — callers must fall back to the unpinned releases/latest form. Verified against the live API: the list is ordered newest-first and its first non-nightly entry is the latest stable tag.

Package var so T0 tests can stub it (CI must never touch the network).

Functions

func CacheDir

func CacheDir() string

CacheDir is ~/.cache/ompinyin (respects XDG_CACHE_HOME; OMPINYIN_TEST_HOME takes precedence for hermetic tests).

Types

type Manager

type Manager struct {
	HTTP           *http.Client
	MirrorOverride string               // --mirror <URL>: single custom URL for the asset
	LocalDir       string               // --mirror <dir>: offline asset directory (no HTTP)
	MirrorSource   catalog.MirrorSource // --mirror <preset>: named download policy
	Logf           func(format string, args ...any)
}

Manager downloads and extracts assets.

func (*Manager) ExtractZip

func (m *Manager) ExtractZip(zipPath, destDir string, overwrite bool) (extracted, skipped []string, err error)

ExtractZip extracts zipPath into destDir following the L2 rules:

  • zip-slip rejected (.. or absolute paths)
  • same-name *.custom.yaml skipped with a warning (managed-file guard)
  • user.yaml / installation.yaml / *.userdb / custom_phrase.txt NEVER overwritten (even with overwrite=true)
  • with overwrite=false (plain install): any existing file is skipped — a converged host re-run must not rewrite the whole data dir (P1-1b); with overwrite=true (update): existing non-protected files are refreshed

func (*Manager) Fetch

func (m *Manager) Fetch(ctx context.Context, a catalog.Asset, hintTag, hintSHA string) (string, string, string, error)

Fetch ensures the asset is present in the cache and verified. hintTag/hintSHA come from the state ledger. A cache hit avoids any network round-trip; when a hint SHA is known it is re-verified against the cached bytes so a corrupted/tampered cache cannot silently pass. Returns (cachePath, sha256hex, tag).

Cache keys are per-tag (channelName suffixes the pinned tag), so the stable and nightly builds never collide in the cache (P2-4).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL