diff --git a/Authoring-plugins.md b/Authoring-plugins.md new file mode 100644 index 0000000..70922a5 --- /dev/null +++ b/Authoring-plugins.md @@ -0,0 +1,105 @@ +pyenv plugins provide new commands and/or hook into existing functionality of +pyenv. The following file naming scheme should be followed in a plugin project: + +1. `bin/pyenv-COMMAND` for commands +2. `etc/pyenv.d/HOOK_NAME/*.bash` for hooks + + +## pyenv commands + +An pyenv command is an executable named like `pyenv-COMMAND`. It will get +executed when a user runs `pyenv COMMAND`. Its help will be displayed when a +user runs `pyenv help COMMAND`. It can be written in any interpreted language, +but bash script is recommended for portability. + +**A plugin command can't override any of the pyenv's built-in commands.** + +### Environment + +Each pyenv command runs with the following environment: + +* `$PYENV_ROOT` - where pyenv versions & user data is placed, typically `~/.pyenv` +* `$PYENV_DIR` - the current directory of the caller +* `$PATH` - constructed to contain: + 1. pyenv's `libexec` dir with core commands + 1. `$PYENV_ROOT/plugins/*/bin` for plugin commands + 1. `$PATH` (external value) + +### Calling other commands + +When calling other commands from a command, use the `pyenv-COMMAND` form (with +dash) instead of `pyenv COMMAND` (with space). + +Use pyenv's core low-level commands to inspect the environment instead of doing +it manually. For example, read the result of `pyenv-prefix` instead of +constructing it like `$PYENV_ROOT/versions/$version`. + +A plugin command shouldn't have too much knowledge of pyenv's internals. + +### Help text + +An pyenv command should provide help text in the topmost comment of its source +code. The help format is described in `pyenv help help`. + +Here is a template for an executable called `pyenv-COMMAND`: + +```sh +#!/usr/bin/env bash +# +# Summary: One line, short description of a command +# +# Usage: pyenv COMMAND [--optional-flag] +# +# More thorough help text wrapped at 70 characters that spans +# multiple lines until the end of the comment block. + +set -e +[ -n "$PYENV_DEBUG" ] && set -x + +# Optional: Abort with usage line when called with invalid arguments +# (replace COMMAND with the name of this command) +if [ -z "$1" ]; then + pyenv-help --usage COMMAND >&2 + exit 1 +fi +``` + +### Completions + +A command can optionally provide tab-completions in the shell by outputting +completion values when invoked with the `--complete` flag. + +``` sh +# Provide pyenv completions +if [ "$1" = "--complete" ]; then + echo hello + exit +fi +``` + +Note: **it's important to keep the above comment intact**. This is how pyenv +detects if a command is capable of providing completion values. + + +## pyenv hooks + +Hooks are bash scripts named like `HOOK_NAME/*.bash`, where "HOOK_NAME" is one +of: + +* `exec` +* `rehash` +* `which` + +Hooks are looked for in `$PYENV_HOOK_PATH`, which is composed of: + +1. `$PYENV_HOOK_PATH` (external value) +1. `$PYENV_ROOT/pyenv.d` +1. `/usr/local/etc/pyenv.d` +1. `/etc/pyenv.d` +1. `/usr/lib/pyenv/hooks` +1. `$PYENV_ROOT/plugins/*/etc/pyenv.d` + +Hook scripts are executed at specific points during pyenv operation. They +provide a low-level entry point for integration with pyenv's functionality. To +get a better understanding of the possibilities with hooks, read the source +code of pyenv's hook-enabled commands listed above. diff --git a/Deploying-with-pyenv.md b/Deploying-with-pyenv.md new file mode 100644 index 0000000..3e39779 --- /dev/null +++ b/Deploying-with-pyenv.md @@ -0,0 +1,18 @@ +Setting up pyenv on a production server is exactly the same as in development. +Some considerations for a hypothetical deployment strategy: + +* It is suggested that there is a single user for deployment, e.g. "app" user +* `PYENV_ROOT` is at the default location: `~app/.pyenv` +* Ruby versions are either installed or symlinked to `~app/.pyenv/versions` +* pyenv version 0.2 or greater is recommended. + +Users of Capistrano may find these projects useful: + +* [capistrano-pyenv](https://github.com/yyuu/capistrano-pyenv) + +## Ensure consistent PATH for processes + +Interactive, non-interactive shells, cron jobs, and similar processes for the +"app" user all must ensure that pyenv is present in the PATH: + + export PATH=~/.pyenv/shims:~/.pyenv/bin:"$PATH" diff --git a/Plugins.md b/Plugins.md new file mode 100644 index 0000000..5d48007 --- /dev/null +++ b/Plugins.md @@ -0,0 +1,15 @@ +See [[Authoring plugins]] for instructions on how to write new commands for +pyenv or hook into its functionality. + +A plugin can be installed by dropping it in as a sub-directory of +`$PYENV_ROOT/plugins`, or it can be located elsewhere on the system as long as +`pyenv-*` executables are placed in the `$PATH` and hooks are installed +accordingly somewhere in `$PYENV_HOOK_PATH`. + +## Approved plugins + +This list is edited by pyenv maintainers. + +* [virtualenv](https://github.com/yyuu/pyenv-virtualenv) - the standard way to manage virtualenv with pyenv (formerly as known as [python-virtualenv](https://github.com/yyuu/python-virtualenv)) +* [virtualenvwrapper](https://github.com/yyuu/pyenv-virtualenvwrapper) - allow you to play pyenv with virtualenvwrapper +* [pip-rehash](https://github.com/yyuu/pyenv-pip-rehash) - Automatically run `pyenv rehash` every time you install a new package via pip diff --git a/Unix-shell-initialization.md b/Unix-shell-initialization.md new file mode 100644 index 0000000..a5f9ca9 --- /dev/null +++ b/Unix-shell-initialization.md @@ -0,0 +1,139 @@ +Shell initialization files are ways to persist common shell configuration, such +as: + +* `$PATH` and other environment variables +* shell prompt +* shell tab-completion +* aliases, functions +* key bindings + + +## Shell modes + +Which initialization files get sourced by the shell is dependent on the +combination of modes in which a particular shell process runs. There are two +main, non-exclusive modes: + +* **login** - e.g. when user logs in to a system with non-graphical interface or + via SSH; +* **interactive** - shell that has a prompt and whose standard input and error + are both connected to terminals. + +These modes can be manually activated with the following flags to bash/zsh: + +* `-l`, `--login` +* `-i` + +Here are some common operations and shell modes they result in: + +* log in to a remote system via SSH: + **login + interactive** +* execute a script remotely, e.g. `ssh user@host 'echo $PWD'` or with + [Capistrano][]: **non‑login, non‑interactive** +* start a new shell process, e.g. `bash`: + **non‑login, interactive** +* run a script, `bash myscript.sh`: + **non‑login, non‑interactive** +* run an executable with `#!/usr/bin/env bash` shebang: + **non‑login, non‑interactive** +* open a new graphical terminal window/tab: + * on Mac OS X: **login, interactive** + * on Linux: **non‑login, interactive** + + +## Shell init files + +In order of activation: + +### bash + +1. **login** mode: + 1. `/etc/profile` + 2. `~/.bash_profile`, `~/.bash_login`, `~/.profile` (only first one that exists) +2. interactive **non-login**: + 1. `/etc/bash.bashrc` (some Linux; not on Mac OS X) + 2. `~/.bashrc` +3. **non-interactive**: + 1. source file in `$BASH_ENV` + +### Zsh + +1. `/etc/zshenv` +2. `~/.zshenv` +3. **login** mode: + 1. `/etc/zprofile` + 2. `~/.zprofile` +4. **interactive**: + 1. `/etc/zshrc` + 2. `~/.zshrc` +5. **login** mode: + 1. `/etc/zlogin` + 2. `~/.zlogin` + +### [dash][] + +1. **login** mode: + 1. `/etc/profile` + 2. `~/.profile` +2. **interactive**: + 1. source file in `$ENV` + +### [fish][] + +1. `/config.fish` +2. `/etc/fish/config.fish` +3. `~/.config/fish/config.fish` + +### Practical guide to which files get sourced when + +* Opening a new Terminal window/tab: + * **bash** + * OS X: `.bash_profile` or `.profile` (1st found) + * Linux: `.profile` (Ubuntu, once per desktop login session) + `.bashrc` + * **Zsh** + * OS X: `.zshenv` + `.zprofile` + `.zshrc` + * Linux: `.profile` (Ubuntu, once per desktop login session) + `.zshenv` + `.zshrc` +* Logging into a system via SSH: + * **bash**: `.bash_profile` or `.profile` (1st found) + * **Zsh**: `.zshenv` + `.zprofile` + `.zshrc` +* Executing a command remotely with `ssh` or Capistrano: + * **bash**: `.bashrc` + * **Zsh**: `.zshenv` +* Remote git hook triggered by push over SSH: + * *no init files* get sourced, since hooks are running [within a restricted shell](http://git-scm.com/docs/git-shell) + * PATH will be roughly: `/usr/libexec/git-core:/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin` + +## Misc. things that affect `$PATH` + +* OS X: + * `/etc/paths`, `/etc/paths.d/*` + * [`~/.MacOSX/environment.plist`][plist] - affects **all** graphical programs + * `/etc/launchd.conf` + * TextMate: Preferences -> Advanced -> Shell Variables +* Linux: + * `/etc/environment` + +## Final notes + +This guide was tested with: + +* bash 4.2.37, 4.2.39 +* Zsh 4.3.11, 5.0 + +On these operating systems/apps: + +* Mac OS X 10.8 (Mountain Lion): Terminal.app, iTerm2 +* Ubuntu 12.10: Terminal + +See also: + +* [Environment Variables](https://help.ubuntu.com/community/EnvironmentVariables) +* path_helper(8) +* launchd.conf(5) +* pam_env(8) + + + [Capistrano]: https://github.com/capistrano/capistrano/wiki + [dash]: http://gondor.apana.org.au/~herbert/dash/ + [fish]: http://ridiculousfish.com/shell/user_doc/html/index.html#initialization + [plist]: http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/EnvironmentVars.html#//apple_ref/doc/uid/20002093-113982 \ No newline at end of file diff --git a/Why-pyenv?.md b/Why-pyenv?.md new file mode 100644 index 0000000..2bd0818 --- /dev/null +++ b/Why-pyenv?.md @@ -0,0 +1,18 @@ +### pyenv _does..._ + +* Let you **change the global Python version** on a per-user basis. +* Provide support for **per-project Python versions**. +* Allow you to **override the Python version** with an environment + variable. +* Search commands from **multiple versions of Python at a time**. + This may be helpful to test across Python versions with [tox](http://pypi.python.org/pypi/tox). + +### In contrast with pythonbrew and pythonz, pyenv _does not..._ + +* **Depending on Python itself.** pyenv was made from pure shell scripts. + There is no bootstrap problem of Python. +* **Need to be loaded into your shell.** Instead, pyenv's shim + approach works by adding a directory to your `$PATH`. +* **Manage virtualenv.** Of course, you can create [virtualenv](http://pypi.python.org/pypi/virtualenv) + yourself, or [pyenv-virtualenv](https://github.com/yyuu/pyenv-virtualenv) + to automate the process. diff --git a/python-local-exec.md b/python-local-exec.md new file mode 100644 index 0000000..e1b89aa --- /dev/null +++ b/python-local-exec.md @@ -0,0 +1,25 @@ +The `python-local-exec` command is **deprecated** as of pyenv 0.2.0 and will be removed in the next major release. + +## What is python-local-exec? + +`python-local-exec` was introduced in pyenv 0.1.0 as a drop-in replacement for the standard Python shebang line: + + #!/usr/bin/env python-local-exec + +With `python-local-exec` in place, scripts in an application with a `.python-version` or `.pyenv-version` file use the application-specific Python version, regardless of what directory they're run from. This is useful for running scripts in cron jobs without needing to `cd` into the application first. + +## Why is it deprecated? + +The functionality provided by `python-local-exec` has been rolled into the standard `python` shim provided by pyenv. + +Now, when you run scripts or binstubs in an application with a `.python-version` file, pyenv will automatically use the application's specified Python version, regardless of what directory they're run from. + +To upgrade, first ensure your team and its servers are on pyenv 0.2.0 or later. Adjust your shebangs back to: + + #!/usr/bin/env python + +Then be sure to regenerate your shims with `pyenv rehash`. + +## Can I silence the warning message? + +Set `PYENV_SILENCE_WARNINGS=1` in your environment to silence the `python-local-exec` deprecation warning message.