git.delta.rocks / fleet / refs/commits / 12bc0d4f3eb3

difftreelog

source

crates/nix-eval/src/lib.cc6.6 KiBsourcehistory
1#include "nix-eval/src/lib.rs"2#include "lib.hh"3#include <nix/fetchers/fetch-settings.hh>4#include <nix/store/build-result.hh>5#include <nix/store/content-address.hh>6#include <nix/store/derived-path.hh>7#include <nix/store/local-fs-store.hh>8#include <nix/store/outputs-spec.hh>9#include <nix/store/path-info.hh>10#include <nix/store/profiles.hh>11#include <nix/store/realisation.hh>12#include <nix/store/store-api.hh>13#include <nix/util/file-system.hh>14#include <nix/util/hash.hh>15#include <nix/util/posix-source-accessor.hh>16#include <nix/util/ref.hh>17#include <nix/util/signature/local-keys.hh>18#include <nix/util/signature/signer.hh>19#include <nix/util/source-path.hh>20#include <nix_api_fetchers.h>21#include <nix_api_store_internal.h>22#include <sstream>2324struct nix_fetchers_settings {25  nix::ref<nix::fetchers::Settings> settings;26};2728extern "C" {29void set_fetcher_setting(nix_fetchers_settings *settings_struct,30                         const char *setting, const char *value) {31  auto &settings_ref = settings_struct->settings;32  bool result = settings_ref->set(setting, value);33}34}3536rust::String switch_profile(Store *store, rust::Str profile,37                            rust::Str store_path) {38  try {39    auto nixStore = store->ptr;40    auto *lfs = dynamic_cast<nix::LocalFSStore *>(&*nixStore);41    if (!lfs)42      return rust::String("destination is not a local-fs store");43    auto path = nixStore->parseStorePath(std::string(store_path));44    std::filesystem::path prof = std::string(profile);45    auto gen = nix::createGeneration(*lfs, prof, path);46    nix::switchLink(prof, gen);47    return rust::String();48  } catch (const std::exception &e) {49    return rust::String(e.what());50  }51}5253rust::String sign_closure(Store *store, rust::Str store_path,54                          rust::Str key_file) {55  try {56    auto nixStore = store->ptr;57    nix::LocalSigner signer(58        nix::SecretKey::parse(nix::readFile(std::string(key_file))));59    auto root = nixStore->parseStorePath(std::string(store_path));60    nix::StorePathSet closure;61    nixStore->computeFSClosure(root, closure);62    for (auto &p : closure) {63      auto info = nixStore->queryPathInfo(p);64      nix::ValidPathInfo info2(*info);65      info2.sign(*nixStore, signer);66      nixStore->addSignatures(p, info2.sigs);67    }68    return rust::String();69  } catch (const std::exception &e) {70    return rust::String(e.what());71  }72}7374CxxListGenerationsResult list_generations(rust::Str profile_path) {75  CxxListGenerationsResult out{rust::String(), {}};76  try {77    auto [gens, current] =78        nix::findGenerations(std::filesystem::path(std::string(profile_path)));79    for (auto &g : gens) {80      CxxProfileGeneration cg{};81      cg.id = g.number;82      cg.store_path = rust::String(g.path.string());83      cg.creation_time_unix = static_cast<int64_t>(g.creationTime);84      cg.current = current.has_value() && *current == g.number;85      out.generations.push_back(cg);86    }87  } catch (const std::exception &e) {88    out.error = rust::String(e.what());89  }90  return out;91}9293static std::vector<std::string> split_lines(rust::Str joined) {94  std::vector<std::string> out;95  std::string buf;96  std::istringstream iss((std::string(joined)));97  while (std::getline(iss, buf)) {98    if (!buf.empty())99      out.push_back(buf);100  }101  return out;102}103104CxxBuildResult build_drv_outputs(Store *store, rust::Str drv_path,105                                 // TODO: Vec<str>106                                 rust::Str output_names_joined) {107  CxxBuildResult res{rust::String(), {}};108  try {109    auto nixStore = store->ptr;110    auto sp = nixStore->parseStorePath(std::string(drv_path));111112    nix::DerivedPath::Built built{113        .drvPath = nix::makeConstantStorePathRef(sp),114        .outputs = nix::OutputsSpec{nix::OutputsSpec::All{}},115    };116    auto names = split_lines(output_names_joined);117    if (!names.empty()) {118      std::set<nix::OutputName, std::less<>> nameSet;119      for (auto &n : names)120        nameSet.insert(n);121      built.outputs =122          nix::OutputsSpec{nix::OutputsSpec::Names{std::move(nameSet)}};123    }124125    std::vector<nix::DerivedPath> reqs;126    reqs.push_back(built);127128    auto results = nixStore->buildPathsWithResults(reqs);129    for (auto &r : results) {130      if (auto *failure = r.tryGetFailure()) {131        res.error = rust::String(failure->what());132        return res;133      }134    }135    for (auto &r : results) {136      if (auto *success = r.tryGetSuccess()) {137        for (auto &[name, real] : success->builtOutputs) {138          res.outputs.push_back(139              rust::String(nixStore->printStorePath(real.outPath)));140        }141      }142    }143  } catch (const std::exception &e) {144    res.error = rust::String(e.what());145  }146  return res;147}148149CxxBuildResult substitute_paths(Store *store, rust::Str paths_joined) {150  CxxBuildResult res{rust::String(), {}};151  try {152    auto nixStore = store->ptr;153    auto paths = split_lines(paths_joined);154155    std::vector<nix::DerivedPath> reqs;156    reqs.reserve(paths.size());157    for (auto &p : paths) {158      reqs.push_back(nix::DerivedPath::Opaque{nixStore->parseStorePath(p)});159    }160161    // Substituter miss will cause scheduler to trigger build162    auto results = nixStore->buildPathsWithResults(reqs);163    for (auto &r : results) {164      if (r.tryGetSuccess() == nullptr)165        continue;166      if (auto *opaque = std::get_if<nix::DerivedPath::Opaque>(&r.path.raw())) {167        res.outputs.push_back(168            rust::String(nixStore->printStorePath(opaque->path)));169      }170    }171  } catch (const std::exception &e) {172    res.error = rust::String(e.what());173  }174  return res;175}176177bool is_valid_path(Store *store, rust::Str path) {178  try {179    auto nixStore = store->ptr;180    auto sp = nixStore->parseStorePath(std::string(path));181    return nixStore->isValidPath(sp);182  } catch (const std::exception &) {183    return false;184  }185}186187AddFileToStoreResult add_file_to_store(Store *store, rust::Str name,188                                       rust::Str path) {189  AddFileToStoreResult out{rust::String(), rust::String(), rust::String()};190  try {191    auto nixStore = store->ptr;192    auto src = nix::PosixSourceAccessor::createAtRoot(193        std::filesystem::path(std::string(path)));194    auto info = nixStore->addToStoreSlow(std::string(name), src,195                                         nix::ContentAddressMethod::Raw::Flat,196                                         nix::HashAlgorithm::SHA256);197    out.store_path = rust::String(nixStore->printStorePath(info.path));198    if (info.ca.has_value()) {199      out.hash =200          rust::String(info.ca->hash.to_string(nix::HashFormat::SRI, true));201    }202  } catch (const std::exception &e) {203    out.error = rust::String(e.what());204  }205  return out;206}