Skip to content

Refactoring aliases to be more generic, add function support #65

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

Merged
merged 7 commits into from
Jul 29, 2024
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
26 changes: 25 additions & 1 deletion src/artifacts-helper/NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
This installs [Azure Artifacts Credential Provider](https://github.com/microsoft/artifacts-credprovider)
and optionally configures an alias for `dotnet`, `nuget`, `npm`, `yarn`, and `rush` that dynamically sets an authentication token
and optionally configures functions which shadow `dotnet`, `nuget`, `npm`, `yarn`, and `rush` which dynamically sets an authentication token
for pulling artifacts from a feed before running the command.

For `npm`, `yarn`, and `rush` this requires that your `~/.npmrc` file is configured to use the ${ARTIFACTS_ACCESSTOKEN}
Expand Down Expand Up @@ -41,3 +41,27 @@ to download the package.
## OS Support

This feature is tested to work on Debian/Ubuntu and Mariner CBL 2.0

## Changing where functions are configured

By default, the functions are defined in `/etc/bash.bashrc` and `/etc/zsh/zshrc` if the container user is `root`, otherwise `~/.bashrc` and `~/.zshrc`.
This default configuration ensures that the functions are always available for any interactive shells.

In some cases it can be useful to have the functions written to a non-default location. For example:
- the configuration file of a shell other than `bash` and `zsh`
- a custom file which is not a shell configuration script (so that it can be `source`d in non-interactive shells and scripts)

To do this, set the `targetFiles` option to the path script path where the functions should be written. Note that the default paths WILL NOT be used
if the `targetFiles` option is provided, so you may want to include them in the overridden value, or add `source` the custom script in those configurations:

```bash
# .devcontainer/devcontainer.json
{
// ...
"targetFiles": "/custom/path/to/auth-helper.sh"
}

# ~/.bashrc

source /custom/path/to/auth-helper.sh
```
3 changes: 2 additions & 1 deletion src/artifacts-helper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Configures Codespace to authenticate with Azure Artifact feeds
| npxAlias | Create alias for npx | boolean | true |
| rushAlias | Create alias for rush | boolean | true |
| python | Install Python keyring helper for pip | boolean | false |
| targetFiles | Comma-separated list of files to write aliases to | string | DEFAULT (`/etc/bash.bashrc,/etc/zsh/zshrc` for `root`, otherwise `~/.bashrc,~/.zshrc`) |
Copy link
Preview

Copilot AI Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description for targetFiles should mention that it writes functions instead of aliases.

Suggested change
| targetFiles | Comma-separated list of files to write aliases to | string | DEFAULT (`/etc/bash.bashrc,/etc/zsh/zshrc` for `root`, otherwise `~/.bashrc,~/.zshrc`) |
| targetFiles | Comma-separated list of files to write functions to | string | DEFAULT (`/etc/bash.bashrc,/etc/zsh/zshrc` for `root`, otherwise `~/.bashrc,~/.zshrc`) |

Copilot uses AI. Check for mistakes.


## Customizations

Expand All @@ -32,7 +33,7 @@ Configures Codespace to authenticate with Azure Artifact feeds
- `ms-codespaces-tools.ado-codespaces-auth`

This installs [Azure Artifacts Credential Provider](https://github.com/microsoft/artifacts-credprovider)
and optionally configures an alias for `dotnet`, `nuget`, `npm`, `yarn`, and `rush` that dynamically sets an authentication token
and optionally configures functions which shadow `dotnet`, `nuget`, `npm`, `yarn`, and `rush` which dynamically sets an authentication token
for pulling artifacts from a feed before running the command.

For `npm`, `yarn`, and `rush` this requires that your `~/.npmrc` file is configured to use the ${ARTIFACTS_ACCESSTOKEN}
Expand Down
11 changes: 8 additions & 3 deletions src/artifacts-helper/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Azure Artifacts Credential Helper",
"id": "artifacts-helper",
"version": "1.0.9",
"version": "2.0.0",
"description": "Configures Codespace to authenticate with Azure Artifact feeds",
"options": {
"nugetURIPrefixes": {
Expand Down Expand Up @@ -44,11 +44,16 @@
"default": true,
"description": "Create alias for rush"
},
"targetFiles": {
"type": "string",
"default": "DEFAULT",
"description": "Comma separated list of files to write to. Default is '/etc/bash.bashrc,/etc/zsh/zshrc' for root and '~/.bashrc,~/.zshrc' for non-root"
},
"python": {
"type": "boolean",
"default": false,
"description": "Install Python keyring helper for pip"
}
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils",
Expand All @@ -61,4 +66,4 @@
]
}
}
}
}
107 changes: 46 additions & 61 deletions src/artifacts-helper/install.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash

set -e

Expand All @@ -11,6 +11,29 @@ ALIAS_YARN="${YARNALIAS:-"true"}"
ALIAS_NPX="${NPXALIAS:-"true"}"
ALIAS_RUSH="${RUSHALIAS:-"true"}"
INSTALL_PIP_HELPER="${PYTHON:-"false"}"
COMMA_SEP_TARGET_FILES="${TARGETFILES:-"DEFAULT"}"

ALIASES_ARR=()

if [ "${ALIAS_DOTNET}" = "true" ]; then
ALIASES_ARR+=('dotnet')
fi
if [ "${ALIAS_NUGET}" = "true" ]; then
ALIASES_ARR+=('nuget')
fi
if [ "${ALIAS_NPM}" = "true" ]; then
ALIASES_ARR+=('npm')
fi
if [ "${ALIAS_YARN}" = "true" ]; then
ALIASES_ARR+=('yarn')
fi
if [ "${ALIAS_NPX}" = "true" ]; then
ALIASES_ARR+=('npx')
fi
if [ "${ALIAS_RUSH}" = "true" ]; then
ALIASES_ARR+=('rush')
ALIASES_ARR+=('rush-pnpm')
fi

