<commit_before>#include "hash.hh"
#include "shared.hh"
#include "download.hh"
#include "store-api.hh"
#include "eval.hh"
#include "eval-inline.hh"
#include "common-eval-args.hh"
#include "attr-path.hh"
#include "legacy.hh"
#include "finally.hh"
#include "progress-bar.hh"

#include <iostream>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

using namespace nix;


/* If ‘uri’ starts with ‘mirror://’, then resolve it using the list of
   mirrors defined in Nixpkgs. */
string resolveMirrorUri(EvalState & state, string uri)
{
    if (string(uri, 0, 9) != "mirror://") return uri;

    string s(uri, 9);
    auto p = s.find('/');
    if (p == string::npos) throw Error("invalid mirror URI");
    string mirrorName(s, 0, p);

    Value vMirrors;
    state.eval(state.parseExprFromString("import <nixpkgs/pkgs/build-support/fetchurl/mirrors.nix>", "."), vMirrors);
    state.forceAttrs(vMirrors);

    auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
    if (mirrorList == vMirrors.attrs->end())
        throw Error(format("unknown mirror name '%1%'") % mirrorName);
    state.forceList(*mirrorList->value);

    if (mirrorList->value->listSize() < 1)
        throw Error(format("mirror URI '%1%' did not expand to anything") % uri);

    string mirror = state.forceString(*mirrorList->value->listElems()[0]);
    return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
}


