playground-ls-cli 4.14.1.dev8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- localstack_cli/__init__.py +0 -0
- localstack_cli/cli/__init__.py +10 -0
- localstack_cli/cli/console.py +11 -0
- localstack_cli/cli/core_plugin.py +12 -0
- localstack_cli/cli/exceptions.py +19 -0
- localstack_cli/cli/localstack.py +951 -0
- localstack_cli/cli/lpm.py +138 -0
- localstack_cli/cli/main.py +22 -0
- localstack_cli/cli/plugin.py +39 -0
- localstack_cli/cli/plugins.py +134 -0
- localstack_cli/cli/profiles.py +65 -0
- localstack_cli/config.py +1689 -0
- localstack_cli/constants.py +165 -0
- localstack_cli/logging/__init__.py +0 -0
- localstack_cli/logging/format.py +194 -0
- localstack_cli/logging/setup.py +142 -0
- localstack_cli/packages/__init__.py +25 -0
- localstack_cli/packages/api.py +418 -0
- localstack_cli/packages/core.py +416 -0
- localstack_cli/pro/__init__.py +0 -0
- localstack_cli/pro/core/__init__.py +0 -0
- localstack_cli/pro/core/bootstrap/__init__.py +1 -0
- localstack_cli/pro/core/bootstrap/auth.py +213 -0
- localstack_cli/pro/core/bootstrap/dns_utils.py +55 -0
- localstack_cli/pro/core/bootstrap/entitlements.py +117 -0
- localstack_cli/pro/core/bootstrap/extensions/__init__.py +3 -0
- localstack_cli/pro/core/bootstrap/extensions/__main__.py +106 -0
- localstack_cli/pro/core/bootstrap/extensions/autoinstall.py +63 -0
- localstack_cli/pro/core/bootstrap/extensions/bootstrap.py +97 -0
- localstack_cli/pro/core/bootstrap/extensions/repository.py +374 -0
- localstack_cli/pro/core/bootstrap/licensingv2.py +1259 -0
- localstack_cli/pro/core/bootstrap/pods/__init__.py +0 -0
- localstack_cli/pro/core/bootstrap/pods/api_types.py +17 -0
- localstack_cli/pro/core/bootstrap/pods/constants.py +26 -0
- localstack_cli/pro/core/bootstrap/pods/remotes/__init__.py +0 -0
- localstack_cli/pro/core/bootstrap/pods/remotes/api.py +75 -0
- localstack_cli/pro/core/bootstrap/pods/remotes/configs.py +69 -0
- localstack_cli/pro/core/bootstrap/pods/remotes/params.py +86 -0
- localstack_cli/pro/core/bootstrap/pods_client.py +834 -0
- localstack_cli/pro/core/cli/__init__.py +0 -0
- localstack_cli/pro/core/cli/auth.py +226 -0
- localstack_cli/pro/core/cli/aws.py +16 -0
- localstack_cli/pro/core/cli/cli.py +99 -0
- localstack_cli/pro/core/cli/click_utils.py +21 -0
- localstack_cli/pro/core/cli/cloud_pods.py +465 -0
- localstack_cli/pro/core/cli/diff_view.py +41 -0
- localstack_cli/pro/core/cli/ephemeral.py +199 -0
- localstack_cli/pro/core/cli/extensions.py +492 -0
- localstack_cli/pro/core/cli/iam.py +180 -0
- localstack_cli/pro/core/cli/license.py +90 -0
- localstack_cli/pro/core/cli/localstack.py +118 -0
- localstack_cli/pro/core/cli/replicator.py +378 -0
- localstack_cli/pro/core/cli/state.py +183 -0
- localstack_cli/pro/core/cli/tree_view.py +235 -0
- localstack_cli/pro/core/config.py +556 -0
- localstack_cli/pro/core/constants.py +54 -0
- localstack_cli/pro/core/plugins.py +169 -0
- localstack_cli/runtime/__init__.py +6 -0
- localstack_cli/runtime/exceptions.py +7 -0
- localstack_cli/runtime/hooks.py +73 -0
- localstack_cli/testing/__init__.py +1 -0
- localstack_cli/testing/config.py +4 -0
- localstack_cli/utils/__init__.py +0 -0
- localstack_cli/utils/analytics/__init__.py +12 -0
- localstack_cli/utils/analytics/cli.py +67 -0
- localstack_cli/utils/analytics/client.py +111 -0
- localstack_cli/utils/analytics/events.py +30 -0
- localstack_cli/utils/analytics/logger.py +48 -0
- localstack_cli/utils/analytics/metadata.py +250 -0
- localstack_cli/utils/analytics/publisher.py +160 -0
- localstack_cli/utils/analytics/service_request_aggregator.py +133 -0
- localstack_cli/utils/archives.py +271 -0
- localstack_cli/utils/batching.py +258 -0
- localstack_cli/utils/bootstrap.py +1418 -0
- localstack_cli/utils/checksum.py +313 -0
- localstack_cli/utils/collections.py +554 -0
- localstack_cli/utils/common.py +229 -0
- localstack_cli/utils/container_networking.py +142 -0
- localstack_cli/utils/container_utils/__init__.py +0 -0
- localstack_cli/utils/container_utils/container_client.py +1585 -0
- localstack_cli/utils/container_utils/docker_cmd_client.py +987 -0
- localstack_cli/utils/container_utils/docker_sdk_client.py +1018 -0
- localstack_cli/utils/crypto.py +294 -0
- localstack_cli/utils/docker_utils.py +272 -0
- localstack_cli/utils/files.py +327 -0
- localstack_cli/utils/functions.py +92 -0
- localstack_cli/utils/http.py +326 -0
- localstack_cli/utils/json.py +219 -0
- localstack_cli/utils/net.py +516 -0
- localstack_cli/utils/no_exit_argument_parser.py +19 -0
- localstack_cli/utils/numbers.py +49 -0
- localstack_cli/utils/objects.py +235 -0
- localstack_cli/utils/patch.py +260 -0
- localstack_cli/utils/platform.py +77 -0
- localstack_cli/utils/run.py +514 -0
- localstack_cli/utils/server/__init__.py +0 -0
- localstack_cli/utils/server/tcp_proxy.py +108 -0
- localstack_cli/utils/serving.py +187 -0
- localstack_cli/utils/ssl.py +71 -0
- localstack_cli/utils/strings.py +245 -0
- localstack_cli/utils/sync.py +267 -0
- localstack_cli/utils/threads.py +163 -0
- localstack_cli/utils/time.py +81 -0
- localstack_cli/utils/urls.py +21 -0
- localstack_cli/utils/venv.py +100 -0
- localstack_cli/utils/xml.py +41 -0
- localstack_cli/version.py +34 -0
- playground_ls_cli-4.14.1.dev8.dist-info/METADATA +95 -0
- playground_ls_cli-4.14.1.dev8.dist-info/RECORD +112 -0
- playground_ls_cli-4.14.1.dev8.dist-info/WHEEL +5 -0
- playground_ls_cli-4.14.1.dev8.dist-info/entry_points.txt +17 -0
- playground_ls_cli-4.14.1.dev8.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import logging
|
|
3
|
+
from multiprocessing.pool import ThreadPool
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from localstack_cli import config
|
|
9
|
+
from localstack_cli.cli.exceptions import CLIError
|
|
10
|
+
from localstack_cli.packages import InstallTarget, Package
|
|
11
|
+
from localstack_cli.packages.api import NoSuchPackageException, PackagesPluginManager
|
|
12
|
+
from localstack_cli.utils.bootstrap import setup_logging
|
|
13
|
+
|
|
14
|
+
LOG = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.group()
|
|
20
|
+
def cli():
|
|
21
|
+
"""
|
|
22
|
+
The LocalStack Package Manager (lpm) CLI is a set of commands to install third-party packages used by localstack
|
|
23
|
+
service providers.
|
|
24
|
+
|
|
25
|
+
Here are some handy commands:
|
|
26
|
+
|
|
27
|
+
List all packages
|
|
28
|
+
|
|
29
|
+
python -m localstack.cli.lpm list
|
|
30
|
+
|
|
31
|
+
Install DynamoDB Local:
|
|
32
|
+
|
|
33
|
+
python -m localstack.cli.install dynamodb-local
|
|
34
|
+
|
|
35
|
+
Install all community packages, four in parallel:
|
|
36
|
+
|
|
37
|
+
python -m localstack.cli.lpm list | grep "/community" | cut -d'/' -f1 | xargs python -m localstack.cli.lpm install --parallel 4
|
|
38
|
+
"""
|
|
39
|
+
setup_logging()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _do_install_package(package: Package, version: str = None, target: InstallTarget = None):
|
|
43
|
+
console.print(f"installing... [bold]{package}[/bold]")
|
|
44
|
+
try:
|
|
45
|
+
package.install(version=version, target=target)
|
|
46
|
+
console.print(f"[green]installed[/green] [bold]{package}[/bold]")
|
|
47
|
+
except Exception as e:
|
|
48
|
+
console.print(f"[red]error[/red] installing {package}: {e}")
|
|
49
|
+
raise e
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@cli.command()
|
|
53
|
+
@click.argument("package", nargs=-1, required=True)
|
|
54
|
+
@click.option(
|
|
55
|
+
"--parallel",
|
|
56
|
+
type=int,
|
|
57
|
+
default=1,
|
|
58
|
+
required=False,
|
|
59
|
+
help="how many installers to run in parallel processes",
|
|
60
|
+
)
|
|
61
|
+
@click.option(
|
|
62
|
+
"--version",
|
|
63
|
+
type=str,
|
|
64
|
+
default=None,
|
|
65
|
+
required=False,
|
|
66
|
+
help="version to install of a package",
|
|
67
|
+
)
|
|
68
|
+
@click.option(
|
|
69
|
+
"--target",
|
|
70
|
+
type=click.Choice([target.name.lower() for target in InstallTarget]),
|
|
71
|
+
default=None,
|
|
72
|
+
required=False,
|
|
73
|
+
help="target of the installation",
|
|
74
|
+
)
|
|
75
|
+
def install(
|
|
76
|
+
package: list[str],
|
|
77
|
+
parallel: int | None = 1,
|
|
78
|
+
version: str | None = None,
|
|
79
|
+
target: str | None = None,
|
|
80
|
+
):
|
|
81
|
+
"""Install one or more packages."""
|
|
82
|
+
try:
|
|
83
|
+
if target:
|
|
84
|
+
target = InstallTarget[str.upper(target)]
|
|
85
|
+
else:
|
|
86
|
+
# LPM is meant to be used at build-time, the default target is static_libs
|
|
87
|
+
target = InstallTarget.STATIC_LIBS
|
|
88
|
+
|
|
89
|
+
# collect installers and install in parallel:
|
|
90
|
+
console.print(f"resolving packages: {package}")
|
|
91
|
+
package_manager = PackagesPluginManager()
|
|
92
|
+
package_manager.load_all()
|
|
93
|
+
package_instances = package_manager.get_packages(package, version)
|
|
94
|
+
|
|
95
|
+
if parallel > 1:
|
|
96
|
+
console.print(f"install {parallel} packages in parallel:")
|
|
97
|
+
|
|
98
|
+
config.dirs.mkdirs()
|
|
99
|
+
|
|
100
|
+
with ThreadPool(processes=parallel) as pool:
|
|
101
|
+
pool.starmap(
|
|
102
|
+
_do_install_package,
|
|
103
|
+
zip(package_instances, itertools.repeat(version), itertools.repeat(target)),
|
|
104
|
+
)
|
|
105
|
+
except NoSuchPackageException as e:
|
|
106
|
+
LOG.debug(str(e), exc_info=e)
|
|
107
|
+
raise CLIError(str(e))
|
|
108
|
+
except Exception as e:
|
|
109
|
+
LOG.debug("one or more package installations failed.", exc_info=e)
|
|
110
|
+
raise CLIError("one or more package installations failed.")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@cli.command(name="list")
|
|
114
|
+
@click.option(
|
|
115
|
+
"-v",
|
|
116
|
+
"--verbose",
|
|
117
|
+
is_flag=True,
|
|
118
|
+
default=False,
|
|
119
|
+
required=False,
|
|
120
|
+
help="Verbose output (show additional info on packages)",
|
|
121
|
+
)
|
|
122
|
+
def list_packages(verbose: bool):
|
|
123
|
+
"""List available packages of all repositories"""
|
|
124
|
+
package_manager = PackagesPluginManager()
|
|
125
|
+
package_manager.load_all()
|
|
126
|
+
packages = package_manager.get_all_packages()
|
|
127
|
+
for package_name, package_scope, package_instance in packages:
|
|
128
|
+
console.print(f"[green]{package_name}[/green]/{package_scope}")
|
|
129
|
+
if verbose:
|
|
130
|
+
for version in package_instance.get_versions():
|
|
131
|
+
if version == package_instance.default_version:
|
|
132
|
+
console.print(f" - [bold]{version} (default)[/bold]", highlight=False)
|
|
133
|
+
else:
|
|
134
|
+
console.print(f" - {version}", highlight=False)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
if __name__ == "__main__":
|
|
138
|
+
cli()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def main():
|
|
5
|
+
# indicate to the environment we are starting from the CLI
|
|
6
|
+
os.environ["LOCALSTACK_CLI"] = "1"
|
|
7
|
+
|
|
8
|
+
# config profiles are the first thing that need to be loaded (especially before localstack.config!)
|
|
9
|
+
from .profiles import set_and_remove_profile_from_sys_argv
|
|
10
|
+
|
|
11
|
+
# WARNING: This function modifies sys.argv to remove the profile argument.
|
|
12
|
+
set_and_remove_profile_from_sys_argv()
|
|
13
|
+
|
|
14
|
+
# initialize CLI plugins
|
|
15
|
+
from .localstack import create_with_plugins
|
|
16
|
+
|
|
17
|
+
cli = create_with_plugins()
|
|
18
|
+
cli()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from plux import Plugin, PluginManager
|
|
7
|
+
|
|
8
|
+
LOG = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class LocalstackCli:
|
|
12
|
+
group: click.Group
|
|
13
|
+
|
|
14
|
+
def __call__(self, *args, **kwargs):
|
|
15
|
+
self.group(*args, **kwargs)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LocalstackCliPlugin(Plugin):
|
|
19
|
+
namespace = "localstack_cli.plugins.cli"
|
|
20
|
+
|
|
21
|
+
def load(self, cli) -> None:
|
|
22
|
+
self.attach(cli)
|
|
23
|
+
|
|
24
|
+
@abc.abstractmethod
|
|
25
|
+
def attach(self, cli: LocalstackCli) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Attach commands to the `localstack` CLI.
|
|
28
|
+
|
|
29
|
+
:param cli: the cli object
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def load_cli_plugins(cli):
|
|
34
|
+
if os.environ.get("DEBUG_PLUGINS", "0").lower() in ("true", "1"):
|
|
35
|
+
# importing localstack.config is still quite expensive...
|
|
36
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
37
|
+
|
|
38
|
+
loader = PluginManager("localstack_cli.plugins.cli", load_args=(cli,))
|
|
39
|
+
loader.load_all()
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
from plux import PluginManager
|
|
6
|
+
from plux.build.setuptools import find_plugins
|
|
7
|
+
from plux.core.entrypoint import spec_to_entry_point
|
|
8
|
+
from rich import print as rprint
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from rich.tree import Tree
|
|
12
|
+
|
|
13
|
+
from localstack_cli.cli.exceptions import CLIError
|
|
14
|
+
|
|
15
|
+
console = Console()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.group()
|
|
19
|
+
def cli():
|
|
20
|
+
"""
|
|
21
|
+
The plugins CLI is a set of commands to help troubleshoot LocalStack's plugin mechanism.
|
|
22
|
+
"""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@cli.command()
|
|
27
|
+
@click.option("--where", type=str, default=os.path.abspath(os.curdir))
|
|
28
|
+
@click.option("--exclude", multiple=True, default=())
|
|
29
|
+
@click.option("--include", multiple=True, default=("*",))
|
|
30
|
+
@click.option("--output", type=str, default="tree")
|
|
31
|
+
def find(where, exclude, include, output):
|
|
32
|
+
"""
|
|
33
|
+
Find plugins by scanning the given path for PluginSpecs.
|
|
34
|
+
It starts from the current directory if --where is not specified.
|
|
35
|
+
This is what a setup.py method would run as a build step, i.e., discovering entry points.
|
|
36
|
+
"""
|
|
37
|
+
with console.status(f"Scanning path {where}"):
|
|
38
|
+
plugins = find_plugins(where, exclude, include)
|
|
39
|
+
|
|
40
|
+
if output == "tree":
|
|
41
|
+
tree = Tree("Entrypoints")
|
|
42
|
+
for namespace, entry_points in plugins.items():
|
|
43
|
+
node = tree.add(f"[bold]{namespace}")
|
|
44
|
+
|
|
45
|
+
t = Table()
|
|
46
|
+
t.add_column("Name")
|
|
47
|
+
t.add_column("Location")
|
|
48
|
+
|
|
49
|
+
for ep in entry_points:
|
|
50
|
+
key, value = ep.split("=")
|
|
51
|
+
t.add_row(key, value)
|
|
52
|
+
|
|
53
|
+
node.add(t)
|
|
54
|
+
|
|
55
|
+
rprint(tree)
|
|
56
|
+
elif output == "dict":
|
|
57
|
+
rprint(dict(plugins))
|
|
58
|
+
else:
|
|
59
|
+
raise CLIError(f"unknown output format {output}")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@cli.command("list")
|
|
63
|
+
@click.option("--namespace", type=str, required=True)
|
|
64
|
+
def cmd_list(namespace):
|
|
65
|
+
"""
|
|
66
|
+
List all available plugins using a PluginManager from available endpoints.
|
|
67
|
+
"""
|
|
68
|
+
manager = PluginManager(namespace)
|
|
69
|
+
|
|
70
|
+
t = Table()
|
|
71
|
+
t.add_column("Name")
|
|
72
|
+
t.add_column("Factory")
|
|
73
|
+
|
|
74
|
+
for spec in manager.list_plugin_specs():
|
|
75
|
+
ep = spec_to_entry_point(spec)
|
|
76
|
+
t.add_row(spec.name, ep.value)
|
|
77
|
+
|
|
78
|
+
rprint(t)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@cli.command()
|
|
82
|
+
@click.option("--namespace", type=str, required=True)
|
|
83
|
+
@click.option("--name", type=str, required=True)
|
|
84
|
+
def load(namespace, name):
|
|
85
|
+
"""
|
|
86
|
+
Attempts to load a plugin using a PluginManager.
|
|
87
|
+
"""
|
|
88
|
+
manager = PluginManager(namespace)
|
|
89
|
+
|
|
90
|
+
with console.status(f"Loading {namespace}:{name}"):
|
|
91
|
+
then = time.time()
|
|
92
|
+
plugin = manager.load(name)
|
|
93
|
+
took = time.time() - then
|
|
94
|
+
|
|
95
|
+
rprint(
|
|
96
|
+
f":tada: successfully loaded [bold][green]{namespace}[/green][/bold]:[bold][cyan]{name}[/cyan][/bold] ({type(plugin)}"
|
|
97
|
+
)
|
|
98
|
+
rprint(f":stopwatch: loading took {took:.4f} s")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@cli.command()
|
|
102
|
+
@click.option("--namespace", type=str)
|
|
103
|
+
def cache(namespace):
|
|
104
|
+
"""
|
|
105
|
+
Outputs the stevedore entrypoints cache from which plugins are loaded.
|
|
106
|
+
"""
|
|
107
|
+
from stevedore._cache import _c
|
|
108
|
+
|
|
109
|
+
data = _c._get_data_for_path(None)
|
|
110
|
+
|
|
111
|
+
tree = Tree("Entrypoints")
|
|
112
|
+
for group, entry_points in data.get("groups").items():
|
|
113
|
+
if namespace and group != namespace:
|
|
114
|
+
continue
|
|
115
|
+
node = tree.add(f"[bold]{group}")
|
|
116
|
+
|
|
117
|
+
t = Table()
|
|
118
|
+
t.add_column("Name")
|
|
119
|
+
t.add_column("Value")
|
|
120
|
+
|
|
121
|
+
for key, value, _ in entry_points:
|
|
122
|
+
t.add_row(key, value)
|
|
123
|
+
|
|
124
|
+
node.add(t)
|
|
125
|
+
|
|
126
|
+
if namespace:
|
|
127
|
+
rprint(t)
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
rprint(tree)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
cli()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
# important: this needs to be free of localstack imports
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def set_and_remove_profile_from_sys_argv():
|
|
9
|
+
"""
|
|
10
|
+
Performs the following steps:
|
|
11
|
+
|
|
12
|
+
1. Use argparse to parse the command line arguments for the --profile flag.
|
|
13
|
+
All occurrences are removed from the sys.argv list, and the value from
|
|
14
|
+
the last occurrence is used. This allows the user to specify a profile
|
|
15
|
+
at any point on the command line.
|
|
16
|
+
|
|
17
|
+
2. If a --profile flag is not found, check for the -p flag. The first
|
|
18
|
+
occurrence of the -p flag is used and it is not removed from sys.argv.
|
|
19
|
+
The reasoning for this is that at least one of the CLI subcommands has
|
|
20
|
+
a -p flag, and we want to keep it in sys.argv for that command to
|
|
21
|
+
pick up. An existing bug means that if a -p flag is used with a
|
|
22
|
+
subcommand, it could erroneously be used as the profile value as well.
|
|
23
|
+
This behaviour is undesired, but we must maintain back-compatibility of
|
|
24
|
+
allowing the profile to be specified using -p.
|
|
25
|
+
|
|
26
|
+
3. If a profile is found, the 'CONFIG_PROFILE' os variable is set
|
|
27
|
+
accordingly. This is later picked up by ``localstack.config``.
|
|
28
|
+
|
|
29
|
+
WARNING: Any --profile options are REMOVED from sys.argv, so that they are
|
|
30
|
+
not passed to the localstack CLI. This allows the profile option
|
|
31
|
+
to be set at any point on the command line.
|
|
32
|
+
"""
|
|
33
|
+
parser = argparse.ArgumentParser(add_help=False)
|
|
34
|
+
parser.add_argument("--profile")
|
|
35
|
+
namespace, sys.argv = parser.parse_known_args(sys.argv)
|
|
36
|
+
profile = namespace.profile
|
|
37
|
+
|
|
38
|
+
if not profile:
|
|
39
|
+
# if no profile is given, check for the -p argument
|
|
40
|
+
profile = parse_p_argument(sys.argv)
|
|
41
|
+
|
|
42
|
+
if profile:
|
|
43
|
+
os.environ["CONFIG_PROFILE"] = profile.strip()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def parse_p_argument(args) -> str | None:
|
|
47
|
+
"""
|
|
48
|
+
Lightweight arg parsing to find the first occurrence of ``-p <config>``, or ``-p=<config>`` and return the value of
|
|
49
|
+
``<config>`` from the given arguments.
|
|
50
|
+
|
|
51
|
+
:param args: list of CLI arguments
|
|
52
|
+
:returns: the value of ``-p``.
|
|
53
|
+
"""
|
|
54
|
+
for i, current_arg in enumerate(args):
|
|
55
|
+
if current_arg.startswith("-p="):
|
|
56
|
+
# if using the "<arg>=<value>" notation, we remove the "-p=" prefix to get the value
|
|
57
|
+
return current_arg[3:]
|
|
58
|
+
if current_arg == "-p":
|
|
59
|
+
# otherwise use the next arg in the args list as value
|
|
60
|
+
try:
|
|
61
|
+
return args[i + 1]
|
|
62
|
+
except IndexError:
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
return None
|