<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael</title>
    <description>The latest articles on DEV Community by Michael (@micuffaro).</description>
    <link>https://dev.to/micuffaro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F37318%2Fe045301a-e4ca-4a1a-917e-37bcd89aba23.jpg</url>
      <title>DEV Community: Michael</title>
      <link>https://dev.to/micuffaro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/micuffaro"/>
    <language>en</language>
    <item>
      <title>Easy workflow for switching Python virtual environments with ZSH!</title>
      <dc:creator>Michael</dc:creator>
      <pubDate>Tue, 15 Oct 2019 07:14:47 +0000</pubDate>
      <link>https://dev.to/micuffaro/easy-workflow-for-switching-python-virtual-environments-with-zsh-19lc</link>
      <guid>https://dev.to/micuffaro/easy-workflow-for-switching-python-virtual-environments-with-zsh-19lc</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The problem I set out to solve was simply to avoid manually typing pyenv/venv commands&lt;br&gt;
when moving into directories containing different projects, and around my directory tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uq_ZZiAd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gyazo.com/6ad3c719def2828f1f1f2dffc654c90a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uq_ZZiAd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gyazo.com/6ad3c719def2828f1f1f2dffc654c90a.gif" alt="theproblem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are like me, you would be working on different things at different times, and&lt;br&gt;
switching projects around seamlessly becomes a requirement to avoid waste of time&lt;br&gt;
and loss of attention and context.&lt;/p&gt;
&lt;h3&gt;
  
  
  My environment
&lt;/h3&gt;

&lt;p&gt;For the sake of clarity, I am using a Macbook Pro with macOS Mojave, and I have iTerm2&lt;br&gt;
set up with &lt;a href="https://www.zsh.org/"&gt;ZSH&lt;/a&gt; and &lt;a href="https://github.com/robbyrussell/oh-my-zsh"&gt;oh-my-zsh&lt;/a&gt; as my shell.&lt;/p&gt;
&lt;h2&gt;
  
  
  Virtualenvwrapper
&lt;/h2&gt;

&lt;p&gt;Essentially I opted to use &lt;a href="https://virtualenvwrapper.readthedocs.io/en/latest/#"&gt;virtualenvwrapper&lt;/a&gt; instead of pyenv, which I had been using for a few months before.&lt;br&gt;
This nifty library contains an feature called &lt;a href="https://virtualenvwrapper.readthedocs.io/en/latest/command_ref.html#controlling-the-active-environment"&gt;workon&lt;/a&gt;, that allows one, among other things, to activate separate Python environments.&lt;/p&gt;

&lt;p&gt;From the &lt;a href="https://virtualenvwrapper.readthedocs.io/en/latest/install.html"&gt;virtualenvwrapper's docs&lt;/a&gt;:&lt;/p&gt;
&lt;h3&gt;
  
  
  Install with Pip
&lt;/h3&gt;

&lt;p&gt;virtualenvwrapper should be installed into the same global site-packages area where virtualenv is installed. You may need administrative privileges to do that. The easiest way to install it is using pip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install virtualenvwrapper
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Shell Startup File
&lt;/h3&gt;

&lt;p&gt;Add three lines to your shell startup file (.zshrc, .bashrc, .profile, etc.) to set the location where the virtual environments should live, the location of your development project directories, and the location of the script installed with this package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Manage your virtualenvs
&lt;/h3&gt;

&lt;p&gt;Also from the docs, here is a quick list of commands to get started with workon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A list of environments, empty, is printed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkvirtualenv temp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A new environment, temp is created and activated.&lt;br&gt;
It copies the current version of python to make it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This time, the temp environment is included.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workon temp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Activates that environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Deactivates that same environment&lt;/p&gt;

&lt;p&gt;Now that we have an easy way to separate and use our virtual environments, let's talk about Jump!&lt;/p&gt;

&lt;h2&gt;
  
  
  Jump
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/gsamokovarov/jump"&gt;Jump&lt;/a&gt; is a shell integrations which uses fuzzy search to helps you move around your directory structure more easily.&lt;br&gt;
It is a Go application that essentially records your keystrokes and your most used directories&lt;br&gt;
into its own database.&lt;br&gt;
Jump allows you to do stuff like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nqe7_L8z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/gsamokovarov/jump/master/assets/demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nqe7_L8z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/gsamokovarov/jump/master/assets/demo.gif" alt="gyazothing"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing Jump:
&lt;/h3&gt;

&lt;p&gt;On Mac:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install jump
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After which, you need to add the following line in your zshrc&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval "$(jump shell)"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you first use Jump it won't do much, as its database is empty; it will learn as you use it.&lt;/p&gt;

&lt;p&gt;An alternative to jump, in case you don't want to install Go stuff on your machine (why?), is &lt;a href="https://github.com/rupa/z"&gt;z&lt;/a&gt;,&lt;br&gt;
which is entirely written in shell script.&lt;/p&gt;
&lt;h2&gt;
  
  
  Moving around seemlessly between projects
&lt;/h2&gt;

&lt;p&gt;Now you can jump anywhere in your directory tree, and switch virtual environments as your heart desires.&lt;br&gt;
But how do we make the experience more seamless?&lt;/p&gt;

&lt;p&gt;We can hack our bashrc / zshrc file by adding a snippet of bash, which will run every time we &lt;code&gt;cd&lt;/code&gt; into a new directory, checking the presence of a &lt;code&gt;.venv&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Said &lt;code&gt;.venv&lt;/code&gt; file will simply contain the name of the virtual environment we wish to activate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "fooenv" &amp;gt;&amp;gt; .venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We then need to modify our zshrc and add this (admittedly hacky) snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Workon
# Support for bash
PROMPT_COMMAND='prompt'

# Mirrored support for zsh.
precmd() { eval "$PROMPT_COMMAND" }

function prompt()
{
    # Check for directory change
    if [ "$PWD" != "$MYOLDPWD" ]; then
        MYOLDPWD="$PWD"
        # Run workon if .venv exists
        if [[ -e .venv ]]; then
            workon `cat .venv`
        # Run deactivate and redirect any errors to null
        elif [[ ! -e .venv ]]; then
                deactivate 2&amp;gt;/dev/null
        fi
    fi
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Alternatively to the above ugly bash hack, we can simply use the &lt;a href="https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/virtualenvwrapper"&gt;ZSH Plugin for virtualenvwrapper&lt;/a&gt;, which does pretty much the same thing, but better. :)&lt;/p&gt;

&lt;p&gt;Also with the plugin, Python environments with the same name as the repository will be automatically activated on cd, unless we use the &lt;code&gt;.venv&lt;/code&gt; method as described.&lt;/p&gt;

&lt;p&gt;After we source our rc file (or close and reopen our terminal),&lt;br&gt;
We can jump around like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AguzMldJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gyazo.com/9ffecfe8a17a51b022c1c53679dc0bb5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AguzMldJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gyazo.com/9ffecfe8a17a51b022c1c53679dc0bb5.gif" alt="gyazo thing jumping around"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Original post on my blog, &lt;a href="http://sk1u.com/blog/2019/09/22/zsh-jump-workon"&gt;sk1u.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devpythonzsh</category>
    </item>
  </channel>
</rss>