static int _main(int argc, char * * argv)
{
    {
        HashType ht = htSHA256;
        std::vector<string> args;
        bool printPath = getEnv("PRINT_PATH") == "1";
        bool fromExpr = false;
        string attrPath;
        bool unpack = false;
        string name;

        struct MyArgs : LegacyArgs, MixEvalArgs
        {
            using LegacyArgs::LegacyArgs;
        };

        MyArgs myArgs(baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
            if (*arg == "--help")
                showManPage("nix-prefetch-url");
            else if (*arg == "--version")
                printVersion("nix-prefetch-url");
            else if (*arg == "--type") {
                string s = getArg(*arg, arg, end);
                ht = parseHashType(s);
                if (ht == htUnknown)
                    throw UsageError(format("unknown hash type '%1%'") % s);
            }
            else if (*arg == "--print-path")
                printPath = true;
            else if (*arg == "--attr" || *arg == "-A") {
                fromExpr = true;
                attrPath = getArg(*arg, arg, end);
            }
            else if (*arg == "--unpack")
                unpack = true;
            else if (*arg == "--name")
                name = getArg(*arg, arg, end);
            else if (*arg != "" && arg->at(0) == '-')
                return false;
            else
                args.push_back(*arg);
            return true;
        });

        myArgs.parseCmdline(argvToStrings(argc, argv));

        initPlugins();

        if (args.size() > 2)
            throw UsageError("too many arguments");

        Finally f([]() { stopProgressBar(); });

        if (isatty(STDERR_FILENO))
          startProgressBar();

        auto store = openStore();
        auto state = std::make_unique<EvalState>(myArgs.searchPath, store);

        Bindings & autoArgs = *myArgs.getAutoArgs(*state);

        /* If -A is given, get the URI from the specified Nix
           expression. */
        string uri;
        if (!fromExpr) {
            if (args.empty())
                throw UsageError("you must specify a URI");
            uri = args[0];
        } else {
            Path path = resolveExprPath(lookupFileArg(*state, args.empty() ? "." : args[0]));
            Value vRoot;
            state->evalFile(path, vRoot);
            Value & v(*findAlongAttrPath(*state, attrPath, autoArgs, vRoot));
            state->forceAttrs(v);

            /* Extract the URI. */
            auto attr = v.attrs->find(state->symbols.create("urls"));
            if (attr == v.attrs->end())
                throw Error("attribute set does not contain a 'urls' attribute");
            state->forceList(*attr->value);
            if (attr->value->listSize() < 1)
                throw Error("'urls' list is empty");
            uri = state->forceString(*attr->value->listElems()[0]);

            /* Extract the hash mode. */
            attr = v.attrs->find(state->symbols.create("outputHashMode"));
            if (attr == v.attrs->end())
                printInfo("warning: this does not look like a fetchurl call");
            else
                unpack = state->forceString(*attr->value) == "recursive";<commit_msg>nix-prefetch-url: support --unpack w/ -A?<commit_after>#include "hash.hh"
#include "shared.hh"
#include "download.hh"
#include "store-api.hh"
#include "eval.hh"
#include "eval-inline.hh"
#include "common-eval-args.hh"
#include "attr-path.hh"
#include "legacy.hh"
#include "finally.hh"
#include "progress-bar.hh"

#include <iostream>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

using namespace nix;


/* If ‘uri’ starts with ‘mirror://’, then resolve it using the list of
   mirrors defined in Nixpkgs. */
string resolveMirrorUri(EvalState & state, string uri)
{
    if (string(uri, 0, 9) != "mirror://") return uri;

    string s(uri, 9);
    auto p = s.find('/');
    if (p == string::npos) throw Error("invalid mirror URI");
    string mirrorName(s, 0, p);

    Value vMirrors;
    state.eval(state.parseExprFromString("import <nixpkgs/pkgs/build-support/fetchurl/mirrors.nix>", "."), vMirrors);
    state.forceAttrs(vMirrors);

    auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
    if (mirrorList == vMirrors.attrs->end())
        throw Error(format("unknown mirror name '%1%'") % mirrorName);
    state.forceList(*mirrorList->value);

    if (mirrorList->value->listSize() < 1)
        throw Error(format("mirror URI '%1%' did not expand to anything") % uri);

    string mirror = state.forceString(*mirrorList->value->listElems()[0]);
    return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
}


static int _main(int argc, char * * argv)
{
    {
        HashType ht = htSHA256;
        std::vector<string> args;
        bool printPath = getEnv("PRINT_PATH") == "1";
        bool fromExpr = false;
        string attrPath;
        bool unpack = false;
        string name;

        struct MyArgs : LegacyArgs, MixEvalArgs
        {
            using LegacyArgs::LegacyArgs;
        };

        MyArgs myArgs(baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
            if (*arg == "--help")
                showManPage("nix-prefetch-url");
            else if (*arg == "--version")
                printVersion("nix-prefetch-url");
            else if (*arg == "--type") {
                string s = getArg(*arg, arg, end);
                ht = parseHashType(s);
                if (ht == htUnknown)
                    throw UsageError(format("unknown hash type '%1%'") % s);
            }
            else if (*arg == "--print-path")
                printPath = true;
            else if (*arg == "--attr" || *arg == "-A") {
                fromExpr = true;
                attrPath = getArg(*arg, arg, end);
            }
            else if (*arg == "--unpack")
                unpack = true;
            else if (*arg == "--name")
                name = getArg(*arg, arg, end);
            else if (*arg != "" && arg->at(0) == '-')
                return false;
            else
                args.push_back(*arg);
            return true;
        });

        myArgs.parseCmdline(argvToStrings(argc, argv));

        initPlugins();

        if (args.size() > 2)
            throw UsageError("too many arguments");

        Finally f([]() { stopProgressBar(); });

        if (isatty(STDERR_FILENO))
          startProgressBar();

        auto store = openStore();
        auto state = std::make_unique<EvalState>(myArgs.searchPath, store);

        Bindings & autoArgs = *myArgs.getAutoArgs(*state);

        /* If -A is given, get the URI from the specified Nix
           expression. */
        string uri;
        if (!fromExpr) {
            if (args.empty())
                throw UsageError("you must specify a URI");
            uri = args[0];
        } else {
            Path path = resolveExprPath(lookupFileArg(*state, args.empty() ? "." : args[0]));
            Value vRoot;
            state->evalFile(path, vRoot);
            Value & v(*findAlongAttrPath(*state, attrPath, autoArgs, vRoot));
            state->forceAttrs(v);

            /* Extract the URI. */
            auto attr = v.attrs->find(state->symbols.create("urls"));
            if (attr == v.attrs->end())
                throw Error("attribute set does not contain a 'urls' attribute");
            state->forceList(*attr->value);
            if (attr->value->listSize() < 1)
                throw Error("'urls' list is empty");
            uri = state->forceString(*attr->value->listElems()[0]);

            /* Extract the hash mode. */
            attr = v.attrs->find(state->symbols.create("outputHashMode"));
            if (attr == v.attrs->end())
                printInfo("warning: this does not look like a fetchurl call");
            else
                unpack |= state->forceString(*attr->value) == "recursive";
{'fraction_non_alphanumeric': 0.1558482949112929, 'fraction_numerical': 0.004461914373738446, 'mean_word_length': 2.04364694471387, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2388141', 'n_tokens_mistral': 2879, 'n_tokens_neox': 2747, 'n_words': 697}