Skip to content

Commit

Permalink
Hotfix #21604 race condition on .vcpkg-lock (#283)
Browse files Browse the repository at this point in the history
* Fix for #21604 race condition on .vcpkg-lock

* CR feedback.

* clang-format

Co-authored-by: Billy Robert O'Neal III <[email protected]>
  • Loading branch information
ras0219-msft and BillyONeal authored Nov 24, 2021
1 parent 93c2aa3 commit cf82de1
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 43 deletions.
11 changes: 7 additions & 4 deletions azure-pipelines/end-to-end-tests-dir/bundles.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ foreach ($k in $b.keys) {
Refresh-TestRoot

New-Item -ItemType Directory -Force $bundle | Out-Null
New-Item -ItemType File -Force $bundle/.vcpkg-root | Out-Null
@{
readonly = $True
} | ConvertTo-JSON | out-file -enc ascii $bundle/.vcpkg-root | Out-Null
} | ConvertTo-JSON | out-file -enc ascii $bundle/vcpkg-bundle.json | Out-Null

$a = Run-Vcpkg z-print-config `
--vcpkg-root=$bundle `
Expand Down Expand Up @@ -72,9 +73,10 @@ Refresh-TestRoot

New-Item -ItemType Directory -Force $manifestdir | Out-Null
New-Item -ItemType Directory -Force $bundle | Out-Null
New-Item -ItemType File -Force $bundle/.vcpkg-root | Out-Null
@{
readonly = $True
} | ConvertTo-JSON | out-file -enc ascii $bundle/.vcpkg-root | Out-Null
} | ConvertTo-JSON | out-file -enc ascii $bundle/vcpkg-bundle.json | Out-Null
@{
name = "manifest"
version = "0"
Expand Down Expand Up @@ -112,9 +114,10 @@ $manifestdir = Join-Path $TestingRoot "manifest"

New-Item -ItemType Directory -Force $manifestdir | Out-Null
New-Item -ItemType Directory -Force $bundle | Out-Null
New-Item -ItemType File -Force $bundle/.vcpkg-root | Out-Null
@{
readonly = $True
} | ConvertTo-JSON | out-file -enc ascii $bundle/.vcpkg-root | Out-Null
} | ConvertTo-JSON | out-file -enc ascii $bundle/vcpkg-bundle.json | Out-Null
@{
name = "manifest"
version = "0"
Expand Down Expand Up @@ -163,7 +166,7 @@ $CurrentTest = "Testing bundle.usegitregistry"
@{
readonly = $True
usegitregistry = $True
} | ConvertTo-JSON | out-file -enc ascii $bundle/.vcpkg-root | Out-Null
} | ConvertTo-JSON | out-file -enc ascii $bundle/vcpkg-bundle.json | Out-Null
Run-Vcpkg install --dry-run --vcpkg-root=$bundle `
--x-manifest-root=$manifestdir `
--overlay-triplets=$env:VCPKG_ROOT/triplets `
Expand Down
93 changes: 54 additions & 39 deletions src/vcpkg/vcpkgpaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,61 +355,49 @@ namespace vcpkg

static Path lockfile_path(const VcpkgPaths& p) { return p.vcpkg_dir() / "vcpkg-lock.json"; }

VcpkgPaths::VcpkgPaths(Filesystem& filesystem, const VcpkgCmdArguments& args)
: m_pimpl(std::make_unique<details::VcpkgPathsImpl>(
filesystem,
args.feature_flag_settings(),
Util::Enum::to_enum<ToolCache::RequireExactVersions>(args.exact_abi_tools_versions.value_or(false))))
static Path determine_root(const Filesystem& fs, const Path& original_cwd, const VcpkgCmdArguments& args)
{
original_cwd = filesystem.current_path(VCPKG_LINE_INFO);
#if defined(_WIN32)
original_cwd = vcpkg::win32_fix_path_case(original_cwd);
#endif // _WIN32

if (args.vcpkg_root_dir)
{
root = filesystem.almost_canonical(*args.vcpkg_root_dir, VCPKG_LINE_INFO);
return fs.almost_canonical(*args.vcpkg_root_dir, VCPKG_LINE_INFO);
}
else

auto ret = fs.find_file_recursively_up(original_cwd, ".vcpkg-root", VCPKG_LINE_INFO);
if (ret.empty())
{
root = filesystem.find_file_recursively_up(original_cwd, ".vcpkg-root", VCPKG_LINE_INFO);
if (root.empty())
{
root = filesystem.find_file_recursively_up(
filesystem.almost_canonical(get_exe_path_of_current_process(), VCPKG_LINE_INFO),
".vcpkg-root",
VCPKG_LINE_INFO);
}
return fs.find_file_recursively_up(fs.almost_canonical(get_exe_path_of_current_process(), VCPKG_LINE_INFO),
".vcpkg-root",
VCPKG_LINE_INFO);
}

Checks::check_exit(VCPKG_LINE_INFO, !root.empty(), "Error: Could not detect vcpkg-root.");
Debug::print("Using vcpkg-root: ", root, '\n');
const auto vcpkg_root_file = root / ".vcpkg-root";
auto bundle_file = filesystem.read_contents(vcpkg_root_file, VCPKG_LINE_INFO);
if (!std::all_of(bundle_file.begin(), bundle_file.end(), Parse::ParserBase::is_whitespace))
return ret;
}

static void load_bundle_file(const Filesystem& fs, const Path& root, details::VcpkgPathsImpl& impl)
{
const auto vcpkg_bundle_file = root / "vcpkg-bundle.json";
std::error_code ec;
auto bundle_file = fs.read_contents(vcpkg_bundle_file, ec);
if (!ec)
{
auto maybe_bundle_doc = Json::parse(bundle_file, vcpkg_root_file.native());
auto maybe_bundle_doc = Json::parse(bundle_file, bundle_file);
if (auto bundle_doc = maybe_bundle_doc.get())
{
if (auto v = bundle_doc->first.object().get("readonly"))
const auto& first_object = bundle_doc->first.object();
if (auto v = first_object.get("readonly"))
{
m_pimpl->m_readonly = v->boolean();
impl.m_readonly = v->boolean();
}
if (auto v = bundle_doc->first.object().get("usegitregistry"))

if (auto v = first_object.get("usegitregistry"))
{
m_pimpl->m_usegitregistry = v->boolean();
impl.m_usegitregistry = v->boolean();
}
if (auto v = bundle_doc->first.object().get("embeddedsha"))

if (auto v = first_object.get("embeddedsha"))
{
m_pimpl->m_embedded_git_sha = v->string().to_string();
impl.m_embedded_git_sha = v->string().to_string();
}
Debug::print("Bundle config: readonly=",
m_pimpl->m_readonly,
", usegitregistry=",
m_pimpl->m_usegitregistry,
", embeddedsha=",
m_pimpl->m_embedded_git_sha.value_or("nullopt"),
"\n");
}
else
{
Expand All @@ -418,6 +406,33 @@ namespace vcpkg
}
}

Debug::print("Bundle config: readonly=",
impl.m_readonly,
", usegitregistry=",
impl.m_usegitregistry,
", embeddedsha=",
impl.m_embedded_git_sha.value_or("nullopt"),
"\n");
}

VcpkgPaths::VcpkgPaths(Filesystem& filesystem, const VcpkgCmdArguments& args)
: m_pimpl(std::make_unique<details::VcpkgPathsImpl>(
filesystem,
args.feature_flag_settings(),
Util::Enum::to_enum<ToolCache::RequireExactVersions>(args.exact_abi_tools_versions.value_or(false))))
{
original_cwd = filesystem.current_path(VCPKG_LINE_INFO);
#if defined(_WIN32)
original_cwd = vcpkg::win32_fix_path_case(original_cwd);
#endif // _WIN32

root = determine_root(filesystem, original_cwd, args);
Checks::check_exit(VCPKG_LINE_INFO, !root.empty(), "Error: Could not detect vcpkg-root.");
Debug::print("Using vcpkg-root: ", root, '\n');

load_bundle_file(filesystem, root, *m_pimpl);

const auto vcpkg_root_file = root / ".vcpkg-root";
std::error_code ec;
if (args.manifests_enabled())
{
Expand Down

0 comments on commit cf82de1

Please sign in to comment.