Skip to content

Commit

Permalink
Make updates for logic to work on Windows
Browse files Browse the repository at this point in the history
Specifically:

* Handle problematic characters such as spaces by
  quoting arguments

* Add compatibilty shims for differences in virtualenv
  and executable names

We should also consider making these additional improvements:

* See if we can add a compatibilty shim to make the default
  prefix on Windows C:\Program Files\aws-cli in order to make
  a more sane Windows default.

* Consider copying over the aws_completer to the bin folder.
  This is not too useful for Windows since it does not use
  bash. It would also require making a .cmd file for the
  completer.
  • Loading branch information
kyleknap committed Aug 24, 2021
1 parent 20d1a2e commit def990c
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 155 deletions.
22 changes: 11 additions & 11 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@ DOWNLOAD_DEPS_FLAG = @DOWNLOAD_DEPS_FLAG@
all: build

build:
$(PYTHON) $(srcdir)/scripts/buildctl \
"$(PYTHON)" "$(srcdir)/scripts/buildctl" \
build \
--artifact $(INSTALL_TYPE) \
--build-dir $(aws_cli_builddir) $(DOWNLOAD_DEPS_FLAG)
--artifact "$(INSTALL_TYPE)" \
--build-dir "$(aws_cli_builddir)" $(DOWNLOAD_DEPS_FLAG)

clean:
rm -rf $(aws_cli_builddir)
rm -rf "$(aws_cli_builddir)"

install:
$(PYTHON) $(srcdir)/scripts/buildctl \
"$(PYTHON)" "$(srcdir)/scripts/buildctl" \
install \
--build-dir $(aws_cli_builddir) \
--lib-dir $(libdir) \
--bin-dir $(bindir)
--build-dir "$(aws_cli_builddir)" \
--lib-dir "$(libdir)" \
--bin-dir "$(bindir)"

uninstall:
$(PYTHON) $(srcdir)/scripts/buildctl \
"$(PYTHON)" "$(srcdir)/scripts/buildctl" \
uninstall \
--lib-dir $(libdir) \
--bin-dir $(bindir)
--lib-dir "$(libdir)" \
--bin-dir "$(bindir)"

.PHONY: all build install uninstall
32 changes: 1 addition & 31 deletions bin/aws.cmd
Original file line number Diff line number Diff line change
@@ -1,34 +1,4 @@
@echo OFF
REM="""
setlocal
set PythonExe=""
set PythonExeFlags=

for %%i in (cmd bat exe) do (
for %%j in (python.%%i) do (
call :SetPythonExe "%%~$PATH:j"
)
)
for /f "tokens=2 delims==" %%i in ('assoc .py') do (
for /f "tokens=2 delims==" %%j in ('ftype %%i') do (
for /f "tokens=1" %%k in ("%%j") do (
call :SetPythonExe %%k
)
)
)
%PythonExe% -x %PythonExeFlags% "%~f0" %*
exit /B %ERRORLEVEL%
goto :EOF

:SetPythonExe
if not ["%~1"]==[""] (
if [%PythonExe%]==[""] (
set PythonExe="%~1"
)
)
goto :EOF
"""

@echo off & python -x "%~f0" %* & goto :eof
# ===================================================
# Python script starts here
# ===================================================
Expand Down
6 changes: 0 additions & 6 deletions bin/aws_bash_completer

This file was deleted.

29 changes: 0 additions & 29 deletions bin/aws_legacy_completer

This file was deleted.

60 changes: 0 additions & 60 deletions bin/aws_zsh_completer.sh

This file was deleted.

31 changes: 22 additions & 9 deletions scripts/buildctl/awscli_venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,33 @@ def archive(self):

@property
def bin_dir(self):
return os.path.join(self._venv_dir, 'bin')
if sys.platform == 'win32':
return os.path.join(self._venv_dir, 'Scripts')
else:
return os.path.join(self._venv_dir, 'bin')

