about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlan Pearce2024-05-06 17:30:43 +0200
committerAlan Pearce2024-05-07 14:01:30 +0200
commit8c1332020d25f74baa463bb1cec0e6783f565034 (patch)
treecd770b758b2538b79c5f0ddf7187b2cd61380f8d
parentc0fbf11f843af84e8891a708c4d217dd6c523473 (diff)
downloadsearchix-8c1332020d25f74baa463bb1cec0e6783f565034.tar.lz
searchix-8c1332020d25f74baa463bb1cec0e6783f565034.tar.zst
searchix-8c1332020d25f74baa463bb1cec0e6783f565034.zip
feat: link to exact commits in NixOS/nixpkgs
-rw-r--r--data/processed/.keep0
-rw-r--r--data/raw/.keep0
-rw-r--r--internal/options/process.go55
-rw-r--r--justfile35
-rw-r--r--process/main.go18
-rw-r--r--shell.nix1
6 files changed, 100 insertions, 9 deletions
diff --git a/data/processed/.keep b/data/processed/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/data/processed/.keep
diff --git a/data/raw/.keep b/data/raw/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/data/raw/.keep
diff --git a/internal/options/process.go b/internal/options/process.go
index 9721a7b..f15757a 100644
--- a/internal/options/process.go
+++ b/internal/options/process.go
@@ -2,9 +2,12 @@ package options
 
 import (
 	"encoding/json"
+	"fmt"
 	"io"
 	"log/slog"
+	"net/url"
 	"os"
+	"reflect"
 
 	"github.com/bcicen/jstream"
 	"github.com/mitchellh/mapstructure"
@@ -53,6 +56,30 @@ func ValueTypeToString(valueType jstream.ValueType) string {
 	return "very strange"
 }
 
+func makeGitHubFileURL(userRepo string, ref string, subPath string) string {
+	url, _ := url.JoinPath("https://github.com/", userRepo, "blob", ref, subPath)
+
+	return url
+}
+
+// make configurable?
+var channelRepoMap = map[string]string{
+	"nixpkgs":      "NixOS/nixpkgs",
+	"nix-darwin":   "LnL7/nix-darwin",
+	"home-manager": "nix-community/home-manager",
+}
+
+func MakeChannelLink(channel string, ref string, subPath string) (*Link, error) {
+	if channelRepoMap[channel] == "" {
+		return nil, fmt.Errorf("don't know what repository relates to channel <%s>", channel)
+	}
+
+	return &Link{
+		Name: fmt.Sprintf("<%s/%s>", channel, subPath),
+		URL:  makeGitHubFileURL(channelRepoMap[channel], ref, subPath),
+	}, nil
+}
+
 func convertNixValue(nj nixValueJSON) *NixValue {
 	switch nj.Type {
 	case "", "literalExpression":
@@ -74,7 +101,7 @@ func convertNixValue(nj nixValueJSON) *NixValue {
 	}
 }
 
-func Process(inpath string, outpath string) error {
+func Process(inpath string, outpath string, channel string, revision string) error {
 	infile, err := os.Open(inpath)
 	if err != nil {
 		return errors.WithMessagef(err, "failed to open input file %s", inpath)
@@ -115,6 +142,30 @@ func Process(inpath string, outpath string) error {
 		kv := mv.Value.(jstream.KV)
 		x := kv.Value.(map[string]interface{})
 
+		var decls []*Link
+		for _, decl := range x["declarations"].([]interface{}) {
+			switch decl := reflect.ValueOf(decl); decl.Kind() {
+			case reflect.String:
+				s := decl.String()
+				link, err := MakeChannelLink(channel, revision, s)
+				if err != nil {
+					return errors.WithMessagef(err,
+						"could not make a channel link for channel %s, revision %s and subpath %s",
+						channel, revision, s,
+					)
+				}
+				decls = append(decls, link)
+			case reflect.Map:
+				decls = append(decls, decl.Convert(reflect.TypeFor[Link]()).Interface().(*Link))
+			default:
+				println("kind", decl.Kind().String())
+				panic("unexpected object type")
+			}
+		}
+		if len(decls) > 0 {
+			x["declarations"] = decls
+		}
+
 		err = ms.Decode(x) // stores in optJSON
 		if err != nil {
 			return errors.WithMessagef(err, "failed to decode option %#v", x)
@@ -158,7 +209,7 @@ func Process(inpath string, outpath string) error {
 		}
 	}
 
-	_, err = outfile.WriteString("]\n")
+	_, err = outfile.WriteString("\n]\n")
 	if err != nil {
 		return errors.WithMessage(err, "could not write to output")
 	}
diff --git a/justfile b/justfile
index 62e5659..c3b9130 100644
--- a/justfile
+++ b/justfile
@@ -4,14 +4,41 @@ default:
 prepare:
 	ln -sf $(nix-build --no-out-link -A css) frontend/static/base.css
 
-update-nixos-options:
-	wgo run -exit ./process --input $(nix-build --no-out-link -A nixos-options)/share/doc/nixos/options.json --output data/nixos-options.json
+get-nixpkgs-revision channel="nixos-unstable":
+	curl -L https://channels.nixos.org/{{ channel }}/git-revision > data/raw/nixpkgs-{{ channel }}-revision
+
+update-nixpkgs channel="nixos-unstable": (get-nixpkgs-revision channel)
+	curl -L https://channels.nixos.org/{{ channel }}/packages.json.br | brotli --stdout --decompress > data/raw/nixpkgs-{{ channel }}.json
+
+update-nixos-options channel="nixos-unstable": (get-nixpkgs-revision channel)
+	curl -L https://channels.nixos.org/{{ channel }}/options.json.br | brotli --stdout --decompress > data/raw/nixos-options-{{ channel }}.json
 
 update-darwin-options:
-	wgo run -exit ./process --input $(nix-build --no-out-link -A darwin-options)/share/doc/darwin/options.json --output data/darwin-options.json
+	ln -sf $(nix-build --no-out-link -A darwin-options)/share/doc/darwin/options.json data/raw/darwin-options.json
 
 update-home-manager-options:
-	wgo run -exit ./process --input $(nix-build --no-out-link -A home-manager-options)/share/doc/home-manager/options.json --output data/home-manager-options.json
+	ln -sf $(nix-build --no-out-link -A home-manager-options)/share/doc/home-manager/options.json data/raw/home-manager-options.json
+
+process-nixos-options channel="nixos-unstable":
+	wgo run -exit ./process \
+		--input data/raw/nixos-options-{{ channel }}.json \
+		--output data/processed/nixos-options-{{ channel }}.json \
+		--repo NixOS/nixpkgs \
+		--revision-file data/raw/nixpkgs-{{ channel }}-revision
+
+process-darwin-options:
+	wgo run -exit ./process \
+		--input data/raw/darwin-options.json \
+		--output data/processed/darwin-options.json \
+		--repo LnL7/nix-darwin
+
+process-home-manager-options:
+	wgo run -exit ./process \
+		--input data/raw/home-manager-options.json \
+		--output data/processed/home-manager-options.json \
+		--repo nix-community/home-manager
+
+process-all-options: process-nixos-options process-darwin-options process-home-manager-options
 
 update-all-options: update-nixos-options update-darwin-options update-home-manager-options
 
diff --git a/process/main.go b/process/main.go
index 3c9b67a..1089144 100644
--- a/process/main.go
+++ b/process/main.go
@@ -4,6 +4,8 @@ import (
 	"log"
 	"log/slog"
 	"os"
+	"strings"
+
 	"searchix/internal/options"
 
 	"github.com/ardanlabs/conf/v3"
@@ -11,8 +13,11 @@ import (
 )
 
 type Config struct {
-	Input  string `conf:"short:i,required,help:NixOS options file (json)"`
-	Output string `conf:"short:o,default:/dev/stdout"`
+	Input        string `conf:"short:i,required,help:NixOS options file (json)"`
+	Output       string `conf:"short:o,default:/dev/stdout"`
+	Revision     string `conf:"short:r,flag:revision,default:master"`
+	RevisionFile string `conf:"short:f,flag:revision-file"`
+	Channel      string `conf:"short:c,flag:channel,default:nixpkgs"`
 }
 
 func main() {
@@ -29,8 +34,15 @@ func main() {
 		}
 		log.Fatalf("parsing command line: %v", err)
 	}
+	if config.RevisionFile != "" {
+		f, err := os.ReadFile(config.RevisionFile)
+		if err != nil {
+			log.Fatalf("Error reading revision file %s: %v", config.RevisionFile, err)
+		}
+		config.Revision = strings.TrimSpace(string(f))
+	}
 
-	err = options.Process(config.Input, config.Output)
+	err = options.Process(config.Input, config.Output, config.Channel, config.Revision)
 	if err != nil {
 		log.Fatalf("Error processing file: %v", err)
 	}
diff --git a/shell.nix b/shell.nix
index b5a7a33..97d8cda 100644
--- a/shell.nix
+++ b/shell.nix
@@ -21,6 +21,7 @@ pkgs.mkShell {
   packages = with pkgs; [
     goEnv
 
+    brotli
     wgo
     gomod2nix
     niv