nix hash convert: added

This deviated from the proposal! See comments on the issue.

https://github.com/NixOS/nix/issues/8876
This commit is contained in:
Peter Kolloch 2023-11-25 17:35:24 +01:00
parent 156ea78d74
commit 6bbd900d4f
2 changed files with 81 additions and 1 deletions

View file

@ -132,12 +132,75 @@ struct CmdToBase : Command
}
};
/**
* `nix hash convert`
*/
struct CmdHashConvert : Command
{
std::optional<HashFormat> from;
HashFormat to;
std::optional<HashType> type;
std::vector<std::string> hashStrings;
CmdHashConvert(): to(HashFormat::SRI) {
addFlag({
.longName = "from",
// TODO: List format choices. Maybe introduce a constant?
.description = "The format of the input hash.",
.labels = {"hash format"},
.handler = {[this](std::string str) {
from = parseHashFormat(str);
}},
});
addFlag({
.longName = "to",
// TODO: List format choices. Maybe introduce a constant?
.description = "The format of the output hash.",
.labels = {"hash format"},
.handler = {[this](std::string str) {
to = parseHashFormat(str);
}},
});
addFlag({
.longName = "type",
.description = "Specify the type if it can't be auto-detected.",
.labels = {"hash type"},
.handler = {[this](std::string str) {
type = parseHashType(str);
}},
});
expectArgs({
.label = "hashes",
.handler = {&hashStrings},
});
}
std::string description() override
{
return "convert between different hash formats, e.g. base16 and sri.";
}
Category category() override { return catUtility; }
void run() override {
for (const auto& s: hashStrings) {
Hash h = Hash::parseAny(s, type);
if (from && h.to_string(*from, from == HashFormat::SRI) != s) {
auto from_as_string = printHashFormat(*from);
throw BadHash("input hash '%s' does not have the expected format '--from %s'", s, from_as_string);
}
logger->cout(h.to_string(to, to == HashFormat::SRI));
}
}
};
struct CmdHash : NixMultiCommand
{
CmdHash()
: NixMultiCommand(
"hash",
{
{"convert", []() { return make_ref<CmdHashConvert>();}},
{"file", []() { return make_ref<CmdHashBase>(FileIngestionMethod::Flat);; }},
{"path", []() { return make_ref<CmdHashBase>(FileIngestionMethod::Recursive); }},
{"to-base16", []() { return make_ref<CmdToBase>(HashFormat::Base16); }},

View file

@ -81,24 +81,41 @@ rm $TEST_ROOT/hash-path/hello
ln -s x $TEST_ROOT/hash-path/hello
try2 md5 "f78b733a68f5edbdf9413899339eaa4a"
# Conversion.
# Conversion with `nix hash` `nix-hash` and `nix hash convert`
try3() {
# $1 = hash type
# $2 = expected hash in base16
# $3 = expected hash in base32
# $4 = expected hash in base64
h64=$(nix hash convert --type "$1" --to base64 "$2")
[ "$h64" = "$4" ]
h64=$(nix-hash --type "$1" --to-base64 "$2")
[ "$h64" = "$4" ]
# Deprecated experiment
h64=$(nix hash to-base64 --type "$1" "$2")
[ "$h64" = "$4" ]
sri=$(nix hash convert --type "$1" --to sri "$2")
[ "$sri" = "$1-$4" ]
sri=$(nix-hash --type "$1" --to-sri "$2")
[ "$sri" = "$1-$4" ]
sri=$(nix hash to-sri --type "$1" "$2")
[ "$sri" = "$1-$4" ]
h32=$(nix hash convert --type "$1" --to base32 "$2")
[ "$h32" = "$3" ]
h32=$(nix-hash --type "$1" --to-base32 "$2")
[ "$h32" = "$3" ]
h32=$(nix hash to-base32 --type "$1" "$2")
[ "$h32" = "$3" ]
h16=$(nix-hash --type "$1" --to-base16 "$h32")
[ "$h16" = "$2" ]
h16=$(nix hash convert --type "$1" --to base16 "$h64")
[ "$h16" = "$2" ]
h16=$(nix hash to-base16 --type "$1" "$h64")
[ "$h16" = "$2" ]
h16=$(nix hash convert --to base16 "$sri")
[ "$h16" = "$2" ]
h16=$(nix hash to-base16 "$sri")
[ "$h16" = "$2" ]
}