pantsbuild / pants

The Pants Build System
https://www.pantsbuild.org
Apache License 2.0
3.32k stars 636 forks source link

Arg process substitution is broken with the daemon #5385

Open illicitonion opened 6 years ago

illicitonion commented 6 years ago
pants$ git rev-parse HEAD
48210e276bbf796c4b9fe71c9cfffd0b9f536123
pants$ ./pants --target-spec-file=<(echo '3rdparty:guava') list
3rdparty:guava

pants$ ./pants --enable-pantsd=True --target-spec-file=<(echo '3rdparty:guava') list

FAILURE: Please specify one or more explicit target specs (e.g. `./pants list ::`).

FAILURE
stuhood commented 6 years ago

Hm! I have no idea why that worked in the first place. Certainly f = open("<(echo '3rdparty:guava')") does not work.

stuhood commented 6 years ago

...!

$ ./pants --target-spec-file=<(echo '3rdparty:guava') options | grep target.spec.file

target_spec_files = ['/dev/fd/63'] (from FLAG)

(TIL.)

illicitonion commented 6 years ago

Bash process substitution is really handy :) Particularly for things like:

diff <(cat file1) <(cat file2 | tr 'a' 'b')

:)

But yeah, alas we've broken it with the daemon!

kwlzn commented 6 years ago

I think this is specific to and because of the way the <(echo x) bit works under the hood:

$ echo <(echo '3rdparty:guava')
/dev/fd/63

the fd is specific to the parent shell, so it's not portable across the process boundary in the pantsd case by the path provided.

its ~hacky, but we could scan the commandline string for instances of these /dev/fd strings and move their contents to real tmp files & do string substitution before sending the pailgun command which seems like it would 'just work'.

kwlzn commented 6 years ago

(except in the case where the x in <(x) is providing a live stream, I suppose - but probably sufficient for most general ./pants invoke purposes)

illicitonion commented 6 years ago

Sadness :( I wish OSX had a procfs so we could reliably share FDs between processes by path... Oh well!

illicitonion commented 6 years ago

Thanks for investigating!

kwlzn commented 6 years ago

we might still be able to send FDs across processes on OSX, just not by an externally addressable path

stuhood commented 6 years ago

Relates to #5223 "because re-parenting of the pantsd-runner".

Eric-Arellano commented 2 years ago

Is this still relevant? I can't get the command to work regardless of the daemon

❯ ./pants --spec-files=<(echo '3rdparty/python#toml') list
10:17:30.50 [WARN] No targets were matched in goal `list`.

❯ ./pants --spec-files=<(echo '3rdparty/python#toml') --no-pantsd list
10:17:39.91 [WARN] No targets were matched in goal `list`.
stuhood commented 2 years ago

I repro in bash on macOS:

$ ./pants --spec-files=<(echo '3rdparty/python#toml') list
09:53:55.54 [ERROR] 1 Exception encountered:

Engine traceback:
  in select
  in pants.init.plugin_resolver.resolve_plugins
  in construct_scope_
  in pants.engine.internals.options_parsing.scope_options
  in pants.engine.internals.options_parsing.parse_options
Traceback (most recent call last):
 ...
  File "/Users/stuhood/src/pants/src/python/pants/option/options.py", line 135, in create
    with open(spec_file) as f:
PermissionError: [Errno 13] Permission denied: '/dev/fd/63'

Use -ldebug for more logs.
See https://www.pantsbuild.org/v2.14/docs/troubleshooting for common issues.
Consider reaching out for help: https://www.pantsbuild.org/v2.14/docs/getting-help
Eric-Arellano commented 2 years ago

Ah me too. I don't repro with zsh 5.8 on macOS

kaos commented 1 year ago

I still repro, also on zsh 5.9

❯ pants --spec-files=<(echo '3rdparty/python#toml') list
19:47:52.71 [ERROR] 1 Exception encountered:

Engine traceback:
  in select
    ..
  in pants.core.util_rules.environments.determine_local_environment
    ..
  in pants.core.util_rules.environments.determine_all_environments
    ..
  in construct_scope_environments_preview
    ..

Traceback (most recent call last):
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/selectors.py", line 638, in native_engine_generator_send
    res = rule.send(arg) if err is None else rule.throw(throw or err)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/option/subsystem.py", line 312, in _construct_subsytem
    scoped_options = await Get(ScopedOptions, Scope(str(subsystem_typ.options_scope)))
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/selectors.py", line 130, in __await__
    result = yield self
OSError: [Errno 9] Bad file descriptor: '/dev/fd/11'

Traceback (most recent call last):
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/bin/daemon_pants_runner.py", line 133, in single_daemonized_run
    scheduler, options_initializer = self._core.prepare(options_bootstrapper, complete_env)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/pantsd/pants_daemon_core.py", line 130, in prepare
    build_config = self._options_initializer.build_config(options_bootstrapper, env)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/init/options_initializer.py", line 153, in build_config
    return _initialize_build_configuration(self._plugin_resolver, options_bootstrapper, env)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/init/options_initializer.py", line 52, in _initialize_build_configuration
    working_set = plugin_resolver.resolve(options_bootstrapper, env, backends_requirements)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/init/plugin_resolver.py", line 141, in resolve
    for resolved_plugin_location in self._resolve_plugins(options_bootstrapper, env, request):
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/init/plugin_resolver.py", line 163, in _resolve_plugins
    params = Params(request, determine_bootstrap_environment(session))
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/core/util_rules/environments.py", line 448, in determine_bootstrap_environment
    session.product_request(ChosenLocalEnvironmentName, [Params()])[0],
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/scheduler.py", line 580, in product_request
    return self.execute(request)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/scheduler.py", line 521, in execute
    self._raise_on_error([t for _, t in throws])
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/scheduler.py", line 505, in _raise_on_error
    raise ExecutionError(
pants.engine.internals.scheduler.ExecutionError: 1 Exception encountered:

Engine traceback:
  in select
    ..
  in pants.core.util_rules.environments.determine_local_environment
    ..
  in pants.core.util_rules.environments.determine_all_environments
    ..
  in construct_scope_environments_preview
    ..

Traceback (most recent call last):
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/selectors.py", line 638, in native_engine_generator_send
    res = rule.send(arg) if err is None else rule.throw(throw or err)
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/option/subsystem.py", line 312, in _construct_subsytem
    scoped_options = await Get(ScopedOptions, Scope(str(subsystem_typ.options_scope)))
  File "/Users/andreas.stenius/src/github/kaos/pants/src/python/pants/engine/internals/selectors.py", line 130, in __await__
    result = yield self
OSError: [Errno 9] Bad file descriptor: '/dev/fd/11'

Use -ldebug for more logs.
See https://www.pantsbuild.org/v2.19/docs/troubleshooting for common issues.
Consider reaching out for help: https://www.pantsbuild.org/v2.19/docs/getting-help