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

feat(client): auto active env in bash/fish/zsh when executing runtime active cmd #868

Merged
merged 1 commit into from
Aug 5, 2022
Merged
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
16 changes: 14 additions & 2 deletions client/starwhale/core/runtime/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,20 @@ def _quickstart_from_uri(
default=False,
show_default=True,
)
@click.option(
"-i",
"--interactive",
is_flag=True,
default=False,
help="Try entering the interactive shell at the end",
)
def _quickstart(
workdir: str, force: bool, python_env: str, name: str, create_env: bool
workdir: str,
force: bool,
python_env: str,
name: str,
create_env: bool,
interactive: bool,
) -> None:
"""[Only Standalone]Quickstart Starwhale Runtime

Expand All @@ -99,7 +111,7 @@ def _quickstart(
p_workdir = Path(workdir).absolute()
name = name or p_workdir.name
RuntimeTermView.quickstart_from_ishell(
p_workdir, name, python_env, create_env, force
p_workdir, name, python_env, create_env, force, interactive
)


Expand Down
7 changes: 5 additions & 2 deletions client/starwhale/core/runtime/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ def quickstart_from_ishell(
mode: str,
create_env: bool = False,
force: bool = False,
interactive: bool = False,
) -> None:
workdir = Path(workdir).absolute()
console.print(f":printer: render runtime.yaml @ {workdir}")
Expand Down Expand Up @@ -833,7 +834,7 @@ def quickstart_from_ishell(
elif mode == PythonRunEnv.CONDA:
conda_install_req(env_name=_id, req=sw_pkg, enable_pre=True)

activate_python_env(mode=mode, identity=_id)
activate_python_env(mode=mode, identity=_id, interactive=interactive)

@classmethod
def activate(cls, path: str = "", uri: str = "") -> None:
Expand All @@ -854,7 +855,9 @@ def activate(cls, path: str = "", uri: str = "") -> None:
else:
raise Exception("No uri or path to activate")

activate_python_env(mode=mode, identity=str(prefix_path.resolve()))
activate_python_env(
mode=mode, identity=str(prefix_path.resolve()), interactive=True
)

@classmethod
def lock(
Expand Down
5 changes: 4 additions & 1 deletion client/starwhale/core/runtime/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,14 @@ def quickstart_from_ishell(
mode: str,
create_env: bool = False,
force: bool = False,
interactive: bool = False,
) -> None:
console.print(
f":construction: quickstart Starwhale Runtime[{name}] environment..."
)
StandaloneRuntime.quickstart_from_ishell(workdir, name, mode, create_env, force)
StandaloneRuntime.quickstart_from_ishell(
workdir, name, mode, create_env, force, interactive
)
console.print(":clap: Starwhale Runtime environment is ready to use :tada:")

@classmethod
Expand Down
41 changes: 32 additions & 9 deletions client/starwhale/utils/venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,20 +545,43 @@ def package_python_env(
return True


def activate_python_env(
mode: str,
identity: str,
) -> None:
# TODO: switch shell python environment directly
console.print(":cake: run command in shell :cake:")

def activate_python_env(mode: str, identity: str, interactive: bool) -> None:
if mode == PythonRunEnv.VENV:
cmd = f"source {identity}/bin/activate"
elif mode == PythonRunEnv.CONDA:
cmd = f"conda activate {identity}"
else:
raise NoSupportError(mode)

if interactive:
import shellingham

try:
_name, _bin = shellingham.detect_shell()
except shellingham.ShellDetectionFailure:
_name, _bin = "", ""

if _name == "zsh":
# https://zsh.sourceforge.io/Intro/intro_3.html
os.execl(
_bin,
_bin,
"-c",
f"""temp_dir={identity} && \
echo ". $HOME/.zshrc && {cmd}" > $temp_dir/.zshrc && \
ZDOTDIR=$temp_dir zsh -i""",
)
elif _name == "bash":
# https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
os.execl(
_bin, _bin, "-c", f'bash --rcfile <(echo ". "$HOME/.bashrc" && {cmd}")'
)
elif _name == "fish":
# https://fishshell.com/docs/current/language.html#configuration
os.execl(_bin, _bin, "-C", cmd)

# user executes the command manually
console.print(":cake: run command in shell :cake:")
console.print(f"\t[red][bold]{cmd}")


Expand All @@ -569,7 +592,6 @@ def create_python_env(
python_version: str = DEFAULT_PYTHON_VERSION,
force: bool = False,
) -> str:

if mode == PythonRunEnv.VENV:
venvdir = workdir / ".venv"
if venvdir.exists() and not force:
Expand Down Expand Up @@ -666,7 +688,8 @@ def is_venv() -> bool:
[
"python3",
"-c",
"import sys; print(sys.prefix != (getattr(sys, 'base_prefix', None) or (getattr(sys, 'real_prefix', None) or sys.prefix)))", # noqa: E501
"import sys; print(sys.prefix != (getattr(sys, 'base_prefix', None) or (getattr(sys, 'real_prefix', None) or sys.prefix)))",
# noqa: E501
],
)
return "True" in output.decode() or get_venv_env() != ""
Expand Down