# Source /etc/os-release to get OS info
. /etc/os-release
Expand All @@ -20,8 +43,7 @@ if [ "$(id -u)" -ne 0 ]; then
exit 1
fi

apt_get_update()
{
apt_get_update() {
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
Expand Down Expand Up @@ -72,80 +94,43 @@ chmod +rx /usr/local/bin/run-rush.sh
cp ./scripts/run-rush-pnpm.sh /usr/local/bin/run-rush-pnpm.sh
chmod +rx /usr/local/bin/run-rush-pnpm.sh


if [ "${INSTALL_PIP_HELPER}" = "true" ]; then
USER="${_REMOTE_USER}" /tmp/install-python-keyring.sh
rm /tmp/install-python-keyring.sh
fi

INSTALL_WITH_SUDO="false"
if command -v sudo >/dev/null 2>&1; then
if [ "root" != "$_REMOTE_USER" ]; then
if [ "${ALIAS_DOTNET}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias dotnet=/usr/local/bin/run-dotnet.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias dotnet=/usr/local/bin/run-dotnet.sh' >> ~/.zshrc"
fi
if [ "${ALIAS_NUGET}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias nuget=/usr/local/bin/run-nuget.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias nuget=/usr/local/bin/run-nuget.sh' >> ~/.zshrc"
fi
if [ "${ALIAS_NPM}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npm=/usr/local/bin/run-npm.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npm=/usr/local/bin/run-npm.sh' >> ~/.zshrc"
fi
if [ "${ALIAS_YARN}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias yarn=/usr/local/bin/run-yarn.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias yarn=/usr/local/bin/run-yarn.sh' >> ~/.zshrc"
fi
if [ "${ALIAS_NPX}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npx=/usr/local/bin/run-npx.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npx=/usr/local/bin/run-npx.sh' >> ~/.zshrc"
fi
if [ "${ALIAS_RUSH}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush=/usr/local/bin/run-rush.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush=/usr/local/bin/run-rush.sh' >> ~/.zshrc"

sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush-pnpm=/usr/local/bin/run-rush-pnpm.sh' >> ~/.bashrc"
sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush-pnpm=/usr/local/bin/run-rush-pnpm.sh' >> ~/.zshrc"
fi
sudo -u ${_REMOTE_USER} bash -c "/tmp/install-provider.sh ${USENET6}"
rm /tmp/install-provider.sh
exit 0
INSTALL_WITH_SUDO="true"
fi
fi

if [ "${ALIAS_DOTNET}" = "true" ]; then
echo "alias dotnet='/usr/local/bin/run-dotnet.sh'" >> /etc/bash.bashrc || true
echo "alias dotnet='/usr/local/bin/run-dotnet.sh'" >> /etc/zsh/zshrc || true
fi

if [ "${ALIAS_NUGET}" = "true" ]; then
echo "alias nuget='/usr/local/bin/run-nuget.sh'" >> /etc/bash.bashrc || true
echo "alias nuget='/usr/local/bin/run-nuget.sh'" >> /etc/zsh/zshrc || true
fi

if [ "${ALIAS_NPM}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npm=/usr/local/bin/run-npm.sh' >> /etc/bash.bashrc || true
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npm=/usr/local/bin/run-npm.sh' >> /etc/zsh/zshrc || true
if [ "${COMMA_SEP_TARGET_FILES}" = "DEFAULT" ]; then
if [ "${INSTALL_WITH_SUDO}" = "true" ]; then
COMMA_SEP_TARGET_FILES="~/.bashrc,~/.zshrc"
else
COMMA_SEP_TARGET_FILES="/etc/bash.bashrc,/etc/zsh/zshrc"
fi
fi

if [ "${ALIAS_YARN}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias yarn=/usr/local/bin/run-yarn.sh' >> /etc/bash.bashrc || true
sudo -u ${_REMOTE_USER} bash -c "echo 'alias yarn=/usr/local/bin/run-yarn.sh' >> /etc/zsh/zshrc || true
fi
IFS=',' read -r -a TARGET_FILES_ARR <<< "$COMMA_SEP_TARGET_FILES"

if [ "${ALIAS_NPX}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npx=/usr/local/bin/run-npx.sh' >> /etc/bash.bashrc || true
sudo -u ${_REMOTE_USER} bash -c "echo 'alias npx=/usr/local/bin/run-npx.sh' >> /etc/zsh/zshrc || true
fi
for ALIAS in "${ALIASES_ARR[@]}"; do
for TARGET_FILE in "${TARGET_FILES_ARR[@]}"; do
CMD="$ALIAS() { /usr/local/bin/run-$ALIAS.sh; }"

if [ "${ALIAS_RUSH}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush=/usr/local/bin/run-rush.sh' >> /etc/bash.bashrc || true
sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush=/usr/local/bin/run-rush.sh' >> /etc/zsh/zshrc || true
if [ "${INSTALL_WITH_SUDO}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "echo '$CMD' >> $TARGET_FILE"
else
echo $CMD >> $TARGET_FILE || true
fi
done
done

sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush-pnpm=/usr/local/bin/run-rush-pnpm.sh' >> /etc/bash.bashrc || true
sudo -u ${_REMOTE_USER} bash -c "echo 'alias rush-pnpm=/usr/local/bin/run-rush-pnpm.sh' >> /etc/zsh/zshrc || true
if [ "${INSTALL_WITH_SUDO}" = "true" ]; then
sudo -u ${_REMOTE_USER} bash -c "/tmp/install-provider.sh ${USENET6}"
fi

rm /tmp/install-provider.sh

exit 0