diff options
author | Alan Pearce | 2024-05-14 17:24:31 +0200 |
---|---|---|
committer | Alan Pearce | 2024-05-14 17:24:31 +0200 |
commit | df3b6bfd571c38aa7099838aa43bb3aff0eff2bf (patch) | |
tree | 5695d3a1d537b3456c13b60b0bb10a444ad39089 | |
parent | 5f9c7ef00b1ed56fb1abbade4d5dbc3041acd4fc (diff) | |
download | searchix-df3b6bfd571c38aa7099838aa43bb3aff0eff2bf.tar.lz searchix-df3b6bfd571c38aa7099838aa43bb3aff0eff2bf.tar.zst searchix-df3b6bfd571c38aa7099838aa43bb3aff0eff2bf.zip |
feat: add DownloadOptions importer (fetches pre-built options.json)
-rw-r--r-- | internal/config/source.go | 5 | ||||
-rw-r--r-- | internal/importer/download-options.go | 87 | ||||
-rw-r--r-- | internal/importer/importer.go | 14 | ||||
-rw-r--r-- | internal/importer/main.go | 2 |
4 files changed, 108 insertions, 0 deletions
diff --git a/internal/config/source.go b/internal/config/source.go index 2b1b440..28451e3 100644 --- a/internal/config/source.go +++ b/internal/config/source.go @@ -13,6 +13,7 @@ const ( Unknown = iota Channel ChannelNixpkgs + DownloadOptions ) func (f Type) String() string { @@ -21,6 +22,8 @@ func (f Type) String() string { return "channel" case ChannelNixpkgs: return "channel-nixpkgs" + case DownloadOptions: + return "download-options" } return fmt.Sprintf("Fetcher(%d)", f) @@ -32,6 +35,8 @@ func parseType(name string) (Type, error) { return Channel, nil case "channel-nixpkgs": return ChannelNixpkgs, nil + case "download-options": + return DownloadOptions, nil default: return Unknown, fmt.Errorf("unsupported fetcher %s", name) } diff --git a/internal/importer/download-options.go b/internal/importer/download-options.go new file mode 100644 index 0000000..6727138 --- /dev/null +++ b/internal/importer/download-options.go @@ -0,0 +1,87 @@ +package importer + +import ( + "bytes" + "context" + "log/slog" + "net/url" + "os" + "path" + "searchix/internal/config" + "searchix/internal/file" + "searchix/internal/index" + + "github.com/pkg/errors" +) + +type DownloadOptionsImporter struct { + DataPath string + Source *config.Source + SourceFile string + Logger *slog.Logger +} + +var optionsFiles = map[string]string{ + "revision": "revision", + "options": "options.json", +} + +func (i *DownloadOptionsImporter) FetchIfNeeded(parent context.Context) (bool, error) { + ctx, cancel := context.WithTimeout(parent, i.Source.FetchTimeout) + defer cancel() + + root := i.DataPath + + err := file.Mkdirp(root) + if err != nil { + return false, errors.WithMessagef(err, "error creating directory for data: %s", root) + } + + var updated bool + for _, filename := range optionsFiles { + url, err := url.JoinPath(i.Source.URL, filename) + if err != nil { + return false, errors.WithMessagef( + err, + "could not build URL with elements %s and %s", + i.Source.URL, + filename, + ) + } + + path := path.Join(root, filename) + + i.Logger.Debug("preparing to fetch URL", "url", url, "path", path) + + updated, err = fetchFileIfNeeded(ctx, path, url) + if err != nil { + return false, err + } + // don't bother to issue requests for the later files + if !updated { + return false, err + } + } + + return updated, nil +} + +func (i *DownloadOptionsImporter) Import( + parent context.Context, + indexer *index.WriteIndex, +) (bool, error) { + filename := path.Join(i.DataPath, optionsFiles["options"]) + revFilename := path.Join(i.DataPath, optionsFiles["revision"]) + bits, err := os.ReadFile(revFilename) + if err != nil { + return false, errors.WithMessagef(err, "unable to read revision file at %s", revFilename) + } + i.Source.Repo.Revision = string(bytes.TrimSpace(bits)) + i.Logger.Debug("preparing import run", "revision", i.Source.Repo.Revision, "filename", filename) + + return processOptions(parent, indexer, &importConfig{ + Source: i.Source, + Filename: filename, + Logger: i.Logger, + }) +} diff --git a/internal/importer/importer.go b/internal/importer/importer.go index b66b6d3..c50a72b 100644 --- a/internal/importer/importer.go +++ b/internal/importer/importer.go @@ -42,6 +42,20 @@ func NewChannelImporter( } } +func NewDownloadOptionsImporter( + source *config.Source, + dataPath string, + logger *slog.Logger, +) *DownloadOptionsImporter { + fullpath := path.Join(dataPath, source.Channel) + + return &DownloadOptionsImporter{ + DataPath: fullpath, + Source: source, + Logger: logger, + } +} + type importConfig struct { Filename string Source *config.Source diff --git a/internal/importer/main.go b/internal/importer/main.go index 2d87e33..0b7a99d 100644 --- a/internal/importer/main.go +++ b/internal/importer/main.go @@ -34,6 +34,8 @@ func Start(cfg *config.Config, indexer *index.WriteIndex, replace bool) error { imp = NewNixpkgsChannelImporter(source, importerDataPath, logger) case config.Channel: imp = NewChannelImporter(source, importerDataPath, logger) + case config.DownloadOptions: + imp = NewDownloadOptionsImporter(source, importerDataPath, logger) default: log.Printf("unsupported importer type %s", source.Type.String()) |