Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a native pants client. #11922

Merged
merged 30 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9078f42
Introduce a native pants client.
jsirois Apr 7, 2021
a8f85da
Debug macOS test failure.
jsirois Apr 14, 2021
a3b9a7e
Tom's feedback.
jsirois Apr 15, 2021
9fb47cf
Fix parser precedence.
jsirois Apr 16, 2021
4f01fbd
Build engine and client together.
jsirois Apr 16, 2021
89b468f
Fixup flag parsing precedence / string list gathering.
jsirois Apr 16, 2021
ef50d26
Use nailgun crate to manage the pantsd ng connection.
jsirois Apr 16, 2021
c82d677
Tighten up test CWD lock impl.
jsirois Apr 21, 2021
2221636
Break tests out into seperate module files.
jsirois Apr 21, 2021
ab4dd81
Restructure BuildRoot to be testable.
jsirois Apr 21, 2021
9f10182
Fix clippy lints.
jsirois Apr 21, 2021
4c99899
Add best effort tty settings save & restore.
jsirois Apr 22, 2021
f03f4a7
Use nix for termios.
jsirois Apr 22, 2021
81ee069
Hack in an attempt at cross-platform process cmdline handling.
jsirois Apr 22, 2021
c66ebd4
Switch from remoteprocess to sysinfo.
jsirois Apr 22, 2021
1eea5c0
Use sysinfo exclusively to check pants process.
jsirois Apr 22, 2021
6c11e16
Make rust Process name extraction match Python.
jsirois Apr 22, 2021
0d8d6b4
Introduce ParseError to delay expensive error formatting.
jsirois Apr 22, 2021
cb2a394
Merge remote-tracking branch 'upstream/main' into issues/11831
jsirois Jun 1, 2021
215e683
Merge remote-tracking branch 'refs/remotes/upstream/main' into issues…
jsirois Jun 22, 2021
f541ac1
Fix shell fmt and lint.
jsirois Jun 22, 2021
680cc46
Merge remote-tracking branch 'refs/remotes/upstream/main' into issues…
jsirois Jul 2, 2021
7f8047a
Merge remote-tracking branch 'refs/remotes/upstream/main' into issues…
jsirois Jul 2, 2021
cdb0807
Merge remote-tracking branch 'refs/remotes/upstream/main' into issues…
jsirois Jul 5, 2021
61e0654
Add a client test.
jsirois Jul 5, 2021
711885e
Add parse_tests.
jsirois Jul 5, 2021
45d4cd9
Add Args tests.
jsirois Jul 5, 2021
4db027a
Fix test string formatting.
jsirois Jul 6, 2021
c87cdad
Add Env tests.
jsirois Jul 6, 2021
6f1be0c
Clean up Args tests.
jsirois Jul 6, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ GRTAGS
GSYMS
GTAGS
.mypy_cache/
/.pants
21 changes: 17 additions & 4 deletions build-support/bin/rust/bootstrap_code.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,19 @@ readonly NATIVE_ENGINE_BINARY_PYO3="native_engine_pyo3.so"
readonly NATIVE_ENGINE_RESOURCE="${REPO_ROOT}/src/python/pants/engine/internals/${NATIVE_ENGINE_BINARY}"
readonly NATIVE_ENGINE_RESOURCE_PYO3="${REPO_ROOT}/src/python/pants/engine/internals/${NATIVE_ENGINE_BINARY_PYO3}"
readonly NATIVE_ENGINE_RESOURCE_METADATA="${NATIVE_ENGINE_RESOURCE}.metadata"
readonly NATIVE_CLIENT_PATH="${REPO_ROOT}/.pants"
readonly NATIVE_CLIENT_TARGET="${NATIVE_ROOT}/target/${MODE}/pants"

function _build_native_code() {
banner "Building native engine..."
banner "Building native code..."
# NB: See Cargo.toml with regard to the `extension-module` features.
"${REPO_ROOT}/cargo" build \
--features=extension-module \
--features=engine_pyo3/extension-module \
${MODE_FLAG} \
-p engine \
-p engine_pyo3 || die
-p engine_pyo3 \
-p client || die
}