@property
def python_exe(self):
return os.path.join(self.bin_dir, 'python')
exe_name = 'python'
if sys.platform == 'win32':
exe_name += '.exe'
return os.path.join(self.bin_dir, exe_name)

def _pip_install(self, args):
subprocess.run(
[self.python_exe, '-m', 'pip', 'install'] + args,
check=True
)
args = [self.python_exe, '-m', 'pip', 'install'] + args
run_kwargs = {'check': True}
if sys.platform == 'win32':
args = ' '.join(args)
run_kwargs['shell'] = True
subprocess.run(args, **run_kwargs)

def _site_packages(self):
# TODO: We should figure out a more programmatic way of finding this...
python_version = f"python{sys.version_info[0]}.{sys.version_info[1]}"
return os.path.join(
self._venv_dir, 'lib', python_version, 'site-packages')
if sys.platform == 'win32':
return os.path.join(
self._venv_dir, 'Lib', 'site-packages')
else:
python_version = (
f"python{sys.version_info[0]}.{sys.version_info[1]}")
return os.path.join(
self._venv_dir, 'lib', python_version, 'site-packages')
4 changes: 4 additions & 0 deletions scripts/buildctl/constants.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import sys


ROOT_DIR = os.path.dirname(
Expand Down Expand Up @@ -29,4 +30,7 @@
AC_INDEX = os.path.join(ROOT_DIR, 'awscli', 'data', 'ac.index')

INSTALL_DIRNAME = 'aws-cli'

CLI_EXECUTABLES = ['aws', 'aws_completer']
if sys.platform == 'win32':
CLI_EXECUTABLES = ['aws.cmd']
23 changes: 18 additions & 5 deletions scripts/buildctl/install.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import shutil
import sys

from constants import CLI_EXECUTABLES

Expand Down Expand Up @@ -32,21 +33,30 @@ def _copy_to_install_dir(build_dir, install_dir, artifact_type):
shutil.rmtree(install_dir)
shutil.copytree(build_lib, install_dir)
if artifact_type == 'system-sandbox':
_update_venv_shebangs(install_dir)
_update_script_header(install_dir)


def _update_venv_shebangs(install_dir):
def _update_script_header(install_dir):
python_exe_name = 'python'
if sys.platform == 'win32':
python_exe_name = 'python.exe'
python_exe_path = _get_install_bin_exe(
install_dir, 'python', 'system-sandbox')
install_dir, python_exe_name, 'system-sandbox')
for exe in CLI_EXECUTABLES:
exe_path = _get_install_bin_exe(install_dir, exe, 'system-sandbox')
with open(exe_path) as f:
lines = f.readlines()
lines[0] = f'#!{python_exe_path}\n'
lines[0] = _get_script_header(python_exe_path)
with open(exe_path, 'w') as f:
f.write(''.join(lines))


def _get_script_header(python_exe_path):
if sys.platform == 'win32':
return f'@echo off & "{python_exe_path}" -x "%~f0" %* & goto :eof\n'
return f'#!{python_exe_path}\n'


def _symlink_executables(install_dir, bin_dir, artifact_type):
if not os.path.exists(bin_dir):
os.makedirs(bin_dir)
Expand All @@ -67,5 +77,8 @@ def _get_build_lib(build_dir, artifact_type):
def _get_install_bin_exe(install_dir, exe, artifact_type):
install_bin_dir = install_dir
if artifact_type == 'system-sandbox':
install_bin_dir = os.path.join(install_dir, 'bin')
bin_dirname = 'bin'
if sys.platform == 'win32':
bin_dirname = 'Scripts'
install_bin_dir = os.path.join(install_dir, bin_dirname)
return os.path.join(install_bin_dir, exe)
4 changes: 0 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ classifiers =
scripts =
bin/aws
bin/aws_completer
# Should probably remove
bin/aws.cmd
bin/aws_legacy_completer
bin/aws_zsh_completer.sh
bin/aws_bash_completer
packages = find:
python_requires = >=3.7
include_package_data = True
Expand Down

0 comments on commit def990c

Please sign in to comment.