Skip to content

Commit 2ccb9f5

Browse files
committedDec 6, 2019
command-not-found: drop perl dependency
Faster startup and remove some perl packages from the default nixos closure. Eventually we could remove perl completely from the default nixos closure.
1 parent 5c54b35 commit 2ccb9f5

File tree

4 files changed

+100
-65
lines changed

4 files changed

+100
-65
lines changed
 

Diff for: ‎nixos/modules/programs/command-not-found/command-not-found.nix

+2-14
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,8 @@ with lib;
99

1010
let
1111
cfg = config.programs.command-not-found;
12-
commandNotFound = pkgs.substituteAll {
13-
name = "command-not-found";
14-
dir = "bin";
15-
src = ./command-not-found.pl;
16-
isExecutable = true;
17-
inherit (pkgs) perl;
18-
inherit (cfg) dbPath;
19-
perlFlags = concatStrings (map (path: "-I ${path}/${pkgs.perl.libPrefix} ")
20-
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
21-
};
22-
23-
in
24-
25-
{
12+
commandNotFound = pkgs.callPackage ./. { dbPath = cfg.dbPath; };
13+
in {
2614
options.programs.command-not-found = {
2715

2816
enable = mkOption {

Diff for: ‎nixos/modules/programs/command-not-found/command-not-found.pl

-51
This file was deleted.

Diff for: ‎nixos/modules/programs/command-not-found/default.nix

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{ stdenv, sqlite, pkgconfig,
2+
dbPath ? "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite"
3+
}:
4+
# build with: nix-build -E '(import <nixpkgs> {}).callPackage ./. {}'
5+
stdenv.mkDerivation {
6+
name = "command-not-found";
7+
src = ./src;
8+
buildInputs = [ sqlite ];
9+
nativeBuildInputs = [ pkgconfig ];
10+
installPhase = ''
11+
mkdir -p $out/bin
12+
$CXX -O2 -std=c++17 -Wall \
13+
-DDB_PATH=\"${dbPath}\" \
14+
-DNIX_SYSTEM=\"${stdenv.system}\" \
15+
$(pkg-config --cflags --libs sqlite3) \
16+
-o $out/bin/command-not-found \
17+
command-not-found.cpp
18+
'';
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include <memory>
2+
#include <stdio.h>
3+
#include <functional>
4+
#include <string>
5+
#include <vector>
6+
7+
#include <sqlite3.h>
8+
9+
int queryPackages(std::string system, std::string program,
10+
std::vector<std::string> &packages) {
11+
sqlite3 *raw_db = nullptr;
12+
if (sqlite3_open(DB_PATH, &raw_db) != SQLITE_OK) {
13+
fprintf(stderr, "cannot open database \"%s\": %s\n", DB_PATH,
14+
sqlite3_errmsg(raw_db));
15+
};
16+
std::unique_ptr<sqlite3, std::function<void(sqlite3*)>> db(raw_db, [](auto db) { sqlite3_close(db); });
17+
18+
const char *sql =
19+
"select package from Programs where system = ? and name = ?;";
20+
21+
sqlite3_stmt *raw_stmt = nullptr;
22+
if (sqlite3_prepare_v2(db.get(), sql, -1, &raw_stmt, NULL) != SQLITE_OK) {
23+
fprintf(stderr, "Failed to prepare query: %s\n", sqlite3_errmsg(db.get()));
24+
return 1;
25+
}
26+
std::unique_ptr<sqlite3_stmt, std::function<void(sqlite3_stmt*)>> stmt(raw_stmt, [](auto stmt) { sqlite3_finalize(stmt); });
27+
28+
if (sqlite3_bind_text(stmt.get(), 1, system.c_str(), -1, 0) != SQLITE_OK) {
29+
fprintf(stderr, "Failed to bind system parameter: %s\n",
30+
sqlite3_errmsg(db.get()));
31+
return 1;
32+
};
33+
if (sqlite3_bind_text(stmt.get(), 2, program.c_str(), -1, 0) != SQLITE_OK) {
34+
fprintf(stderr, "Failed to bind program parameter: %s\n",
35+
sqlite3_errmsg(db.get()));
36+
return 1;
37+
};
38+
39+
while (sqlite3_step(stmt.get()) == SQLITE_ROW) {
40+
packages.push_back((const char *)(sqlite3_column_text(stmt.get(), 0)));
41+
}
42+
43+
return 0;
44+
}
45+
46+
int main(int argc, char **argv) {
47+
const char *system = getenv("NIX_SYSTEM");
48+
const char *program = argv[1];
49+
50+
if (!system) {
51+
system = NIX_SYSTEM;
52+
}
53+
54+
if (argc < 2) {
55+
fprintf(stderr, "USAGE: %s PROGRAM\n", argv[0]);
56+
return 1;
57+
}
58+
59+
std::vector<std::string> packages = {};
60+
if (queryPackages(system, program, packages) < 0) {
61+
return 1;
62+
};
63+
64+
if (packages.size()) {
65+
auto advice = packages.size() > 1 ?
66+
"It is provided by several packages. You can install it by typing on of the of following commands:\n" :
67+
"You can install it by typing:";
68+
fprintf(stderr,
69+
"The program '%s' is currently not installed. %s\n",
70+
program, advice);
71+
for (auto pkg : packages) {
72+
fprintf(stderr, " nix-env -iA nixos.%s\n", pkg.c_str());
73+
}
74+
} else {
75+
fprintf(stderr, "%s: command not found\n", program);
76+
}
77+
78+
return 127;
79+
}

0 commit comments

Comments
 (0)
Please sign in to comment.