repo-sync/mirror/options.go
James Coleman 14cf482549
Some checks are pending
Go package / build (push) Waiting to run
first commit
2026-07-27 14:16:32 -05:00

91 lines
2.7 KiB
Go

// Package mirror synchronizes remote package repositories into a local
// directory tree, preserving the upstream layout so the result can be
// served directly to package managers.
package mirror
import (
"net/url"
"path"
"strings"
"time"
"github.com/grmrgecko/repo-sync/fetch"
)
// RepoType identifies the repository format being synchronized.
type RepoType string
const (
// RepoRPM synchronizes yum/dnf style repositories.
RepoRPM RepoType = "rpm"
// RepoDeb synchronizes apt style repositories.
RepoDeb RepoType = "deb"
// RepoArch synchronizes pacman style repositories.
RepoArch RepoType = "arch"
// RepoApk synchronizes Alpine apk style repositories.
RepoApk RepoType = "apk"
)
// Options configures a synchronization run.
type Options struct {
// Type selects the repository format.
Type RepoType
// URLs lists the repository or mirrorlist URLs to synchronize.
URLs []string
// Destination is the local directory repositories are placed under.
Destination string
// Trim drops this many leading URL path components when building the
// destination path.
Trim int
// Flat places repositories directly in Destination without copying the
// URL path.
Flat bool
// Discover crawls each URL's directory listings for repositories.
Discover bool
// DiscoverDepth limits how deep discovery crawls below each URL.
DiscoverDepth int
// Workers is the number of concurrent download workers.
Workers int
// Verify re-verifies checksums of existing local files.
Verify bool
// Prune deletes local files no longer part of the repository.
Prune bool
// PruneGrace defers pruning a file until it has been unreferenced for
// this long across runs.
PruneGrace time.Duration
// DryRun reports what would change without downloading packages or
// altering the published repository.
DryRun bool
// destBase, when set by the mirror server, pins the repository root
// directory directly instead of deriving it from the URL path.
destBase string
// Components limits deb synchronization to these components.
Components []string
// Architectures limits deb synchronization to these architectures.
Architectures []string
}
// repoDest maps a repository URL onto the destination directory according
// to the configured trimming rules.
func (o *Options) repoDest(repoURL string) (string, error) {
if o.destBase != "" {
return o.destBase, nil
}
if o.Flat {
return o.Destination, nil
}
u, err := url.Parse(repoURL)
if err != nil {
return "", err
}
var segs []string
for _, seg := range strings.Split(u.Path, "/") {
if seg != "" {
segs = append(segs, seg)
}
}
if o.Trim >= len(segs) {
return o.Destination, nil
}
return fetch.LocalJoin(o.Destination, path.Join(segs[o.Trim:]...))
}