Feat/dynamic import (#473)

* Make the channel importer versions dynamic

* few things fromt he list

1. add nixos-org-configurations as input to flake.nix
2. evaluate channels.nix file and export channels via environment variable.
   that environment variable (lets call it NIXOS_CHANNELS) should be present
   during the build and inside the nix shell. the content of the variable can
   be JSON.
3. we pickup the NIXOS_CHANNELS environment variable in
   frontend/webpack.config.js and pass it further to webpack process, just
   like we do with ELASTICSEARCH_MAPPING_SCHEMA_VERSION.
4. we forward NIXOS_CHANNELS to Elm via frontend/src/index.js as an Elm
   application flag. Just like we do with other variables there.

* Decode nixosChannels in Elm

* Use nixosChannels that came via application flag

* read nixos channels in github action

* defaultNixOSChannel should be calculated

* add two pointers where the check should be added

* pass nixosChannels to flake-info and remove title, rather calculate it

* Add NixosChannels struct validation and validation Error

* Read NIXOS_CHANNEL variable

* Check channel

* Add channel struct to fix parsing NIXOS_CHANNELS

* Use `eachDefaultSystem` instead of listing them manually

* Add individual dev shells for frontend and backend

* Update .github/workflows/import-to-elasticsearch.yml

Co-authored-by: Naïm Favier <n@monade.li>

* use both development environments by default (as it was)

but still provide devShells for each of the subprojects

* pkgs.lib → lib everywhere

and define lib = nixpkgs.lib before the call to eachDefaultSystem
Also, version = lib.fileContents ./VERSION;

* Update flake.nix

Co-authored-by: Naïm Favier <n@monade.li>

* typo

* bumping version to test the changes to import-to-elasticsearch github action

* some invisibile characters needed to be removed

* typo

* will this work

* typo

* forgot the checkout step

* add some debugging

* typo

* read NIXOS_CHANNELS from environment not via argument

* fix for the NIXOS_CHANNELS variable

Co-authored-by: Janne Heß <janne@hess.ooo>
Co-authored-by: ysndr <me@ysndr.de>
Co-authored-by: Naïm Favier <n@monade.li>
This commit is contained in:
Rok Garbas 2022-04-24 23:48:01 +02:00 committed by GitHub
parent 492794fad7
commit eea6cd3ffb
Failed to generate hash of commit
15 changed files with 507 additions and 262 deletions

View file

@ -7,15 +7,36 @@ on:
jobs:
nixos-channels:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.nixos-channels.outputs.matrix }}
steps:
- name: Checking out the repository
uses: actions/checkout@v3
- name: Setup
uses: ./.github/actions/common-setup
with:
CACHIX_SIGNING_KEY: ${{ secrets.CACHIX_SIGNING_KEY }}
- name: NixOS Channels
id: nixos-channels
run: |
nix build -L .#nixosChannels
channels="{\"channel\": $(< ./result)}"
echo $channels
echo "::set-output name=matrix::$channels"
import-nixpkgs:
needs: nixos-channels
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
channel:
- unstable
- 21.11
matrix: ${{ fromJSON(needs.nixos-channels.outputs.matrix) }}
env:
RUST_LOG: debug
@ -46,7 +67,6 @@ jobs:
if: github.repository_owner == 'NixOS'
import-flakes:
runs-on: ubuntu-latest

View file

@ -1 +1 @@
29
30

View file