function bootstrap_native_code() {
Expand All @@ -66,7 +69,11 @@ function bootstrap_native_code() {
if [[ -f "${NATIVE_ENGINE_RESOURCE_METADATA}" ]]; then
engine_version_in_metadata="$(sed -n 's/^engine_version: //p' "${NATIVE_ENGINE_RESOURCE_METADATA}")"
fi
if [[ ! -f "${NATIVE_ENGINE_RESOURCE}" || ! -f "${NATIVE_ENGINE_RESOURCE_PYO3}" || "${engine_version_calculated}" != "${engine_version_in_metadata}" ]]; then
if [[ ! -f "${NATIVE_ENGINE_RESOURCE}" || ! -f \
"${NATIVE_ENGINE_RESOURCE_PYO3}" || ! -f \
"${NATIVE_CLIENT_PATH}" || \
"${engine_version_calculated}" != "${engine_version_in_metadata}" ]]; then

_build_native_code || die

# If bootstrapping the native engine fails, don't attempt to run pants
Expand All @@ -80,15 +87,21 @@ function bootstrap_native_code() {
die "Failed to build native engine, file missing at ${native_binary_pyo3}."
fi

# If bootstrapping the native client fails, don't attempt to run pants afterwards.
if [[ ! -f "${NATIVE_CLIENT_TARGET}" ]]; then
die "Failed to build native client."
fi

# Pick up Cargo.lock changes if any caused by the `cargo build`.
engine_version_calculated="$(calculate_current_hash)"

# Create the native engine resource.
# NB: On Mac Silicon, for some reason, first removing the old native_engine.so is necessary to avoid the Pants
# process from being killed when recompiling.
rm -f "${NATIVE_ENGINE_RESOURCE}" "${NATIVE_ENGINE_RESOURCE_PYO3}"
rm -f "${NATIVE_ENGINE_RESOURCE}" "${NATIVE_ENGINE_RESOURCE_PYO3}" "${NATIVE_CLIENT_PATH}"
cp "${native_binary}" "${NATIVE_ENGINE_RESOURCE}"
cp "${native_binary_pyo3}" "${NATIVE_ENGINE_RESOURCE_PYO3}"
cp "${NATIVE_CLIENT_TARGET}" "${NATIVE_CLIENT_PATH}"

# Create the accompanying metadata file.
local -r metadata_file=$(mktemp -t pants.native_engine.metadata.XXXXXX)
Expand Down
20 changes: 17 additions & 3 deletions pants
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,31 @@ source "${HERE}/build-support/pants_venv"
source "${HERE}/build-support/bin/rust/bootstrap_code.sh"

function exec_pants_bare() {

PANTS_EXE="${HERE}/src/python/pants/bin/pants_loader.py"
PANTS_NATIVE_EXE="${HERE}/.pants"
PANTS_PY_EXE="${HERE}/src/python/pants/bin/pants_loader.py"
PANTS_SRCPATH="${HERE}/src/python"

# Redirect activation and native bootstrap to ensure that they don't interfere with stdout.
activate_pants_venv 1>&2
bootstrap_native_code 1>&2

if [ -n "${USE_NATIVE_PANTS}" ]; then
set +e
"${PANTS_NATIVE_EXE}" "$@"
result=$?
# N.B.: The native pants client currently relies on pantsd being up. If it's not, it will fail
# with exit code 75 (EX_TEMPFAIL in /usr/include/sysexits.h) and we should fall through to the
# python pants client which knows how to start up pantsd. This failure takes O(1ms); so has no
# appreciable impact on --no-pantsd runs.
if ((result != 75)); then
exit ${result}
fi
set -e
fi

# shellcheck disable=SC2086
PYTHONPATH="${PANTS_SRCPATH}:${PYTHONPATH}" RUNNING_PANTS_FROM_SOURCES=1 \
exec ${PANTS_PREPEND_ARGS:-} "$(venv_dir)/bin/python" "${PANTS_EXE}" "$@"
exec ${PANTS_PREPEND_ARGS:-} "$(venv_dir)/bin/python" "${PANTS_PY_EXE}" "$@"
}

exec_pants_bare "$@"
106 changes: 104 additions & 2 deletions src/rust/engine/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/rust/engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ members = [
"async_latch",
"async_semaphore",
"async_value",
"client",
"concrete_time",
"engine_pyo3",
"fs",
Expand Down Expand Up @@ -60,6 +61,7 @@ default-members = [
".",
"async_latch",
"async_semaphore",
"client",
"async_value",
"concrete_time",
"engine_pyo3",
Expand Down
30 changes: 30 additions & 0 deletions src/rust/engine/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
version = "0.0.1"
edition = "2018"
name = "client"
authors = [ "Pants Build <pantsbuild@gmail.com>" ]
publish = false

[[bin]]
name = "pants"
path = "src/main.rs"

[dependencies]
env_logger = "0.5.4"
jsirois marked this conversation as resolved.
Show resolved Hide resolved
futures = "0.3"
libc = "0.2"
log = "0.4"
nailgun = { path = "../nailgun" }
nix = "0.20"
peg = "0.7"
sha2 = "0.9"
shellexpand = "2.1"
strum = "0.20"
strum_macros = "0.20"
sysinfo = "0.17.1"
tokio = { version = "1.4", features = ["rt-multi-thread", "macros", "net", "io-std", "io-util"] }
toml = "0.5"
uname = "0.1"

[dev-dependencies]
tempdir = "0.3"
64 changes: 64 additions & 0 deletions src/rust/engine/client/src/build_root.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).

use std::env;
use std::ops::Deref;
use std::path::{Path, PathBuf};

use log::debug;

#[derive(Debug)]
pub struct BuildRoot(PathBuf);

impl BuildRoot {
const SENTINEL_FILES: &'static [&'static str] = &["pants", "BUILDROOT", "BUILD_ROOT"];

pub fn find() -> Result<BuildRoot, String> {
let cwd = env::current_dir().map_err(|e| format!("Failed to determine $CWD: {}", e))?;
Self::find_from(&cwd)
}

pub(crate) fn find_from(start: &Path) -> Result<BuildRoot, String> {
let mut build_root = start;
loop {
for sentinel in Self::SENTINEL_FILES {
let sentinel_path = build_root.join(sentinel);
if !sentinel_path.exists() {
continue;
}
let sentinel_path_metadata = sentinel_path.metadata().map_err(|e| {
format!(
"\
Failed to read metadata for {path} to determine if is a build root sentinel file: {err}\
",
path = sentinel_path.display(),
err = e
)
})?;
if sentinel_path_metadata.is_file() {
let root = BuildRoot(build_root.to_path_buf());
debug!("Found {:?} starting search from {}.", root, start.display());
return Ok(root);
}
}

build_root = build_root.parent().ok_or(format!(
"\
No build root detected for the current directory of {cwd}. Pants detects the build root \
jsirois marked this conversation as resolved.
Show resolved Hide resolved
by looking for at least one file from {sentinel_files} in the cwd and its ancestors. If \
you have none of these files, you can create an empty file in your build root.\
",
cwd = start.display(),
sentinel_files = Self::SENTINEL_FILES.join(", ")
))?;
}
}
}

impl Deref for BuildRoot {
type Target = PathBuf;

fn deref(&self) -> &PathBuf {
&self.0
}
}
Loading