Skip to content

Commit

Permalink
feat: add ability to provide custom pip flags (#1447)
Browse files Browse the repository at this point in the history
**Issue
number:[ADDON-75910](https://splunk.atlassian.net/browse/ADDON-75910)**

## Summary

Added ability to provide custom pip flags during build process.

### Changes

`ucc-gen build` command has a new flag `--pip-custom-flag`.

### User experience

User can add custom flag to `pip install` command which is executed
during build.

## Checklist

If your change doesn't seem to apply, please leave them unchecked.

* [x] I have performed a self-review of this change
* [x] Changes have been tested
* [x] Changes are documented
* [x] PR title follows [conventional commit
semantics](https://www.conventionalcommits.org/en/v1.0.0/)
  • Loading branch information
sgoral-splunk authored Nov 13, 2024
1 parent 4721738 commit 718c897
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 10 deletions.
6 changes: 6 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ It takes the following parameters:
to pip install command. The default is`False`.
>**NOTE:** This flag is deprecated and will be removed from pip in the future.
Instead of using this flag, the correct solution would be to fix the packages your project depends on to work properly with the new resolver. Additionally, this flag is not compatible with pip version `23.2`. Use `23.2.1` instead.
* `--pip-custom-flag` - [optional] Additional flag(s) that will be added to the `pip install` command.
By default, all the following flags are added to the `pip install` command: `--no-compile`, `--prefer-binary` and `--ignore-installed`.
If `--pip-custom-flag` is specified these three arguments will be missing so if you still want them in your command add them to the `--pip-custom-flag` argument.

Example: `--pip-custom-flag="--no-compile --prefer-binary --ignore-installed --report path/to/report.json --progress-bar on"`

* `--ui-source-map` - [optional] if present generates front-end source maps (.js.map files), that helps with code debugging.

### Verbose mode
Expand Down
3 changes: 3 additions & 0 deletions splunk_add_on_ucc_framework/commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ def generate(
pip_version: str = "latest",
pip_legacy_resolver: bool = False,
ui_source_map: bool = False,
pip_custom_flag: Optional[str] = None,
) -> None:
logger.info(f"ucc-gen version {__version__} is used")
logger.info(f"Python binary name to use: {python_binary_name}")
Expand Down Expand Up @@ -499,6 +500,7 @@ def generate(
os_libraries=global_config.os_libraries,
pip_version=pip_version,
pip_legacy_resolver=pip_legacy_resolver,
pip_custom_flag=pip_custom_flag,
)
except SplunktaucclibNotFound as e:
logger.error(str(e))
Expand Down Expand Up @@ -566,6 +568,7 @@ def generate(
python_binary_name,
pip_version=pip_version,
pip_legacy_resolver=pip_legacy_resolver,
pip_custom_flag=pip_custom_flag,
)
logger.info(
f"Installed add-on requirements into {ucc_lib_target} from {source}"
Expand Down
14 changes: 10 additions & 4 deletions splunk_add_on_ucc_framework/install_python_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def install_python_libraries(
os_libraries: Optional[List[OSDependentLibraryConfig]] = None,
pip_version: str = "latest",
pip_legacy_resolver: bool = False,
pip_custom_flag: Optional[str] = None,
) -> None:
path_to_requirements_file = os.path.join(source_path, "lib", "requirements.txt")
if os.path.isfile(path_to_requirements_file):
Expand All @@ -163,6 +164,7 @@ def install_python_libraries(
installer=python_binary_name,
pip_version=pip_version,
pip_legacy_resolver=pip_legacy_resolver,
pip_custom_flag=pip_custom_flag,
)
if includes_ui:
_check_libraries_required_for_ui(
Expand Down Expand Up @@ -202,6 +204,7 @@ def install_libraries(
installer: str,
pip_version: str = "latest",
pip_legacy_resolver: bool = False,
pip_custom_flag: Optional[str] = None,
) -> None:
"""
Upgrades `pip` version to the latest one and installs requirements to the
Expand All @@ -222,13 +225,16 @@ def install_libraries(
sys.exit(1)

deps_resolver = "--use-deprecated=legacy-resolver " if pip_legacy_resolver else ""
custom_flag = (
pip_custom_flag
if pip_custom_flag
else "--no-compile --prefer-binary --ignore-installed "
)
pip_install_command = (
f'-r "{requirements_file_path}" '
f"--no-compile "
f"--prefer-binary "
f"--ignore-installed "
f"{deps_resolver}"
f'--target "{installation_path}"'
f'--target "{installation_path}" '
f"{custom_flag}"
)
_pip_install(
installer=installer, command=pip_update_command, command_desc="pip upgrade"
Expand Down
8 changes: 8 additions & 0 deletions splunk_add_on_ucc_framework/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
help="Use old pip dependency resolver by adding flag '--use-deprecated=legacy-resolver' "
"to pip install command.",
)
build_parser.add_argument(
"--pip-custom-flag",
help="Custom flag that will be add to pip install command",
type=str,
default=False,
required=False,
)
build_parser.add_argument(
"--ui-source-map",
help="Adds front-end source-map files .js.map",
Expand Down Expand Up @@ -216,6 +223,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
pip_version=args.pip_version,
pip_legacy_resolver=args.pip_legacy_resolver,
ui_source_map=args.ui_source_map,
pip_custom_flag=args.pip_custom_flag,
)
if args.command == "package":
package.package(path_to_built_addon=args.path, output_directory=args.output)
Expand Down
70 changes: 64 additions & 6 deletions tests/unit/test_install_python_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ def test_install_libraries(mock_subprocess_run):

expected_install_command = (
'python3 -m pip install -r "package/lib/requirements.txt"'
" --no-compile --prefer-binary --ignore-installed "
'--target "/path/to/output/addon_name/lib"'
' --target "/path/to/output/addon_name/lib" '
"--no-compile --prefer-binary --ignore-installed "
)
expected_pip_update_command = "python3 -m pip install --upgrade pip"
mock_subprocess_run.assert_has_calls(
Expand Down Expand Up @@ -413,8 +413,8 @@ def test_install_libraries_custom_pip(mock_subprocess_run):

expected_install_command = (
'python3 -m pip install -r "package/lib/requirements.txt"'
" --no-compile --prefer-binary --ignore-installed "
'--target "/path/to/output/addon_name/lib"'
' --target "/path/to/output/addon_name/lib" '
"--no-compile --prefer-binary --ignore-installed "
)
expected_pip_update_command = "python3 -m pip install --upgrade pip==21.666.666"
mock_subprocess_run.assert_has_calls(
Expand Down Expand Up @@ -442,8 +442,8 @@ def test_install_libraries_legacy_resolver(mock_subprocess_run):

expected_install_command = (
'python3 -m pip install -r "package/lib/requirements.txt"'
" --no-compile --prefer-binary --ignore-installed "
'--use-deprecated=legacy-resolver --target "/path/to/output/addon_name/lib"'
' --use-deprecated=legacy-resolver --target "/path/to/output/addon_name/lib" '
"--no-compile --prefer-binary --ignore-installed "
)
expected_pip_update_command = "python3 -m pip install --upgrade pip"
mock_subprocess_run.assert_has_calls(
Expand Down Expand Up @@ -507,3 +507,61 @@ def test_validate_conflicting_paths_empty_list():
def test_is_pip_lib_installed_wrong_arguments():
with pytest.raises(InvalidArguments):
_pip_is_lib_installed("i", "t", "l", allow_higher_version=True)


@mock.patch("subprocess.run", autospec=True)
def test_install_libraries_pip_custom_flag(mock_subprocess_run):
mock_subprocess_run.return_value = MockSubprocessResult(0)

install_libraries(
"package/lib/requirements.txt",
"/path/to/output/addon_name/lib",
"python3",
pip_custom_flag="--report path/to/json.json",
)

expected_install_command = (
'python3 -m pip install -r "package/lib/requirements.txt"'
' --target "/path/to/output/addon_name/lib" --report path/to/json.json'
)
expected_pip_update_command = "python3 -m pip install --upgrade pip"
mock_subprocess_run.assert_has_calls(
[
mock.call(
expected_pip_update_command, shell=True, env=None, capture_output=True
),
mock.call(
expected_install_command, shell=True, env=None, capture_output=True
),
]
)


@mock.patch("subprocess.run", autospec=True)
def test_install_libraries_multiple_pip_custom_flags(mock_subprocess_run):
mock_subprocess_run.return_value = MockSubprocessResult(0)

install_libraries(
"package/lib/requirements.txt",
"/path/to/output/addon_name/lib",
"python3",
pip_custom_flag="--no-compile --prefer-binary --ignore-installed "
"--report path/to/json.json --progress-bar on --require-hashes",
)

expected_install_command = (
'python3 -m pip install -r "package/lib/requirements.txt"'
' --target "/path/to/output/addon_name/lib" --no-compile --prefer-binary --ignore-installed '
"--report path/to/json.json --progress-bar on --require-hashes"
)
expected_pip_update_command = "python3 -m pip install --upgrade pip"
mock_subprocess_run.assert_has_calls(
[
mock.call(
expected_pip_update_command, shell=True, env=None, capture_output=True
),
mock.call(
expected_install_command, shell=True, env=None, capture_output=True
),
]
)
38 changes: 38 additions & 0 deletions tests/unit/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -33,6 +34,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -47,6 +49,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -61,6 +64,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -75,6 +79,7 @@
"verbose_file_summary_report": True,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -96,6 +101,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -119,6 +125,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -144,6 +151,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -170,6 +178,7 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand Down Expand Up @@ -197,6 +206,7 @@
"verbose_file_summary_report": True,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand Down Expand Up @@ -226,6 +236,7 @@
"verbose_file_summary_report": True,
"pip_version": "21.0.0",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand Down Expand Up @@ -256,6 +267,7 @@
"verbose_file_summary_report": True,
"pip_version": "21.0.0",
"pip_legacy_resolver": True,
"pip_custom_flag": False,
"ui_source_map": False,
},
),
Expand All @@ -278,6 +290,32 @@
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": False,
"ui_source_map": True,
},
),
(
[
"--source",
"package",
"--ta-version",
"2.2.0",
"--python-binary-name",
"python.exe",
"--ui-source-map",
"--pip-custom-flag",
"--progress-bar on",
],
{
"source": "package",
"config_path": None,
"addon_version": "2.2.0",
"output_directory": None,
"python_binary_name": "python.exe",
"verbose_file_summary_report": False,
"pip_version": "latest",
"pip_legacy_resolver": False,
"pip_custom_flag": "--progress-bar on",
"ui_source_map": True,
},
),
Expand Down

0 comments on commit 718c897

Please sign in to comment.