@ -1,5 +1,7 @@
{ pkgs ? import <nixpkgs> { } }: with pkgs;
rustPlatform.buildRustPackage rec {
{ pkgs ? import <nixpkgs> {}
, nixosChannels ? {}
}:
pkgs.rustPlatform.buildRustPackage rec {
name = "flake-info";
src = ./.;
cargoLock = {
@ -8,11 +10,18 @@ rustPlatform.buildRustPackage rec {
"elasticsearch-8.0.0-alpha.1" = "sha256-gjmk3Q3LTAvLhzQ+k1knSp1HBwtqNiubjXNnLy/cS5M=";
};
};
nativeBuildInputs = [ pkg-config ];
buildInputs = [ openssl openssl.dev makeWrapper ]
++ lib.optional pkgs.stdenv.isDarwin [ libiconv darwin.apple_sdk.frameworks.Security ];
nativeBuildInputs = with pkgs; [ pkg-config ];
buildInputs =
with pkgs; [
openssl
openssl.dev
makeWrapper
] ++ lib.optional pkgs.stdenv.isDarwin [
libiconv
darwin.apple_sdk.frameworks.Security
];
checkInputs = [ pandoc ];
checkInputs = with pkgs; [ pandoc ];
NIXPKGS_PANDOC_FILTERS_PATH = "${pkgs.path + "/doc/build-aux/pandoc-filters"}";
@ -24,6 +33,7 @@ rustPlatform.buildRustPackage rec {
postInstall = ''
wrapProgram $out/bin/flake-info \
--set NIXPKGS_PANDOC_FILTERS_PATH "${NIXPKGS_PANDOC_FILTERS_PATH}" \
--prefix PATH : ${pandoc}/bin
--set NIXOS_CHANNELS '${builtins.toJSON nixosChannels}' \
--prefix PATH : ${pkgs.pandoc}/bin
'';
}

View file

@ -5,11 +5,14 @@ use flake_info::data::import::{Kind, NixOption};
use flake_info::data::{self, Export, Nixpkgs, Source};
use flake_info::elastic::{ElasticsearchError, ExistsStrategy};
use flake_info::{commands, elastic};
use lazy_static::lazy_static;
use log::{debug, error, info, warn};
use semver::VersionReq;
use serde::Deserialize;
use sha2::Digest;
use std::path::{Path, PathBuf};
use std::ptr::hash;
use std::str::FromStr;
use std::{fs, io};
use structopt::{clap::ArgGroup, StructOpt};
use thiserror::Error;
@ -198,6 +201,9 @@ enum FlakeInfoError {
#[error("Nix check failed: {0}")]
NixCheck(#[from] NixCheckError),
#[error("Nixos Channel `{0}` not among the allowed Channels set by NIXOS_CHANNELS ({:?}", .1.channels)]
UnknownNixOSChannel(String, NixosChannels),
#[error("Getting flake info caused an error: {0:?}")]
Flake(anyhow::Error),
#[error("Getting nixpkgs info caused an error: {0:?}")]
@ -237,6 +243,8 @@ async fn run_command(
Ok((exports, ident))
}
Command::Nixpkgs { channel } => {
NIXOS_CHANNELS.check_channel(&channel)?;
let nixpkgs = Source::nixpkgs(channel)
.await
.map_err(FlakeInfoError::Nixpkgs)?;
@ -251,6 +259,8 @@ async fn run_command(
Ok((exports, ident))
}
Command::NixpkgsArchive { source, channel } => {
NIXOS_CHANNELS.check_channel(&channel)?;
let ident = (
"nixos".to_string(),
channel.to_owned(),
@ -404,3 +414,36 @@ async fn push_to_elastic(
Ok(())
}
/// Information about allowed and default nixos channels.
/// Typyically passed by environment variable NIXOS_CHANNELS.
/// Used to filter the input arguments for `flake-info nixpkgs` and `flake-info nixpkgs-archive`
#[derive(Clone, Debug, Deserialize)]
struct NixosChannels {
channels: Vec<Channel>,
}
#[derive(Clone, Debug, Deserialize)]
struct Channel {
branch: String
}
impl NixosChannels {
fn check_channel(&self, channel: &String) -> Result<(), FlakeInfoError> {
self.channels.iter().find(|c| &c.branch == channel).map_or_else(|| Ok(()), |_| Err(FlakeInfoError::UnknownNixOSChannel(channel.clone(), self.clone())))
}
}
impl FromStr for NixosChannels {
type Err=serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
lazy_static! {
static ref NIXOS_CHANNELS: NixosChannels = std::env::var("NIXOS_CHANNELS")
.unwrap_or("".to_string())
.parse().unwrap();
}

View file

@ -15,6 +15,22 @@
"type": "github"
}
},
"nixos-org-configurations": {
"flake": false,
"locked": {
"lastModified": 1648674978,
"narHash": "sha256-7lVlPb9/Lu3M9xPzwdvtgqkeQI4FAMv+T3v+yT54ZZ0=",
"owner": "NixOS",
"repo": "nixos-org-configurations",
"rev": "76c0687ac275235142dae7c855aab2885302298c",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixos-org-configurations",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1650701402,
@ -33,6 +49,7 @@
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixos-org-configurations": "nixos-org-configurations",
"nixpkgs": "nixpkgs"
}
}

109
flake.nix
View file

@ -6,33 +6,116 @@
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.nixos-org-configurations.url = "github:NixOS/nixos-org-configurations";
inputs.nixos-org-configurations.flake = false;
outputs = { self
, nixpkgs
, flake-utils
, nixos-org-configurations
}:
flake-utils.lib.eachSystem
(with flake-utils.lib.system; [
x86_64-linux
i686-linux
x86_64-darwin
aarch64-linux
])
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
warnToUpgradeNix = pkgs.lib.warn "Please upgrade Nix to 2.7 or later.";
lib = nixpkgs.lib;
warnToUpgradeNix = lib.warn "Please upgrade Nix to 2.7 or later.";
version = lib.fileContents ./VERSION;
nixosChannels =
let
allChannels = (import "${nixos-org-configurations}/channels.nix").channels;
filteredChannels =
lib.filterAttrs
(n: v:
builtins.elem v.status ["beta" "stable" "rolling"] &&
lib.hasPrefix "nixos-" n &&
v ? variant && v.variant == "primary"
)
allChannels;
in
{
channels =
lib.mapAttrsToList
(n: v:
{
id = lib.removePrefix "nixos-" n;
status = v.status;
jobset =
builtins.concatStringsSep
"/"
(lib.init (lib.splitString "/" v.job));
branch = n;
}
)
filteredChannels;
default =
builtins.head
(builtins.sort (e1: e2: ! (builtins.lessThan e1 e2))
(builtins.map
(lib.removePrefix "nixos-")
(builtins.attrNames
(lib.filterAttrs (_: v: v.status == "stable") filteredChannels)
)
)
);
};
nixosChannelsFile = pkgs.runCommand "nixosChannels.json" {} ''
echo '${builtins.toJSON (builtins.map (c: c.id) nixosChannels.channels)}' > $out
'';
mkDevShell = { inputsFrom ? [], extraPackages ? [], extraShellHook ? "" }:
pkgs.mkShell {
inherit inputsFrom;
packages = extraPackages;
shellHook = ''
export NIXOS_CHANNELS='${builtins.toJSON nixosChannels}';
export ELASTICSEARCH_MAPPING_SCHEMA_VERSION="${version}";
'' + extraShellHook;
};
in rec {
packages.default = packages.flake-info;
packages.flake-info = import ./flake-info { inherit pkgs; };
packages.frontend = import ./frontend { inherit pkgs; };
packages.flake-info = import ./flake-info { inherit pkgs nixosChannels; };
packages.frontend = import ./frontend { inherit pkgs nixosChannels version; };
packages.nixosChannels = nixosChannelsFile;
devShells.default = pkgs.mkShell {
inputsFrom = builtins.attrValues packages;
shellHook = ''
devShells.default = mkDevShell {
inputsFrom = [
packages.flake-info
packages.frontend
];
extraPackages = [pkgs.rustfmt];
extraShellHook = ''
export RUST_SRC_PATH="${pkgs.rustPlatform.rustLibSrc}";
export NIXPKGS_PANDOC_FILTERS_PATH="${packages.flake-info.NIXPKGS_PANDOC_FILTERS_PATH}";
export PATH=$PWD/frontend/node_modules/.bin:$PATH
rm -rf frontend/node_modules
ln -sf ${packages.frontend.yarnPkg}/libexec/${(builtins.parseDrvName packages.frontend.name).name}/node_modules frontend/
echo "========================================================"
echo "= To develop the frontend run: cd frontend && yarn dev ="
echo "========================================================"
'';
};
devShells.flake-info = mkDevShell {
inputsFrom = [packages.flake-info];
extraPackages = [pkgs.rustfmt];
extraShellHook = ''
export RUST_SRC_PATH="${pkgs.rustPlatform.rustLibSrc}";
export NIXPKGS_PANDOC_FILTERS_PATH="${packages.flake-info.NIXPKGS_PANDOC_FILTERS_PATH}";
'';
};
devShells.frontend = mkDevShell {
inputsFrom = [packages.frontend] ;
extraShellHook = ''
export PATH=$PWD/frontend/node_modules/.bin:$PATH
rm -rf frontend/node_modules
ln -sf ${packages.frontend.yarnPkg}/libexec/${(builtins.parseDrvName packages.frontend.name).name}/node_modules frontend/
echo "========================================================"
echo "= To develop the frontend run: cd frontend && yarn dev ="
echo "========================================================"
'';
};

View file

@ -1,5 +1,6 @@
{ pkgs ? import <nixpkgs> { }
, version ? pkgs.lib.removeSuffix "\n" (builtins.readFile ../VERSION)
, nixosChannels
, version
}:
let
package = builtins.fromJSON (builtins.readFile ./package.json);
@ -52,6 +53,9 @@ pkgs.stdenv.mkDerivation {
elm-analyse
]);
ELASTICSEARCH_MAPPING_SCHEMA_VERSION = version;
NIXOS_CHANNELS = builtins.toJSON nixosChannels;
configurePhase = pkgs.elmPackages.fetchElmDeps {
elmPackages = import ./elm-srcs.nix;
elmVersion = pkgs.elmPackages.elm.version;
@ -66,7 +70,6 @@ pkgs.stdenv.mkDerivation {
buildPhase = ''
# Yarn writes cache directories etc to $HOME.
export HOME=$PWD/yarn_home
sed -i -e "s|process.env.ELASTICSEARCH_MAPPING_SCHEMA_VERSION|${version}|" src/index.js
yarn prod
'';
@ -75,14 +78,6 @@ pkgs.stdenv.mkDerivation {
cp -R ./dist/* $out/
cp netlify.toml $out/
'';
shellHook = ''
rm -rf frontend/node_modules
ln -sf ${yarnPkg}/libexec/${package.name}/node_modules frontend/
export PATH=$PWD/frontend/node_modules/.bin:$PATH
export ELASTICSEARCH_MAPPING_SCHEMA_VERSION=${version}
echo "============================"
echo "= To develop the frontend run: cd frontend && yarn dev ="
echo "============================"
'';
passthru.yarnPkg = yarnPkg;
}

View file

@ -25,13 +25,20 @@ import Html.Attributes
, id
, src
)
import Json.Decode
import Page.Flakes exposing (Model(..))
import Page.Home
import Page.Options
import Page.Packages
import RemoteData exposing (RemoteData(..))
import Route exposing (SearchType(..))
import Search exposing (Msg(..), defaultFlakeId)
import Search
exposing
( Msg(..)
, NixOSChannel
, decodeNixOSChannels
, defaultFlakeId
)
import Url
@ -44,6 +51,7 @@ type alias Flags =
, elasticsearchUrl : String
, elasticsearchUsername : String
, elasticsearchPassword : String
, nixosChannels : Json.Decode.Value
}
@ -51,6 +59,8 @@ type alias Model =
{ navKey : Browser.Navigation.Key
, route : Route.Route
, elasticsearch : Search.Options
, defaultNixOSChannel : String
, nixosChannels : List NixOSChannel
, page : Page
}
@ -70,6 +80,14 @@ init :
-> ( Model, Cmd Msg )
init flags url navKey =
let
nixosChannels =
case Json.Decode.decodeValue decodeNixOSChannels flags.nixosChannels of
Ok c ->
c
Err _ ->
{ default = "", channels = [] }
model =
{ navKey = navKey
, elasticsearch =
@ -78,6 +96,8 @@ init flags url navKey =
flags.elasticsearchUrl
flags.elasticsearchUsername
flags.elasticsearchPassword
, defaultNixOSChannel = nixosChannels.default
, nixosChannels = nixosChannels.channels
, page = NotFound
, route = Route.Home
}
@ -127,6 +147,7 @@ attemptQuery (( model, _ ) as pair) =
, Cmd.map msg <|
makeRequest
model.elasticsearch
model.nixosChannels
searchModel.searchType
searchModel.channel
(Maybe.withDefault "" searchModel.query)
@ -239,7 +260,7 @@ changeRouteTo currentModel url =
_ ->
Nothing
in
Page.Packages.init searchArgs modelPage
Page.Packages.init searchArgs currentModel.defaultNixOSChannel currentModel.nixosChannels modelPage
|> updateWith Packages PackagesMsg model
|> avoidReinit
|> attemptQuery
@ -254,7 +275,7 @@ changeRouteTo currentModel url =
_ ->
Nothing
in
Page.Options.init searchArgs modelPage
Page.Options.init searchArgs currentModel.defaultNixOSChannel currentModel.nixosChannels modelPage
|> updateWith Options OptionsMsg model
|> avoidReinit
|> attemptQuery
@ -269,7 +290,7 @@ changeRouteTo currentModel url =
_ ->
Nothing
in
Page.Flakes.init searchArgs modelPage
Page.Flakes.init searchArgs currentModel.defaultNixOSChannel currentModel.nixosChannels modelPage
|> updateWith Flakes FlakesMsg model
|> avoidReinit
|> attemptQuery
@ -300,19 +321,19 @@ update msg model =
changeRouteTo model url
( HomeMsg subMsg, Home subModel ) ->
Page.Home.update subMsg subModel
Page.Home.update subMsg subModel model.nixosChannels
|> updateWith Home HomeMsg model
( PackagesMsg subMsg, Packages subModel ) ->
Page.Packages.update model.navKey subMsg subModel
Page.Packages.update model.navKey subMsg subModel model.nixosChannels
|> updateWith Packages PackagesMsg model
( OptionsMsg subMsg, Options subModel ) ->
Page.Options.update model.navKey subMsg subModel
Page.Options.update model.navKey subMsg subModel model.nixosChannels
|> updateWith Options OptionsMsg model
( FlakesMsg subMsg, Flakes subModel ) ->
Page.Flakes.update model.navKey subMsg subModel
Page.Flakes.update model.navKey subMsg subModel model.nixosChannels
|> updateWith Flakes FlakesMsg model
( _, _ ) ->
@ -436,13 +457,13 @@ viewPage model =
div [] [ text "Welcome" ]
Packages packagesModel ->
Html.map (\m -> PackagesMsg m) <| Page.Packages.view packagesModel
Html.map (\m -> PackagesMsg m) <| Page.Packages.view model.nixosChannels packagesModel
Options optionsModel ->
Html.map (\m -> OptionsMsg m) <| Page.Options.view optionsModel
Html.map (\m -> OptionsMsg m) <| Page.Options.view model.nixosChannels optionsModel
Flakes flakesModel ->
Html.map (\m -> FlakesMsg m) <| Page.Flakes.view flakesModel
Html.map (\m -> FlakesMsg m) <| Page.Flakes.view model.nixosChannels flakesModel

View file

@ -35,6 +35,7 @@ import Route
import Search
exposing
( Msg(..)
, NixOSChannel
, viewFlakes
, viewResult
, viewSearchInput
@ -50,8 +51,13 @@ type Model
| PackagesModel Page.Packages.Model
init : Route.SearchArgs -> Maybe Model -> ( Model, Cmd Msg )
init searchArgs model =
init :
Route.SearchArgs
-> String
-> List NixOSChannel
-> Maybe Model
-> ( Model, Cmd Msg )
init searchArgs defaultNixOSChannel nixosChannels model =
let
-- init with respective module or with packages by default
searchType =
@ -60,10 +66,14 @@ init searchArgs model =
mapEitherModel m =
case ( searchType, m ) of
( OptionSearch, OptionModel model_ ) ->
Tuple.mapBoth OptionModel (Cmd.map OptionsMsg) <| Page.Options.init searchArgs <| Just model_
Tuple.mapBoth OptionModel (Cmd.map OptionsMsg) <|
Page.Options.init searchArgs defaultNixOSChannel nixosChannels <|
Just model_
( PackageSearch, PackagesModel model_ ) ->
Tuple.mapBoth PackagesModel (Cmd.map PackagesMsg) <| Page.Packages.init searchArgs <| Just model_
Tuple.mapBoth PackagesModel (Cmd.map PackagesMsg) <|
Page.Packages.init searchArgs defaultNixOSChannel nixosChannels <|
Just model_
_ ->
default
@ -71,10 +81,12 @@ init searchArgs model =
default =
case searchType of
PackageSearch ->
Tuple.mapBoth PackagesModel (Cmd.map PackagesMsg) <| Page.Packages.init searchArgs Nothing
Tuple.mapBoth PackagesModel (Cmd.map PackagesMsg) <|
Page.Packages.init searchArgs defaultNixOSChannel nixosChannels Nothing
OptionSearch ->
Tuple.mapBoth OptionModel (Cmd.map OptionsMsg) <| Page.Options.init searchArgs Nothing
Tuple.mapBoth OptionModel (Cmd.map OptionsMsg) <|
Page.Options.init searchArgs defaultNixOSChannel nixosChannels Nothing
( newModel, newCmd ) =
Maybe.withDefault default <| Maybe.map mapEitherModel model
@ -97,8 +109,9 @@ update :
Browser.Navigation.Key
-> Msg
-> Model
-> List NixOSChannel
-> ( Model, Cmd Msg )
update navKey msg model =
update navKey msg model nixosChannels =
case ( msg, model ) of
( OptionsMsg msg_, OptionModel model_ ) ->
case msg_ of
@ -110,6 +123,7 @@ update navKey msg model =
navKey
subMsg
model_
nixosChannels
in
( newModel, Cmd.map Page.Options.SearchMsg newCmd ) |> Tuple.mapBoth OptionModel (Cmd.map OptionsMsg)
@ -123,6 +137,7 @@ update navKey msg model =
navKey
subMsg
model_
nixosChannels
in
( newModel, Cmd.map Page.Packages.SearchMsg newCmd ) |> Tuple.mapBoth PackagesModel (Cmd.map PackagesMsg)
@ -134,8 +149,11 @@ update navKey msg model =
-- VIEW
view : Model -> Html Msg
view model =
view :
List NixOSChannel
-> Model
-> Html Msg
view nixosChannels model =
let
resultStatus result =
case result of
@ -172,8 +190,8 @@ view model =
)
)
[ h1 [] bodyTitle
, viewSearchInput outMsg categoryName Nothing model_.query
, viewResult outMsg Route.Flakes categoryName model_ viewSuccess viewBuckets <|
, viewSearchInput nixosChannels outMsg categoryName Nothing model_.query
, viewResult nixosChannels outMsg Route.Flakes categoryName model_ viewSuccess viewBuckets <|
viewFlakes outMsg model_.channel model_.searchType
]
@ -194,6 +212,7 @@ view model =
makeRequest :
Search.Options
-> List NixOSChannel
-> SearchType
-> String
-> String
@ -202,13 +221,14 @@ makeRequest :
-> Maybe String
-> Search.Sort
-> Cmd Msg
makeRequest options searchType index_id query from size maybeBuckets sort =
makeRequest options nixosChannels searchType index_id query from size maybeBuckets sort =
let
cmd =
case searchType of
PackageSearch ->
Search.makeRequest
(makeRequestBody searchType query from size maybeBuckets sort)
nixosChannels
index_id
Page.Packages.decodeResultItemSource
Page.Packages.decodeResultAggregations
@ -221,6 +241,7 @@ makeRequest options searchType index_id query from size maybeBuckets sort =
OptionSearch ->
Search.makeRequest
(makeRequestBody searchType query from size maybeBuckets sort)
nixosChannels
index_id
Page.Options.decodeResultItemSource
Page.Options.decodeResultAggregations

View file

@ -1,6 +1,7 @@
module Page.Home exposing (Model, Msg, init, update, view)
import Html exposing (Html, div, text)
import Search exposing (NixOSChannel)
@ -24,8 +25,12 @@ type Msg
= NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
update :
Msg
-> Model
-> List NixOSChannel
-> ( Model, Cmd Msg )
update msg model _ =
case msg of
NoOp ->
( model, Cmd.none )

View file

@ -45,7 +45,12 @@ import Http exposing (Body)
import Json.Decode
import Json.Decode.Pipeline
import Route exposing (SearchType)
import Search exposing (Details, decodeResolvedFlake)
import Search
exposing
( Details
, NixOSChannel
, decodeResolvedFlake
)
@ -82,11 +87,16 @@ type alias AggregationsAll =
}
init : Route.SearchArgs -> Maybe Model -> ( Model, Cmd Msg )
init searchArgs model =
init :
Route.SearchArgs
-> String
-> List NixOSChannel
-> Maybe Model
-> ( Model, Cmd Msg )
init searchArgs defaultNixOSChannel nixosChannels model =
let
( newModel, newCmd ) =
Search.init searchArgs model
Search.init searchArgs defaultNixOSChannel nixosChannels model
in
( newModel
, Cmd.map SearchMsg newCmd
@ -105,8 +115,9 @@ update :
Browser.Navigation.Key
-> Msg
-> Model
-> List NixOSChannel
-> ( Model, Cmd Msg )
update navKey msg model =
update navKey msg model nixosChannels =
case msg of
SearchMsg subMsg ->
let
@ -116,6 +127,7 @@ update navKey msg model =
navKey
subMsg
model
nixosChannels
in
( newModel, Cmd.map SearchMsg newCmd )
@ -124,12 +136,16 @@ update navKey msg model =
-- VIEW
view : Model -> Html Msg
view model =
view :
List NixOSChannel
-> Model
-> Html Msg
view nixosChannels model =
Search.view { toRoute = Route.Options, categoryName = "options" }
[ text "Search more than "
, strong [] [ text "10 000 options" ]
]
nixosChannels
model
viewSuccess
viewBuckets
@ -146,26 +162,28 @@ viewBuckets _ _ =
viewSuccess :
String
List NixOSChannel
-> String
-> Details
-> Maybe String
-> List (Search.ResultItem ResultItemSource)
-> Html Msg
viewSuccess channel showInstallDetails show hits =
viewSuccess nixosChannels channel showInstallDetails show hits =
ul []
(List.map
(viewResultItem channel showInstallDetails show)
(viewResultItem nixosChannels channel showInstallDetails show)
hits
)
viewResultItem :
String
List NixOSChannel
-> String
-> Details
-> Maybe String
-> Search.ResultItem ResultItemSource
-> Html Msg
viewResultItem channel _ show item =
viewResultItem nixosChannels channel _ show item =
let
showHtml value =
case Html.Parser.run <| String.trim value of
@ -229,7 +247,7 @@ viewResultItem channel _ show item =
|> Maybe.withDefault []
)
++ [ div [] [ text "Declared in" ]
, div [] <| findSource channel item.source
, div [] <| findSource nixosChannels channel item.source
]
else
@ -283,8 +301,12 @@ viewResultItem channel _ show item =
]
findSource : String -> ResultItemSource -> List (Html a)
findSource channel source =
findSource :
List NixOSChannel
-> String
-> ResultItemSource
-> List (Html a)
findSource nixosChannels channel source =
let
githubUrlPrefix branch =
"https://github.com/NixOS/nixpkgs/blob/" ++ branch ++ "/"
@ -297,7 +319,7 @@ findSource channel source =
value
asGithubLink value =
case Search.channelDetailsFromId channel of
case List.head (List.filter (\x -> x.id == channel) nixosChannels) of
Just channelDetails ->
a
[ href <| githubUrlPrefix channelDetails.branch ++ (value |> String.replace ":" "#L")
@ -342,6 +364,7 @@ findSource channel source =
makeRequest :
Search.Options
-> List NixOSChannel
-> SearchType
-> String
-> String
@ -350,9 +373,10 @@ makeRequest :
-> Maybe String
-> Search.Sort
-> Cmd Msg
makeRequest options _ channel query from size _ sort =
makeRequest options nixosChannels _ channel query from size _ sort =
Search.makeRequest
(makeRequestBody query from size sort)
nixosChannels
channel
decodeResultItemSource
decodeResultAggregations

View file

@ -51,6 +51,7 @@ import Route exposing (Route(..), SearchType)
import Search
exposing
( Details(..)
, NixOSChannel
, decodeResolvedFlake
, viewBucket
)
@ -162,11 +163,16 @@ initBuckets bucketsAsString =
|> Maybe.withDefault emptyBuckets
init : Route.SearchArgs -> Maybe Model -> ( Model, Cmd Msg )
init searchArgs model =
init :
Route.SearchArgs
-> String
-> List NixOSChannel
-> Maybe Model
-> ( Model, Cmd Msg )
init searchArgs defaultNixOSChannel nixosChannels model =
let
( newModel, newCmd ) =
Search.init searchArgs model
Search.init searchArgs defaultNixOSChannel nixosChannels model
in
( newModel
, Cmd.map SearchMsg newCmd
@ -195,8 +201,9 @@ update :
Browser.Navigation.Key
-> Msg
-> Model
-> List NixOSChannel
-> ( Model, Cmd Msg )
update navKey msg model =
update navKey msg model nixosChannels =
case msg of
SearchMsg subMsg ->
let
@ -206,6 +213,7 @@ update navKey msg model =
navKey
subMsg
model
nixosChannels
in
( newModel, Cmd.map SearchMsg newCmd )
@ -214,12 +222,16 @@ update navKey msg model =
-- VIEW
view : Model -> Html Msg
view model =
view :
List NixOSChannel
-> Model
-> Html Msg
view nixosChannels model =
Search.view { toRoute = Route.Packages, categoryName = "packages" }
[ text "Search more than "
, strong [] [ text "80 000 packages" ]
]
nixosChannels
model
viewSuccess
viewBuckets
@ -282,26 +294,28 @@ filterPlatformsBucket =
viewSuccess :
String
List NixOSChannel
-> String
-> Details
-> Maybe String
-> List (Search.ResultItem ResultItemSource)
-> Html Msg
viewSuccess channel showInstallDetails show hits =
viewSuccess nixosChannels channel showInstallDetails show hits =
ul []
(List.map
(viewResultItem channel showInstallDetails show)
(viewResultItem nixosChannels channel showInstallDetails show)
hits
)
viewResultItem :
String
List NixOSChannel
-> String
-> Details
-> Maybe String
-> Search.ResultItem ResultItemSource
-> Html Msg
viewResultItem channel showInstallDetails show item =
viewResultItem nixosChannels channel showInstallDetails show item =
let
optionals b l =
if b then
@ -368,7 +382,7 @@ viewResultItem channel showInstallDetails show item =
)
|> Maybe.withDefault []
)
++ renderSource item channel trapClick createShortDetailsItem createGithubUrl
++ renderSource item nixosChannels channel trapClick createShortDetailsItem createGithubUrl
++ (let
licenses =
item.source.licenses
@ -450,7 +464,7 @@ viewResultItem channel showInstallDetails show item =
]
showPlatform platform =
case Search.channelDetailsFromId channel of
case List.head (List.filter (\x -> x.id == channel) nixosChannels) of
Just channelDetails ->
let
url =
@ -650,8 +664,23 @@ viewResultItem channel showInstallDetails show item =
)
renderSource : Search.ResultItem ResultItemSource -> String -> Html.Attribute Msg -> (String -> String -> Html Msg) -> (String -> String -> String) -> List (Html Msg)
renderSource item channel trapClick createShortDetailsItem createGithubUrl =
renderSource :
Search.ResultItem ResultItemSource
-> List NixOSChannel
-> String
-> Html.Attribute Msg
->
(String
-> String
-> Html Msg
)
->
(String
-> String
-> String
)
-> List (Html Msg)
renderSource item nixosChannels channel trapClick createShortDetailsItem createGithubUrl =
let
makeLink text url =
[ li [ trapClick ] [ createShortDetailsItem text url ] ]
@ -660,7 +689,7 @@ renderSource item channel trapClick createShortDetailsItem createGithubUrl =
item.source.position
|> Maybe.map
(\pos ->
case Search.channelDetailsFromId channel of
case List.head (List.filter (\x -> x.id == channel) nixosChannels) of
Nothing ->
[]
@ -684,6 +713,7 @@ renderSource item channel trapClick createShortDetailsItem createGithubUrl =
makeRequest :
Search.Options
-> List NixOSChannel
-> SearchType
-> String
-> String
@ -692,9 +722,10 @@ makeRequest :
-> Maybe String
-> Search.Sort
-> Cmd Msg
makeRequest options _ channel query from size maybeBuckets sort =
makeRequest options nixosChannels _ channel query from size maybeBuckets sort =
Search.makeRequest
(makeRequestBody query from size maybeBuckets sort)
nixosChannels
channel
decodeResultItemSource
decodeResultAggregations

View file

@ -4,15 +4,16 @@ module Search exposing
, Details(..)
, Model
, Msg(..)
, NixOSChannel
, NixOSChannelStatus
, Options
, ResultHits
, ResultItem
, SearchResult
, Sort(..)
, channelDetailsFromId
, channels
, closeButton
, decodeAggregation
, decodeNixOSChannels
, decodeResolvedFlake
, decodeResult
, defaultFlakeId
@ -153,6 +154,68 @@ type Sort
| AlphabeticallyDesc
type alias NixOSChannels =
{ default : String
, channels : List NixOSChannel
}
type alias NixOSChannel =
{ id : String
, status : NixOSChannelStatus
, jobset : String
, branch : String
}
type NixOSChannelStatus
= Rolling
| Stable
| Beta
channelTitle : NixOSChannel -> String
channelTitle channel =
if channel.status == Beta
then channel.id ++ " (Beta)"
else channel.id
decodeNixOSChannels : Json.Decode.Decoder NixOSChannels
decodeNixOSChannels =
Json.Decode.map2 NixOSChannels
(Json.Decode.field "default" Json.Decode.string)
(Json.Decode.field "channels" (Json.Decode.list decodeNixOSChannel))
decodeNixOSChannel : Json.Decode.Decoder NixOSChannel
decodeNixOSChannel =
Json.Decode.map4 NixOSChannel
(Json.Decode.field "id" Json.Decode.string)
(Json.Decode.field "status"
(Json.Decode.string
|> Json.Decode.andThen
(\status ->
case status of
"rolling" ->
Json.Decode.succeed Rolling
"stable" ->
Json.Decode.succeed Stable
"beta" ->
Json.Decode.succeed Beta
_ ->
Json.Decode.fail ("Unknown status: " ++ status)
)
)
)
(Json.Decode.field "jobset" Json.Decode.string)
(Json.Decode.field "branch" Json.Decode.string)
type alias ResolvedFlake =
{ type_ : String
, owner : Maybe String
@ -206,9 +269,11 @@ decodeResolvedFlake =
init :
Route.SearchArgs
-> String
-> List NixOSChannel
-> Maybe (Model a b)
-> ( Model a b, Cmd (Msg a b) )
init args maybeModel =
init args defaultNixOSChannel nixosChannels maybeModel =
let
getField getFn default =
maybeModel
@ -216,7 +281,7 @@ init args maybeModel =
|> Maybe.withDefault default
modelChannel =
getField .channel defaultChannel
getField .channel defaultNixOSChannel
modelFrom =
getField .from 0
@ -249,7 +314,7 @@ init args maybeModel =
, showInstallDetails = Unset
, searchType = Maybe.withDefault Route.PackageSearch args.type_
}
|> ensureLoading
|> ensureLoading nixosChannels
, Browser.Dom.focus "search-query-input" |> Task.attempt (\_ -> NoOp)
)
@ -262,9 +327,14 @@ shouldLoad model =
ensureLoading :
Model a b
List NixOSChannel
-> Model a b
ensureLoading model =
-> Model a b
ensureLoading nixosChannels model =
let
channels =
List.map .id nixosChannels
in
if model.query /= Nothing && model.query /= Just "" && List.member model.channel channels then
{ model | result = RemoteData.Loading }
@ -324,8 +394,9 @@ update :
-> Browser.Navigation.Key
-> Msg a b
-> Model a b
-> List NixOSChannel
-> ( Model a b, Cmd (Msg a b) )
update toRoute navKey msg model =
update toRoute navKey msg model nixosChannels =
case msg of
NoOp ->
( model
@ -338,7 +409,7 @@ update toRoute navKey msg model =
, show = Nothing
, from = 0
}
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
ToggleSort ->
@ -359,7 +430,7 @@ update toRoute navKey msg model =
, show = Nothing
, from = 0
}
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
ChannelChange channel ->
@ -369,7 +440,7 @@ update toRoute navKey msg model =
, buckets = Nothing
, from = 0
}
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
FlakeChange flake ->
@ -379,7 +450,7 @@ update toRoute navKey msg model =
, buckets = Nothing
, from = 0
}
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
SubjectChange subject ->
@ -389,7 +460,7 @@ update toRoute navKey msg model =
, buckets = Nothing
, from = 0
}
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
QueryInput query ->
@ -403,7 +474,7 @@ update toRoute navKey msg model =
, show = Nothing
, buckets = Nothing
}
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
QueryResponse result ->
@ -426,7 +497,7 @@ update toRoute navKey msg model =
ChangePage from ->
{ model | from = from }
|> ensureLoading
|> ensureLoading nixosChannels
|> pushUrl toRoute navKey
ShowInstallDetails details ->
@ -470,123 +541,11 @@ createUrl toRoute model =
-- VIEW
type Channel
= Unstable
| Release_21_11
{-| TODO: we should consider using more dynamic approach here
and load channels from apis similar to what status page does
-}
type alias ChannelDetails =
{ id : String
, title : String
, jobset : String
, branch : String
}
defaultChannel : String
defaultChannel =
"21.11"
channelDetails : Channel -> ChannelDetails
channelDetails channel =
case channel of
Unstable ->
ChannelDetails "unstable" "unstable" "nixos/trunk-combined" "nixos-unstable"
Release_21_11 ->
ChannelDetails "21.11" "21.11" "nixos/release-21.11" "nixos-21.11"
channelFromId : String -> Maybe Channel
channelFromId channel_id =
case channel_id of
"unstable" ->
Just Unstable
"21.11" ->
Just Release_21_11
_ ->
Nothing
channelDetailsFromId : String -> Maybe ChannelDetails
channelDetailsFromId channel_id =
channelFromId channel_id
|> Maybe.map channelDetails
channels : List String
channels =
[ "21.11"
, "unstable"
]
defaultFlakeId : String
defaultFlakeId =
"group-manual"
-- flakeFromId : String -> Maybe Flake
-- flakeFromId flake_id =
-- let
-- find : String -> List Flake -> Maybe Flake
-- find id_ list =
-- case list of
-- flake :: rest ->
-- if flake.id == id_ then
-- Just flake
--
-- else
-- find id_ rest
--
-- [] ->
-- Nothing
-- in
-- find flake_id flakes
--
--
-- flakeIds : List String
-- flakeIds =
-- List.map .id flakes
--
--
-- flakes : List Flake
-- flakes =
-- [ { id = "latest-nixos-21.11-latest"
-- , isNixpkgs = True
-- , title = "Nixpkgs 21.11"
-- , source = ""
-- }
-- , { id = "latest-nixos-21.05-latest"
-- , isNixpkgs = True
-- , title = "Nixpkgs 21.05"
-- , source = ""
-- }
-- , { id = "nixos-21.09-latest"
-- , isNixpkgs = True
-- , title = "Nixpkgs 21.09"
-- , source = ""
-- }
-- , { id = "latest-nixos-unstable"
-- , isNixpkgs = True
-- , title = "Nixpkgs Unstable"
-- , source = ""
-- }
-- , { id = "flakes"
-- , isNixpkgs = False
-- , title = "Public Flakes"
-- , source = ""
-- }
-- ]
sortBy : List Sort
sortBy =
[ Relevance
@ -730,9 +689,11 @@ view :
, categoryName : String
}
-> List (Html c)
-> List NixOSChannel
-> Model a b
->
(String
(List NixOSChannel
-> String
-> Details
-> Maybe String
-> List (ResultItem a)
@ -746,7 +707,7 @@ view :
-> (Msg a b -> c)
-> List (Html c)
-> Html c
view { toRoute, categoryName } title model viewSuccess viewBuckets outMsg searchBuckets =
view { toRoute, categoryName } title nixosChannels model viewSuccess viewBuckets outMsg searchBuckets =
let
resultStatus =
case model.result of
@ -773,8 +734,8 @@ view { toRoute, categoryName } title model viewSuccess viewBuckets outMsg search
)
)
[ h1 [] title
, viewSearchInput outMsg categoryName (Just model.channel) model.query
, viewResult outMsg toRoute categoryName model viewSuccess viewBuckets searchBuckets
, viewSearchInput nixosChannels outMsg categoryName (Just model.channel) model.query
, viewResult nixosChannels outMsg toRoute categoryName model viewSuccess viewBuckets searchBuckets
]
@ -810,12 +771,14 @@ viewFlakes outMsg _ selectedCategory =
viewResult :
(Msg a b -> c)
List NixOSChannel
-> (Msg a b -> c)
-> Route.SearchRoute
-> String
-> Model a b
->
(String
(List NixOSChannel
-> String
-> Details
-> Maybe String
-> List (ResultItem a)
@ -828,7 +791,7 @@ viewResult :
)
-> List (Html c)
-> Html c
viewResult outMsg toRoute categoryName model viewSuccess viewBuckets searchBuckets =
viewResult nixosChannels outMsg toRoute categoryName model viewSuccess viewBuckets searchBuckets =
case model.result of
RemoteData.NotAsked ->
div [] []
@ -855,14 +818,14 @@ viewResult outMsg toRoute categoryName model viewSuccess viewBuckets searchBucke
div [ class "search-results" ]
[ ul [ class "search-sidebar" ] <| List.append searchBuckets buckets
, div []
(viewResults model result viewSuccess toRoute outMsg categoryName)
(viewResults nixosChannels model result viewSuccess toRoute outMsg categoryName)
]
else
div [ class "search-results" ]
[ ul [ class "search-sidebar" ] searchBuckets
, div []
(viewResults model result viewSuccess toRoute outMsg categoryName)
(viewResults nixosChannels model result viewSuccess toRoute outMsg categoryName)
]
RemoteData.Failure error ->
@ -960,12 +923,13 @@ viewBucket title buckets searchMsgFor selectedBucket sets =
viewSearchInput :
(Msg a b -> c)
List NixOSChannel
-> (Msg a b -> c)
-> String
-> Maybe String
-> Maybe String
-> Html c
viewSearchInput outMsg categoryName selectedChannel searchQuery =
viewSearchInput nixosChannels outMsg categoryName selectedChannel searchQuery =
form
[ onSubmit (outMsg QueryInputSubmit)
, class "search-input"
@ -986,17 +950,22 @@ viewSearchInput outMsg categoryName selectedChannel searchQuery =
[ text "Search" ]
]
:: (selectedChannel
|> Maybe.map (\x -> [ div [] (viewChannels outMsg x) ])
|> Maybe.map (\x -> [ div [] (viewChannels nixosChannels outMsg x) ])
|> Maybe.withDefault []
)
)
viewChannels :
(Msg a b -> c)
List NixOSChannel
-> (Msg a b -> c)
-> String
-> List (Html c)
viewChannels outMsg selectedChannel =
viewChannels nixosChannels outMsg selectedChannel =
let
channels =
List.map .id nixosChannels
in
List.append
[ div []
[ h4 [] [ text "Channel: " ]
@ -1004,23 +973,19 @@ viewChannels outMsg selectedChannel =
[ class "btn-group"
, attribute "data-toggle" "buttons-radio"
]
(List.filterMap
(\channelId ->
channelDetailsFromId channelId
|> Maybe.map
(\channel ->
button
[ type_ "button"
, classList
[ ( "btn", True )
, ( "active", channel.id == selectedChannel )
]
, onClick <| outMsg (ChannelChange channel.id)
]
[ text channel.title ]
)
(List.map
(\channel ->
button
[ type_ "button"
, classList
[ ( "btn", True )
, ( "active", channel.id == selectedChannel )
]
, onClick <| outMsg (ChannelChange channel.id)
]
[ text <| channelTitle channel ]
)
channels
nixosChannels
)
]
]
@ -1037,10 +1002,12 @@ viewChannels outMsg selectedChannel =
viewResults :
Model a b
List NixOSChannel
-> Model a b
-> SearchResult a b
->
(String
(List NixOSChannel
-> String
-> Details
-> Maybe String
-> List (ResultItem a)
@ -1050,7 +1017,7 @@ viewResults :
-> (Msg a b -> c)
-> String
-> List (Html c)
viewResults model result viewSuccess _ outMsg categoryName =
viewResults nixosChannels model result viewSuccess _ outMsg categoryName =
let
from =
String.fromInt (model.from + 1)
@ -1093,7 +1060,7 @@ viewResults model result viewSuccess _ outMsg categoryName =
)
)
]
, viewSuccess model.channel model.showInstallDetails model.show result.hits.hits
, viewSuccess nixosChannels model.channel model.showInstallDetails model.show result.hits.hits
, Html.map outMsg <| viewPager model result.hits.total.value
]
@ -1379,6 +1346,7 @@ makeRequestBody query from sizeRaw sort type_ sortField otherSortFields bucketsF
makeRequest :
Http.Body
-> List NixOSChannel
-> String
-> Json.Decode.Decoder a
-> Json.Decode.Decoder b
@ -1386,10 +1354,15 @@ makeRequest :
-> (RemoteData.WebData (SearchResult a b) -> Msg a b)
-> Maybe String
-> Cmd (Msg a b)
makeRequest body channel decodeResultItemSource decodeResultAggregations options responseMsg tracker =
makeRequest body nixosChannels channel decodeResultItemSource decodeResultAggregations options responseMsg tracker =
let
branch : String
branch =
Maybe.map (\details -> details.branch) (channelDetailsFromId channel) |> Maybe.withDefault channel
nixosChannels
|> List.filter (\x -> x.id == channel)
|> List.head
|> Maybe.map (\x -> x.branch)
|> Maybe.withDefault channel
index =
"latest-" ++ String.fromInt options.mappingSchemaVersion ++ "-" ++ branch

View file

@ -6,9 +6,10 @@ const {Elm} = require('./Main');
Elm.Main.init({
flags: {
elasticsearchMappingSchemaVersion: parseInt(process.env.ELASTICSEARCH_MAPPING_SCHEMA_VERSION) || 0,
elasticsearchMappingSchemaVersion: parseInt(process.env.ELASTICSEARCH_MAPPING_SCHEMA_VERSION),
elasticsearchUrl: process.env.ELASTICSEARCH_URL || 'https://nixos-search-5886075189.us-east-1.bonsaisearch.net:443',
elasticsearchUsername : process.env.ELASTICSEARCH_USERNAME || 'z3ZFJ6y2mR',
elasticsearchPassword : process.env.ELASTICSEARCH_PASSWORD || 'ds8CEvALPf9pui7XG'
elasticsearchPassword : process.env.ELASTICSEARCH_PASSWORD || 'ds8CEvALPf9pui7XG',
nixosChannels : JSON.parse(process.env.NIXOS_CHANNELS)
}
});

View file

@ -27,7 +27,8 @@ var common = {
},
plugins: [
new webpack.EnvironmentPlugin([
"ELASTICSEARCH_MAPPING_SCHEMA_VERSION"
"ELASTICSEARCH_MAPPING_SCHEMA_VERSION",
"NIXOS_CHANNELS"
]),
new HTMLWebpackPlugin({
// Use this template to get basic responsive meta tags