diff options
-rw-r--r-- | .golangci.yaml | 2 | ||||
-rw-r--r-- | CHANGELOG.md | 40 | ||||
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | frontend/static/search.js | 49 | ||||
-rw-r--r-- | frontend/static/style.css | 30 | ||||
-rw-r--r-- | internal/components/combined.go | 4 | ||||
-rw-r--r-- | internal/components/markdown.go | 2 | ||||
-rw-r--r-- | internal/components/options.go | 6 | ||||
-rw-r--r-- | internal/components/packages.go | 6 | ||||
-rw-r--r-- | internal/components/page.go | 5 | ||||
-rw-r--r-- | internal/components/search.go | 27 | ||||
-rw-r--r-- | internal/index/indexer.go | 15 | ||||
-rw-r--r-- | internal/index/search.go | 27 | ||||
-rw-r--r-- | internal/index/search_test.go | 150 | ||||
-rw-r--r-- | internal/server/mux.go | 22 | ||||
-rw-r--r-- | modd.conf | 2 | ||||
-rw-r--r-- | nix/modules/default.nix | 2 | ||||
-rw-r--r-- | nix/package.nix | 2 |
18 files changed, 345 insertions, 58 deletions
diff --git a/.golangci.yaml b/.golangci.yaml index e44d5d8..1e968df 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -21,6 +21,8 @@ linters: - unconvert - wrapcheck linters-settings: + paralleltest: + ignore-missing: true gosec: excludes: - G115 diff --git a/CHANGELOG.md b/CHANGELOG.md index 87a6f0a..f6988be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,47 @@ # Changelog -## [v0.1.30](https://git.alanpearce.eu/searchix/diff/?id=v0.1.29&id2=5762645aedc4d39a9e6caeb227410ca9bae2d2b5) (2025-03-18) +## [v0.1.31](https://git.alanpearce.eu/searchix/diff/?id=v0.1.30&id2=d4ec6e5beecd549114dafd0b7c3b4a9d910388fb) (2025-03-21) ### Features +- **nixos-module:** allow setting environment variables + ([e8fbdf3](https://git.alanpearce.eu/searchix/commit/?id=e8fbdf3bd12c8920a6e9bd84b34e787764b11eaf)) +- **nixos-module:** allow setting environment variables + ([78fc3e6](https://git.alanpearce.eu/searchix/commit/?id=78fc3e6cd43e6df90e17067fe0eb52b9badf9a75)) +- demote NUR results in combined search + ([782b636](https://git.alanpearce.eu/searchix/commit/?id=782b636c6ba9ebccecf46c7a1e5583e8108baf9a)) +- promote results with literal or prefix name matches + ([49a07fb](https://git.alanpearce.eu/searchix/commit/?id=49a07fb0b513dcaeb6241f4d87c160b9e0119260)) +- make list of source links dynamic + ([7247322](https://git.alanpearce.eu/searchix/commit/?id=7247322a386f065c643dc58f0ae5b57ad7ec1cc1)) +- enable NUR package import + ([2705e97](https://git.alanpearce.eu/searchix/commit/?id=2705e97ce1cf7d6a399c5f0175c36562fdef3352)) +- wrap search form in semantic <search> element + ([ff1e953](https://git.alanpearce.eu/searchix/commit/?id=ff1e9539fca1f011cfd52d0309a373f211c3fd10)) +- show last/next/current indexing run time + ([383ee78](https://git.alanpearce.eu/searchix/commit/?id=383ee780613116e78db9114a39a2d6127533463c)) +- shorten shutdown timeout in development + ([49e3004](https://git.alanpearce.eu/searchix/commit/?id=49e3004d33bf84aa081460e4a6d89a8d84cc12b0)) +- Convert templ components to gomponents + ([896d844](https://git.alanpearce.eu/searchix/commit/?id=896d844cac976afd0ee8aa73dd2fb28e15e7ac79)) + +### Fixes + +- remove rendering from search timeout restriction + ([d4ec6e5](https://git.alanpearce.eu/searchix/commit/?id=d4ec6e5beecd549114dafd0b7c3b4a9d910388fb)) +- package programs displayed off-centre + ([de98780](https://git.alanpearce.eu/searchix/commit/?id=de987806cd030e85a22e11b35835a3524068adb7)) +- footer spacing + ([c0c02ac](https://git.alanpearce.eu/searchix/commit/?id=c0c02ac768a144f4417edfba967a4f7857a150b9)) +- detach version from rest of footer text + ([6b342b8](https://git.alanpearce.eu/searchix/commit/?id=6b342b83cedec82d240fc820d9696d3bb3eda8a2)) +- wrong pagination links for combined results + ([9102aef](https://git.alanpearce.eu/searchix/commit/?id=9102aef53c5fb73585359306a518e726a3623731)) + +### [v0.1.30](https://git.alanpearce.eu/searchix/diff/?id=v0.1.29&id2=v0.1.30) (2025-03-18) + +#### Features + - show version number and link in footer ([5762645](https://git.alanpearce.eu/searchix/commit/?id=5762645aedc4d39a9e6caeb227410ca9bae2d2b5)) - split compound words in names into n-grams diff --git a/README.md b/README.md index 4430131..cb3877e 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,22 @@ A search tool to find options and packages in the NixOS ecosystem. Aims to be li - NixOS options - Nix packages - [Nix darwin](https://github.com/LnL7/nix-darwin) options -- [Home manager](https://github.com/nix-community/home-manager) options. +- [Home manager](https://github.com/nix-community/home-manager) options +- [Nix User Repository](https://github.com/nix-community/NUR) packages There is an instance running at [searchix.alanpearce.eu](https://searchix.alanpearce.eu/), which uses the following channels, with updates attempted daily: - nixos-options: nixos-unstable - nixpkgs: nixos-unstable -- darwin: master -- home-manager: master +- darwin: master branch +- home-manager: master branch +- nur: main branch -You can also [run it yourself](./docs/running.md), if you're feeling bold. It's very light-weight! +You can also [run it yourself](./docs/running.md), if you're feeling bold. It's quite lightweight! ## Status -**Alpha** +**Beta** Expect breakage. Search results are not expected to match the quality of [search.nixos.org](https://search.nixos.org/), the priority is more on having multiple sources in one location. diff --git a/frontend/static/search.js b/frontend/static/search.js index e16c83c..0bf4a5e 100644 --- a/frontend/static/search.js +++ b/frontend/static/search.js @@ -28,14 +28,24 @@ if (window.trustedTypes && trustedTypes.createPolicy) { }); } +/** + * + * @param {MouseEvent} ev + */ function openSiblingDialog(ev) { - const dialog = ev.target.nextElementSibling; - dialog.showModal(); - dialog.querySelector("button").addEventListener("click", function () { - dialog.close(); - }); + if (!(ev.shiftKey || ev.altKey || ev.ctrlKey || ev.metaKey)) { + const dialog = ev.target.nextElementSibling; + dialog.showModal(); + dialog.querySelector("button").addEventListener("click", function () { + dialog.close(); + }); + } } +/** + * + * @param {HTMLElement} results + */ function addOpenDialogListeners(results) { results.querySelectorAll("a.open-dialog").forEach(function (element) { element.addEventListener("click", handleDialogOpen); @@ -45,12 +55,20 @@ function addOpenDialogListeners(results) { }); } +/** + * + * @param {MouseEvent} ev + */ function paginationLinkClicked(ev) { const url = new URL(ev.target.href); getResults(url); ev.preventDefault(); } +/** + * + * @param {HTMLElement} pagination + */ function addPaginationEventListeners(pagination) { Array.from(pagination.children).forEach((child) => child.addEventListener("click", paginationLinkClicked), @@ -70,6 +88,10 @@ function renderResults(html) { } } +/** + * + * @param {URL} url + */ async function getResults(url) { try { state.url = url.toJSON(); @@ -141,6 +163,10 @@ document.querySelector("a.current").addEventListener("click", function (ev) { queryInput.value = ""; }); +/** + * + * @param {string} html + */ function renderDetails(html) { const fragment = detailsRange.createContextualFragment( escapePolicy !== null ? escapePolicy.createHTML(html) : html, @@ -157,6 +183,10 @@ dialog.querySelector("button").addEventListener("click", function () { dialog.close(); }); +/** + * + * @param {URL} url + */ async function getDetail(url) { try { state.url = url.toJSON(); @@ -178,9 +208,14 @@ async function getDetail(url) { } } +/** + * @param {MouseEvent} ev + */ function handleDialogOpen(ev) { - getDetail(new URL(ev.target.href)); - ev.preventDefault(); + if (!(ev.ctrlKey || ev.metaKey || ev.shiftKey || ev.altKey)) { + getDetail(new URL(ev.target.href)); + ev.preventDefault(); + } } if (state.opened.length > 0) { diff --git a/frontend/static/style.css b/frontend/static/style.css index 8766844..f7d1f75 100644 --- a/frontend/static/style.css +++ b/frontend/static/style.css @@ -2,7 +2,7 @@ --sans-font: -apple-system, BlinkMacSystemFont, sans-serif; --standard-border-radius: 0; --preformatted: var(--code); - --min-width: 60rem; + --min-width: 80rem; --accent-error: #ffe0e0; } @@ -162,13 +162,39 @@ dialog > h2 { } table { - width: 100%; margin-top: 0; + width: 100%; + table-layout: fixed; + white-space: nowrap; +} + +th.description { + width: 50%; +} + +th.score { + width: 8ex; } td, th { padding: 0.25rem 0.5rem; + text-overflow: ellipsis; + overflow: clip; +} + +tr { + height: 1.5rem; +} + +td.description > * { + max-width: 100%; + text-overflow: ellipsis; + overflow: clip; +} + +td.description > *:not(:first-child) { + display: none; } ul:only-child { diff --git a/internal/components/combined.go b/internal/components/combined.go index fe97e14..8c2dc34 100644 --- a/internal/components/combined.go +++ b/internal/components/combined.go @@ -31,7 +31,7 @@ func Combined(result *index.Result) g.Node { Th(Scope("col"), g.Text("Attribute")), Th(Scope("col"), g.Text("Description")), g.If(config.DevMode, - Th(Scope("col"), g.Text("Score")), + Th(Scope("col"), Class("score"), g.Text("Score")), ), ), ), @@ -41,7 +41,7 @@ func Combined(result *index.Result) g.Node { Td( openCombinedDialogLink(nix.GetKey(hit.Data)), ), - Td( + Td(Class("description"), CombinedData(hit.Data), ), g.If(config.DevMode, diff --git a/internal/components/markdown.go b/internal/components/markdown.go index 405ab52..a26fe3d 100644 --- a/internal/components/markdown.go +++ b/internal/components/markdown.go @@ -4,7 +4,7 @@ import ( "regexp" ) -var firstSentenceRegexp = regexp.MustCompile(`^.*?\.[[:space:]]`) +var firstSentenceRegexp = regexp.MustCompile(`^.+?(\.[[:space:]]|:\n)`) func firstSentence[T ~string](text T) T { if fs := firstSentenceRegexp.FindString(string(text)); fs != "" { diff --git a/internal/components/options.go b/internal/components/options.go index 1d01784..630fecd 100644 --- a/internal/components/options.go +++ b/internal/components/options.go @@ -14,9 +14,9 @@ func Options(result *index.Result) g.Node { THead( Tr( Th(Scope("col"), g.Text("Title")), - Th(Scope("col"), g.Text("Description")), + Th(Scope("col"), Class("description"), g.Text("Description")), g.If(config.DevMode, - Th(Scope("col"), g.Text("Score")), + Th(Scope("col"), Class("score"), g.Text("Score")), ), ), ), @@ -37,7 +37,7 @@ func optionRow(hit index.DocumentMatch, o nix.Option) g.Node { Td( openDialogLink(o.Name), ), - Td( + Td(Class("description"), firstSentence(o.Description), Dialog(ID(o.Name)), ), diff --git a/internal/components/packages.go b/internal/components/packages.go index db45302..90bf92d 100644 --- a/internal/components/packages.go +++ b/internal/components/packages.go @@ -15,9 +15,9 @@ func Packages(result *index.Result) g.Node { Tr( Th(Scope("col"), g.Text("Attribute")), Th(Scope("col"), g.Text("Name")), - Th(Scope("col"), g.Text("Description")), + Th(Scope("col"), Class("description"), g.Text("Description")), g.If(config.DevMode, - Th(Scope("col"), g.Text("Score")), + Th(Scope("col"), Class("score"), g.Text("Score")), ), ), ), @@ -41,7 +41,7 @@ func packageRow(hit index.DocumentMatch, p nix.Package) g.Node { Td( g.Text(p.Name), ), - Td( + Td(Class("description"), g.Text(p.Description), ), g.If(config.DevMode, diff --git a/internal/components/page.go b/internal/components/page.go index 6830247..06e16ae 100644 --- a/internal/components/page.go +++ b/internal/components/page.go @@ -90,7 +90,10 @@ func Page(tdata TemplateData, children ...g.Node) g.Node { g.Group([]g.Node{ g.Text("Searchix "), A( - Href("https://git.sr.ht/~alanpearce/searchix/refs/"+config.Version), + Href( + "https://git.sr.ht/~alanpearce/searchix/tree/"+config.Version+"/CHANGELOG.md", + ), + TitleAttr("View changelog"), g.Text(config.Version), ), g.Text(" "), diff --git a/internal/components/search.go b/internal/components/search.go index b4ef7bd..3db1cd4 100644 --- a/internal/components/search.go +++ b/internal/components/search.go @@ -19,6 +19,7 @@ func SearchForm(tdata TemplateData, r ResultData) g.Node { Input( ID("query"), Aria("labelledby", "legend"), + MinLength("2"), Name("query"), Type("search"), Value(r.Query), @@ -45,31 +46,33 @@ func SearchPage(tdata TemplateData, r ResultData, children ...g.Node) g.Node { g.Text("Indexing in progress, started "), Time( DateTime(Indexing.StartedAt.Format(time.RFC3339)), - Title(Indexing.StartedAt.Format(time.RFC3339)), + Title(Indexing.StartedAt.Format(time.DateTime)), g.Text(time.Since(Indexing.StartedAt).Round(time.Second).String()), ), g.Text(" ago. "), g.If(!Indexing.FinishedAt.IsZero(), - g.Text("Last run took "), - Time( - DateTime(Indexing.FinishedAt.Format(time.RFC3339)), - Title(Indexing.FinishedAt.Format(time.RFC3339)), - g.Text(time.Since(Indexing.FinishedAt).Round(time.Minute).String()), - ), + g.Group([]g.Node{ + g.Text("Last run took "), + Time( + DateTime(Indexing.FinishedAt.Format(time.RFC3339)), + Title(Indexing.FinishedAt.Format(time.DateTime)), + g.Text(time.Since(Indexing.FinishedAt).Round(time.Minute).String()), + ), + }), ), ), P( g.Text("Indexing last ran "), Time( DateTime(Indexing.FinishedAt.Format(time.RFC3339)), - Title(Indexing.FinishedAt.Format(time.RFC3339)), - g.Text(time.Since(Indexing.FinishedAt).Round(time.Minute).String()), + Title(Indexing.FinishedAt.Format(time.DateTime)), + g.Textf("%.0f hours ago", time.Since(Indexing.FinishedAt).Hours()), ), - g.Text(" ago, will run again in "), + g.Text(", will run again in "), Time( DateTime(Indexing.NextRun.Format(time.RFC3339)), - Title(Indexing.NextRun.Format(time.RFC3339)), - g.Text(time.Until(Indexing.NextRun).Round(time.Minute).String()), + Title(Indexing.NextRun.Format(time.DateTime)), + g.Textf("%.0f hours", time.Until(Indexing.NextRun).Hours()), ), g.Text("."), ), diff --git a/internal/index/indexer.go b/internal/index/indexer.go index 8cbc8e2..c4032e8 100644 --- a/internal/index/indexer.go +++ b/internal/index/indexer.go @@ -8,6 +8,7 @@ import ( "math" "os" "path" + "path/filepath" "slices" "go.alanpearce.eu/searchix/internal/file" @@ -93,13 +94,6 @@ func createIndexMapping() (mapping.IndexMapping, errors.E) { if err != nil { return nil, errors.WithMessage(err, "could not add custom analyser") } - err = indexMapping.AddCustomAnalyzer("keyword_single", map[string]any{ - "type": keyword.Name, - "tokenizer": letter.Name, - }) - if err != nil { - return nil, errors.WithMessage(err, "could not add custom analyser") - } identityFieldMapping := bleve.NewKeywordFieldMapping() @@ -222,6 +216,13 @@ func OpenOrCreate( ) (*ReadIndex, *WriteIndex, bool, errors.E) { var err errors.E bleve.SetLog(zap.NewStdLog(options.Logger.Named("bleve").GetLogger())) + if !filepath.IsAbs(dataRoot) { + wd, err := os.Getwd() + if err != nil { + return nil, nil, false, errors.WithMessagef(err, "could not get working directory") + } + dataRoot = filepath.Join(wd, dataRoot) + } indexPath := path.Join(dataRoot, indexBaseName) metaPath := path.Join(dataRoot, metaBaseName) diff --git a/internal/index/search.go b/internal/index/search.go index 292661e..a8124c7 100644 --- a/internal/index/search.go +++ b/internal/index/search.go @@ -128,8 +128,8 @@ func (index *ReadIndex) Search( // match the user's query in any field ... query.AddMust(bleve.NewDisjunctionQuery( - bleve.NewTermQuery(keyword), - bleve.NewPrefixQuery(keyword), + setBoost(bleve.NewTermQuery(keyword), 50), + setBoost(bleve.NewPrefixQuery(keyword), 25), bleve.NewMatchPhraseQuery(keyword), bleve.NewMatchQuery(keyword), )) @@ -140,13 +140,23 @@ func (index *ReadIndex) Search( ) } else { q := bleve.NewDisjunctionQuery( - setBoost(setField(bleve.NewTermQuery("nixpkgs"), "Source"), -150), - setBoost(setField(bleve.NewTermQuery("nur"), "Source"), -200), + setBoost(setField(bleve.NewTermQuery("nixpkgs"), "Source"), -1000), + setBoost(setField(bleve.NewTermQuery("nur"), "Source"), -5000), ) query.AddShould(q) } + mainProgramQuery := bleve.NewMatchQuery(keyword) + mainProgramQuery.SetField("MainProgram") + mainProgramQuery.SetBoost(50) + query.AddShould(mainProgramQuery) + + mainProgramLiteralQuery := bleve.NewTermQuery(keyword) + mainProgramLiteralQuery.SetField("MainProgram") + mainProgramLiteralQuery.SetBoost(100) + query.AddShould(mainProgramLiteralQuery) + programsQuery := bleve.NewMatchQuery(keyword) programsQuery.SetField("Programs") programsQuery.SetBoost(2) @@ -215,3 +225,12 @@ func (index *ReadIndex) GetDocument( return nil, err } + +func (index *ReadIndex) Close() error { + err := index.index.Close() + if err != nil { + return errors.WithStack(err) + } + + return nil +} diff --git a/internal/index/search_test.go b/internal/index/search_test.go new file mode 100644 index 0000000..339a0de --- /dev/null +++ b/internal/index/search_test.go @@ -0,0 +1,150 @@ +package index_test + +import ( + "context" + "maps" + "math" + "slices" + "testing" + "time" + + "go.alanpearce.eu/searchix/internal/config" + "go.alanpearce.eu/searchix/internal/index" + "go.alanpearce.eu/searchix/internal/nix" + "go.alanpearce.eu/x/log" +) + +const dataRoot = "../../data" + +func TestSearchGitPackagesFirst(t *testing.T) { + log := log.Configure(false) + cfg := config.DefaultConfig + + read, _, exists, err := index.OpenOrCreate(dataRoot, false, &index.Options{ + Logger: log.Named("index"), + LowMemory: false, + }) + defer read.Close() + if err != nil { + t.Fatal(err) + } + if !exists { + t.Fatal("expected index to exist") + } + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + source := cfg.Importer.Sources["nixpkgs"] + if source == nil || !source.Enable { + t.Fatal("expected source to exist and be enabled") + } + + result, err := read.Search( + ctx, + source, + "git", + 0, + 100, + ) + if err != nil { + t.Fatal(err) + } + + if result.Total < 4 { + t.Errorf("Expected at least 4 results, got %d", result.Total) + } + important := map[string]int{ + "git": 0, + "git-doc": 0, + "gitFull": 0, + "gitMinimal": 0, + "gitSVN": 0, + } + var i int + for hit := range result.Hits { + data := hit.Data.(nix.Package) + if _, found := important[data.Attribute]; found { + important[data.Attribute] = i + } + i++ + } + if slices.Max(slices.Collect(maps.Values(important))) > len(important) { + t.Errorf( + "Expected all of %s to be the first %d matches, got %v", + slices.Collect(maps.Keys(important)), + len(important), + important, + ) + } +} + +func TestSearchJujutsuPackagesFirst(t *testing.T) { + log := log.Configure(false) + cfg := config.DefaultConfig + + read, _, exists, err := index.OpenOrCreate(dataRoot, false, &index.Options{ + Logger: log.Named("index"), + LowMemory: false, + }) + defer read.Close() + if err != nil { + t.Fatal(err) + } + if !exists { + t.Fatal("expected index to exist") + } + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + source := cfg.Importer.Sources["nixpkgs"] + if source == nil || !source.Enable { + t.Fatal("expected source to exist and be enabled") + } + + result, err := read.Search( + ctx, + source, + "jj", + 0, + 100, + ) + if err != nil { + t.Fatal(err) + } + + if result.Total < 4 { + t.Errorf("Expected at least 4 results, got %d", result.Total) + } + important := map[string]int{ + "jj": 0, + "jujutsu": 0, + "lazyjj": 0, + "jjui": 0, + "jj-fzf": 0, + } + matches := []string{} + unwanted := "javacc" + unwantedIndex := math.MaxInt + var i int + for hit := range result.Hits { + data := hit.Data.(nix.Package) + if _, found := important[data.Attribute]; found { + matches = append(matches, data.Attribute) + } else if data.Attribute == unwanted { + unwantedIndex = i + matches = append(matches, data.Attribute) + } + i++ + } + if slices.Max(slices.Collect(maps.Values(important))) > unwantedIndex { + t.Errorf( + "Expected all of %s to be above unwanted result %s at index %d. Results: %v", + slices.Collect(maps.Keys(important)), + unwanted, + unwantedIndex, + matches, + ) + } +} diff --git a/internal/server/mux.go b/internal/server/mux.go index f7a82d8..968b37c 100644 --- a/internal/server/mux.go +++ b/internal/server/mux.go @@ -93,12 +93,15 @@ func NewMux( } } - ctx, cancel := context.WithTimeout(r.Context(), searchTimeout) - defer cancel() - if r.URL.Query().Has("query") { qs := r.URL.Query().Get("query") + if len(qs) < 2 { + errorHandler(w, r, "Query too short", http.StatusBadRequest) + + return + } + var pageSize int = search.DefaultPageSize var pageNumber = 1 if pg := r.URL.Query().Get("page"); pg != "" { @@ -110,11 +113,15 @@ func NewMux( } if pageNumber == 0 { pageNumber = 1 - pageSize = math.MaxInt + pageSize = config.MaxResultsShowAll } } page := pagination.New(pageNumber, pageSize) + + ctx, cancel := context.WithTimeout(r.Context(), searchTimeout) results, err := index.Search(ctx, source, qs, page.From, page.Size) + cancel() + if err != nil { if err == context.DeadlineExceeded { errorHandler(w, r, "Search timed out", http.StatusInternalServerError) @@ -126,7 +133,8 @@ func NewMux( return } - if pageSize == math.MaxInt && results.Total > config.MaxResultsShowAll { + if pageSize == config.MaxResultsShowAll && + results.Total > config.MaxResultsShowAll { errorHandler(w, r, "Too many results, use pagination", http.StatusBadRequest) } @@ -219,9 +227,9 @@ func NewMux( importerSingular := importerType.Singular() ctx, cancel := context.WithTimeout(r.Context(), searchTimeout) - defer cancel() - doc, err := index.GetDocument(ctx, source, r.PathValue("id")) + cancel() + if err != nil { errorHandler( w, diff --git a/modd.conf b/modd.conf index 0a3e6a1..c4874f5 100644 --- a/modd.conf +++ b/modd.conf @@ -3,5 +3,5 @@ internal/index/indexer.go { } **/*.go config.toml { - daemon +sigint: go run ./cmd/searchix-web --dev --config config.toml + daemon +sigint: go run -ldflags="-X go.alanpearce.eu/searchix/internal/config.Version=$(git describe --tags --abbrev=0)" ./cmd/searchix-web --dev --config config.toml } diff --git a/nix/modules/default.nix b/nix/modules/default.nix index ba425ca..5184dde 100644 --- a/nix/modules/default.nix +++ b/nix/modules/default.nix @@ -200,7 +200,7 @@ in description = '' Configuration for searchix. - See https://git.alanpearce.eu/searchix/tree/defaults.toml?h=v0.1.30 + See https://git.alanpearce.eu/searchix/tree/defaults.toml?h=v0.1.31 ''; }; }; diff --git a/nix/package.nix b/nix/package.nix index cf00514..996c0c4 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -13,7 +13,7 @@ , css }: let - version = "0.1.30"; + version = "0.1.31"; in buildGoApplication { pname = "searchix"; |