diff --git a/doc/manual/rl-next/flake-metadata-time.md b/doc/manual/rl-next/flake-metadata-time.md new file mode 100644 index 000000000..8664b5a75 --- /dev/null +++ b/doc/manual/rl-next/flake-metadata-time.md @@ -0,0 +1,28 @@ +--- +synopsis: "`nix flake metadata` prints modified date" +cls: 1700 +credits: jade +category: Improvements +--- + +Ever wonder "gee, when *did* I update nixpkgs"? +Wonder no more, because `nix flake metadata` now simply tells you the times every locked flake input was updated: + +``` +<...> +Description: The purely functional package manager +Path: /nix/store/c91yi8sxakc2ry7y4ac1smzwka4l5p78-source +Revision: c52cff582043838bbe29768e7da232483d52b61d-dirty +Last modified: 2024-07-31 22:15:54 +Inputs: +├───flake-compat: github:edolstra/flake-compat/0f9255e01c2351cc7d116c072cb317785dd33b33 +│ Last modified: 2023-10-04 06:37:54 +├───nix2container: github:nlewo/nix2container/3853e5caf9ad24103b13aa6e0e8bcebb47649fe4 +│ Last modified: 2024-07-10 13:15:56 +├───nixpkgs: github:NixOS/nixpkgs/e21630230c77140bc6478a21cd71e8bb73706fce +│ Last modified: 2024-07-25 11:26:27 +├───nixpkgs-regression: github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2 +│ Last modified: 2022-01-24 11:20:45 +└───pre-commit-hooks: github:cachix/git-hooks.nix/f451c19376071a90d8c58ab1a953c6e9840527fd + Last modified: 2024-07-15 04:21:09 +``` diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 9d18b81b8..672930342 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -209,6 +209,11 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON { auto lockedFlake = lockFlake(); auto & flake = lockedFlake.flake; + auto formatTime = [](time_t time) -> std::string { + std::ostringstream os{}; + os << std::put_time(std::localtime(&time), "%F %T"); + return os.str(); + }; if (json) { nlohmann::json j; @@ -260,7 +265,7 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON if (auto lastModified = flake.lockedRef.input.getLastModified()) logger->cout( ANSI_BOLD "Last modified:" ANSI_NORMAL " %s", - std::put_time(std::localtime(&*lastModified), "%F %T")); + formatTime(*lastModified)); if (!lockedFlake.lockFile.root->inputs.empty()) logger->cout(ANSI_BOLD "Inputs:" ANSI_NORMAL); @@ -275,16 +280,25 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON bool last = i + 1 == node.inputs.size(); if (auto lockedNode = std::get_if<0>(&input.second)) { - logger->cout("%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s", - prefix + (last ? treeLast : treeConn), input.first, + // ├───agenix: github:ryantm/agenix/8d37c5bdeade12b6479c85acd133063ab53187a0 + logger->cout("%s%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s", + prefix, last ? treeLast : treeConn, input.first, (*lockedNode)->lockedRef); + // ├───lix: https://git.lix.systems/api/v1/repos/lix-project <....> + // │ Last modified: 2024-07-31 21:01:34 + if (auto lastModified = (*lockedNode)->lockedRef.input.getLastModified()) { + logger->cout("%s%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s", + prefix, last ? treeNull : treeLine, "Last modified", formatTime(*lastModified)); + } + bool firstVisit = visited.insert(*lockedNode).second; if (firstVisit) recurse(**lockedNode, prefix + (last ? treeNull : treeLine)); } else if (auto follows = std::get_if<1>(&input.second)) { - logger->cout("%s" ANSI_BOLD "%s" ANSI_NORMAL " follows input '%s'", - prefix + (last ? treeLast : treeConn), input.first, + // │ ├───darwin follows input 'flake-utils' + logger->cout("%s%s" ANSI_BOLD "%s" ANSI_NORMAL " follows input '%s'", + prefix, last ? treeLast : treeConn, input.first, printInputPath(*follows)); } } diff --git a/tests/functional/flakes/flake-metadata.sh b/tests/functional/flakes/flake-metadata.sh new file mode 100644 index 000000000..ab5a69b3a --- /dev/null +++ b/tests/functional/flakes/flake-metadata.sh @@ -0,0 +1,36 @@ +source ./common.sh + +flakeDir=$TEST_ROOT/flake +mkdir -p "$flakeDir" + +cat > "$flakeDir/flake.nix" <<-'EOF' +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; + flake-utils.url = "github:numtide/flake-utils"; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + lanzaboote = { + url = "github:nix-community/lanzaboote"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "flake-utils"; + inputs.flake-compat.follows = "flake-compat"; + }; + }; + + outputs = { ... }: {}; +} +EOF + +cp flake-metadata/flake.lock "$flakeDir" +touch -d @1000 "$flakeDir/flake.nix" "$flakeDir/flake.lock" "$flakeDir" + +# For some reason we use NIX_STORE_DIR which causes unstable paths. This is +# goofy. We can just use --store, which sets rootDir and does not have this +# problem. +actualStore=$NIX_STORE_DIR +unset NIX_STORE_DIR +NOCOLOR=1 TZ=UTC LC_ALL=C.UTF-8 nix flake metadata --store "$actualStore" "$flakeDir" | grep -v -e 'Locked URL:' -e 'Resolved URL:' > "$TEST_ROOT/metadata.out.actual" +diff -u flake-metadata/metadata.out.expected "$TEST_ROOT/metadata.out.actual" diff --git a/tests/functional/flakes/flake-metadata/flake.lock b/tests/functional/flakes/flake-metadata/flake.lock new file mode 100644 index 000000000..62b7dc3e8 --- /dev/null +++ b/tests/functional/flakes/flake-metadata/flake.lock @@ -0,0 +1,245 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711299236, + "narHash": "sha256-6/JsyozOMKN8LUGqWMopKTSiK8N79T8Q+hcxu2KkTXg=", + "owner": "ipetkov", + "repo": "crane", + "rev": "880573f80d09e18a11713f402b9e6172a085449f", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709336216, + "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "pre-commit-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "flake-compat": [ + "flake-compat" + ], + "flake-parts": "flake-parts", + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks-nix": "pre-commit-hooks-nix", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1713369831, + "narHash": "sha256-G4OGxvlIIjphpkxcRAkf1QInYsAeqbfNh6Yl1JLy2uM=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "850f27322239f8cfa56b122cc9a278ab99a49015", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "lanzaboote", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1719824438, + "narHash": "sha256-pY0wosAgcr9W4vmGML0T3BVhQiGuKoozCbs2t+Je1zc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "7f993cdf26ccef564eabf31fdb40d140821e12bc", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1710695816, + "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks-nix": { + "inputs": { + "flake-compat": [ + "lanzaboote", + "flake-compat" + ], + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1710923068, + "narHash": "sha256-6hOpUiuxuwpXXc/xfJsBUJeqqgGI+JMJuLo45aG3cKc=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "e611897ddfdde3ed3eaac4758635d7177ff78673", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "lanzaboote": "lanzaboote", + "nixpkgs": "nixpkgs" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711246447, + "narHash": "sha256-g9TOluObcOEKewFo2fR4cn51Y/jSKhRRo4QZckHLop0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "dcc802a6ec4e9cc6a1c8c393327f0c42666f22e4", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/tests/functional/flakes/flake-metadata/metadata.out.expected b/tests/functional/flakes/flake-metadata/metadata.out.expected new file mode 100644 index 000000000..72e57eca7 --- /dev/null +++ b/tests/functional/flakes/flake-metadata/metadata.out.expected @@ -0,0 +1,36 @@ +Path: /nix/store/gaxb42z68bcr8lch467shvmnhjjzgd8b-source +Last modified: 1970-01-01 00:16:40 +Inputs: +├───flake-compat: github:edolstra/flake-compat/0f9255e01c2351cc7d116c072cb317785dd33b33 +│ Last modified: 2023-10-04 13:37:54 +├───flake-utils: github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a +│ Last modified: 2024-03-11 08:33:50 +│ └───systems: github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e +│ Last modified: 2023-04-09 08:27:08 +├───lanzaboote: github:nix-community/lanzaboote/850f27322239f8cfa56b122cc9a278ab99a49015 +│ Last modified: 2024-04-17 16:03:51 +│ ├───crane: github:ipetkov/crane/880573f80d09e18a11713f402b9e6172a085449f +│ │ Last modified: 2024-03-24 16:53:56 +│ │ └───nixpkgs follows input 'lanzaboote/nixpkgs' +│ ├───flake-compat follows input 'flake-compat' +│ ├───flake-parts: github:hercules-ci/flake-parts/f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2 +│ │ Last modified: 2024-03-01 23:36:56 +│ │ └───nixpkgs-lib follows input 'lanzaboote/nixpkgs' +│ ├───flake-utils follows input 'flake-utils' +│ ├───nixpkgs follows input 'nixpkgs' +│ ├───pre-commit-hooks-nix: github:cachix/pre-commit-hooks.nix/e611897ddfdde3ed3eaac4758635d7177ff78673 +│ │ Last modified: 2024-03-20 08:24:28 +│ │ ├───flake-compat follows input 'lanzaboote/flake-compat' +│ │ ├───flake-utils follows input 'lanzaboote/flake-utils' +│ │ ├───gitignore: github:hercules-ci/gitignore.nix/637db329424fd7e46cf4185293b9cc8c88c95394 +│ │ │ Last modified: 2024-02-28 02:28:52 +│ │ │ └───nixpkgs follows input 'lanzaboote/pre-commit-hooks-nix/nixpkgs' +│ │ ├───nixpkgs follows input 'lanzaboote/nixpkgs' +│ │ └───nixpkgs-stable: github:NixOS/nixpkgs/614b4613980a522ba49f0d194531beddbb7220d3 +│ │ Last modified: 2024-03-17 17:16:56 +│ └───rust-overlay: github:oxalica/rust-overlay/dcc802a6ec4e9cc6a1c8c393327f0c42666f22e4 +│ Last modified: 2024-03-24 02:14:07 +│ ├───flake-utils follows input 'lanzaboote/flake-utils' +│ └───nixpkgs follows input 'lanzaboote/nixpkgs' +└───nixpkgs: github:nixos/nixpkgs/7f993cdf26ccef564eabf31fdb40d140821e12bc + Last modified: 2024-07-01 09:00:38 diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 7a9c7182f..2b5dfe422 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -69,8 +69,9 @@ functional_tests_scripts = [ 'flakes/unlocked-override.sh', 'flakes/absolute-paths.sh', 'flakes/build-paths.sh', - 'flakes/flake-registry.sh', 'flakes/flake-in-submodule.sh', + 'flakes/flake-metadata.sh', + 'flakes/flake-registry.sh', 'flakes/subdir-flake.sh', 'gc.sh', 'nix-collect-garbage-d.sh',