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

Add target scripts flag #10472

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions news/3934.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added --target-scripts flag to specify the directory to place the package's scripts, which may be different to the directory pointed by --target.
This allows, for instance, to do the following --target <path>/lib/python/site-packages --target-scripts <path>/bin
The default behavior, if --target-scripts is not passed, is to place the scripts in the scripts directory (depending on the OS) inside the --target directory
35 changes: 32 additions & 3 deletions src/pip/_internal/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ def add_options(self) -> None:
"with new versions."
),
)
self.cmd_opts.add_option(
'--target-scripts',
dest='target_scripts_dir',
metavar='dir',
default=None,
help='Install packages\' scripts into <dir>. It requires the -t or --target flag to be used.'
)
cmdoptions.add_target_python_options(self.cmd_opts)

self.cmd_opts.add_option(
Expand Down Expand Up @@ -244,6 +251,9 @@ def run(self, options: Values, args: List[str]) -> int:
if options.use_user_site and options.target_dir is not None:
raise CommandError("Can not combine '--user' and '--target'")

if options.target_scripts_dir is not None and options.target_dir is None:
raise CommandError("Can not use '--target-scripts' without '--target'")

cmdoptions.check_install_build_global(options)
upgrade_strategy = "to-satisfy-only"
if options.upgrade:
Expand Down Expand Up @@ -280,6 +290,15 @@ def run(self, options: Values, args: List[str]) -> int:
# Create a target directory for using with the target option
target_temp_dir = TempDirectory(kind="target")
target_temp_dir_path = target_temp_dir.path

if options.target_scripts_dir is not None:
options.target_scripts_dir = os.path.abspath(options.target_scripts_dir)
if (os.path.exists(options.target_scripts_dir) and not
os.path.isdir(options.target_scripts_dir)):
raise CommandError(
"Target's scripts path exists but is not a directory, will not "
"continue."
)
self.enter_context(target_temp_dir)

global_options = options.global_options or []
Expand Down Expand Up @@ -457,14 +476,14 @@ def run(self, options: Values, args: List[str]) -> int:
if options.target_dir:
assert target_temp_dir
self._handle_target_dir(
options.target_dir, target_temp_dir, options.upgrade
options.target_dir, target_temp_dir, options.target_scripts_dir, options.upgrade
)

warn_if_run_as_root()
return SUCCESS

def _handle_target_dir(
self, target_dir: str, target_temp_dir: TempDirectory, upgrade: bool
self, target_dir: str, target_temp_dir: TempDirectory, target_scripts_dir: str, upgrade: bool
) -> None:
ensure_dir(target_dir)

Expand All @@ -477,12 +496,19 @@ def _handle_target_dir(
scheme = get_scheme("", home=target_temp_dir.path)
purelib_dir = scheme.purelib
platlib_dir = scheme.platlib
scripts_dir = scheme.scripts
data_dir = scheme.data

if target_scripts_dir is None:
target_scripts_dir = os.path.join(target_dir, os.path.relpath(scripts_dir, target_temp_dir.path))
ensure_dir(target_scripts_dir)

if os.path.exists(purelib_dir):
lib_dir_list.append(purelib_dir)
if os.path.exists(platlib_dir) and platlib_dir != purelib_dir:
lib_dir_list.append(platlib_dir)
if os.path.exists(scripts_dir):
lib_dir_list.append(scripts_dir)
if os.path.exists(data_dir):
lib_dir_list.append(data_dir)

Expand All @@ -492,7 +518,10 @@ def _handle_target_dir(
ddir = os.path.join(data_dir, item)
if any(s.startswith(ddir) for s in lib_dir_list[:-1]):
continue
target_item_dir = os.path.join(target_dir, item)
if lib_dir == scripts_dir:
target_item_dir = os.path.join(target_scripts_dir, item)
else:
target_item_dir = os.path.join(target_dir, item)
if os.path.exists(target_item_dir):
if not upgrade:
logger.warning(
Expand Down