Compare commits

..

No commits in common. "master" and "v0.4.6" have entirely different histories.

44 changed files with 259 additions and 936 deletions

View file

@ -1,71 +1,5 @@
# Changes
2018-09-15 (version 0.7.0)
* New generic `stdout` and `env` segments
2018-06-20 (version 0.6.0)
* Support for custom themes
* New option for the `time` segment to specify format of the displayed time
([@dundalek](https://github.com/b-ryan/powerline-shell/pull/383))
2018-04-22 (version 0.5.4)
* Reverted fix for
([#249](https://github.com/b-ryan/powerline-shell/issues/249)) because it
caused issues on Mac.
2018-04-21 (version 0.5.3)
* New theme! (gruvbox)
([@monicaycli](https://github.com/b-ryan/powerline-shell/pull/388))
2018-04-21 (version 0.5.2)
* Fix hostname colorize bug
([@comagnaw](https://github.com/b-ryan/powerline-shell/issues/353))
* Fix issue with prompt bleeding behavior
([@bytebeast](https://github.com/b-ryan/powerline-shell/issues/249))
* Better error message when config file cannot be decoded (Closes
[#371](https://github.com/b-ryan/powerline-shell/issues/371))
2018-04-13 (version 0.5.1)
* Fix Python 3 compatibility of `git_stash` segment
2018-04-10 (version 0.5.0)
* Patch environment for VCS subprocesses rather than generating a new one
* Fix `cwd` segment so it respects `max_depth` configuration
* Fix Ruby segment for Python 3 compatibility
([@Blue-Dog-Archolite](https://github.com/b-ryan/powerline-shell/pull/366))
* Configuration is now expected to be at
`~/.config/powerline-shell/config.json` ([@emansije and
@kc9jud](https://github.com/b-ryan/powerline-shell/pull/334))
* New `git_stash` segment
([@apinkney97](https://github.com/b-ryan/powerline-shell/pull/379))
2018-02-19 (version 0.4.9)
* Fix root user segment
([@TiGR](https://github.com/b-ryan/powerline-shell/pull/362))
* Fixes and enhancements for SVN segment
([@emansije](https://github.com/b-ryan/powerline-shell/pull/349))
2018-01-29 (version 0.4.8)
* Bring back the ability to create custom themes
([@b-ryan](https://github.com/b-ryan/powerline-shell/pull/352))
* Add the ability to customize the `time` segment in themes
([@gaurav-nelson](https://github.com/b-ryan/powerline-shell/pull/338))
2018-01-15 (version 0.4.7)
* VCS segments (git, hg, etc.) can now show a symbol identifying what VPS the
current directory uses
([@emansije](https://github.com/b-ryan/powerline-shell/pull/298))
2018-01-11 (version 0.4.6)
* Fix bug in SVN segment

View file

@ -1,6 +1,6 @@
FROM python:2-alpine
FROM aa8y/core:python2
MAINTAINER github.com/b-ryan/powerline-shell
MAINTAINER github.com/banga/powerline-shell
USER root
RUN apk add --no-cache --update \
@ -9,23 +9,25 @@ RUN apk add --no-cache --update \
git \
mercurial \
php5 \
subversion \
&& \
subversion && \
rm -rf /var/cache/apk/*
RUN mkdir /code
WORKDIR /code
# Cache the dev requirements. Directory is set in the base image.
WORKDIR $APP_DIR
COPY requirements-dev.txt .
RUN pip install -r requirements-dev.txt && \
rm requirements-dev.txt
rm -rf requirements-dev.txt
RUN bzr whoami "root <root@example.com>" && \
git config --global user.email "root@example.com" && \
git config --global user.name "root"
# 'USER' is set in the base image. It points to a non-root user called 'docker'.
USER $USER
RUN bzr whoami "$USERNAME <$USER@example.com>" && \
git config --global user.email "$USER@example.com" && \
git config --global user.name "$USERNAME"
# COPY . ./
# RUN ./setup.py install
COPY . ./
USER root
RUN ./setup.py install && \
chown -R $USER:$USER .
ENV USER root
CMD ["nosetests"]
USER $USER
ENTRYPOINT ["/bin/bash"]

182
README.md
View file

@ -1,8 +1,9 @@
# A Powerline style prompt for your shell
A beautiful and useful prompt generator for Bash, ZSH, Fish, and tcsh:
A [Powerline](https://github.com/Lokaltog/vim-powerline) like prompt for Bash,
ZSH, Fish, and tcsh:
![MacVim+Solarized+Powerline+CtrlP](https://raw.github.com/b-ryan/powerline-shell/master/bash-powerline-screenshot.png)
![MacVim+Solarized+Powerline+CtrlP](https://raw.github.com/banga/powerline-shell/master/bash-powerline-screenshot.png)
- Shows some important details about the git/svn/hg/fossil branch (see below)
- Changes color if the last command exited with a failure code
@ -10,10 +11,6 @@ A beautiful and useful prompt generator for Bash, ZSH, Fish, and tcsh:
- Shows the current Python [virtualenv](http://www.virtualenv.org/) environment
- It's easy to customize and extend. See below for details.
The generated prompts are designed to resemble
[powerline](https://github.com/powerline/powerline), but otherwise this project
has no relation to powerline.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
@ -23,11 +20,9 @@ has no relation to powerline.
- [Bash](#bash)
- [ZSH](#zsh)
- [Fish](#fish)
- [tcsh](#tcsh)
- [Customization](#customization)
- [Config File](#config-file)
- [Adding, Removing and Re-arranging segments](#adding-removing-and-re-arranging-segments)
- [Generic Segments](#generic-segments)
- [Segment Separator](#segment-separator)
- [Themes](#themes)
- [Segment Configuration](#segment-configuration)
@ -47,26 +42,24 @@ quick look into the state of your repo:
of commits is shown along with `⇡` or `⇣` indicating whether a git push
or pull is pending.
If files are modified or in conflict, the situation is summarized with the
following symbols:
In addition, git has a few extra symbols:
- `✎` -- a file has been modified (but not staged for commit, in git)
- `✔` -- a file is staged for commit (git) or added for tracking
- `✎` -- a file has been modified, but not staged for commit
- `✔` -- a file is staged for commit
- `✼` -- a file has conflicts
- `?` -- a file is untracked
FIXME
- A `+` appears when untracked files are present (except for git, which uses
`?` instead)
Each of these will have a number next to it if more than one file matches.
The segment can start with a symbol representing the version control system in
use. To show that symbol, the configuration file must have a variable `vcs`
with an option `show_symbol` set to `true` (see
[Segment Configuration](#segment-configuration)).
## Setup
This script uses ANSI color codes to display colors in a terminal. These are
notoriously non-portable, so may not work for you out of the box, but try
setting your $TERM to `xterm-256color`.
setting your $TERM to `xterm-256color`, because that works for me.
- Patch the font you use for your terminal: see
[powerline-fonts](https://github.com/Lokaltog/powerline-fonts)
@ -91,7 +84,7 @@ install for just your user, if you'd like. But you may need to fiddle with your
- Or, install from the git repository:
```
git clone https://github.com/b-ryan/powerline-shell
git clone https://github.com/banga/powerline-shell
cd powerline-shell
python setup.py install
```
@ -100,23 +93,18 @@ python setup.py install
### Bash
Add the following to your `.bashrc` file:
Add the following to your `.bashrc` (or `.profile` on Mac):
```
function _update_ps1() {
PS1=$(powerline-shell $?)
PS1="$(powerline-shell $?)"
}
if [[ $TERM != linux && ! $PROMPT_COMMAND =~ _update_ps1 ]]; then
if [ "$TERM" != "linux" ]; then
PROMPT_COMMAND="_update_ps1; $PROMPT_COMMAND"
fi
```
**Note:** On macOS, you must add this to one of `.bash_profile`, `.bash_login`,
or `.profile`. macOS will execute the files in the aforementioned order and
will stop execution at the first file it finds. For more information on the
order of precedence, see the section **INVOCATION** in `man bash`.
### ZSH
Add the following to your `.zshrc`:
@ -135,7 +123,7 @@ function install_powerline_precmd() {
precmd_functions+=(powerline_precmd)
}
if [ "$TERM" != "linux" -a -x "$(command -v powerline-shell)" ]; then
if [ "$TERM" != "linux" ]; then
install_powerline_precmd
fi
```
@ -163,74 +151,53 @@ alias precmd 'set prompt="`powerline-shell --shell tcsh $?`"'
### Config File
Powerline-shell is customizable through the use of a config file. This file is
expected to be located at `~/.config/powerline-shell/config.json`. You can
generate the default config at this location using:
expected to be located at `~/.powerline-shell.json`. You can generate the
default config at this location using:
```
mkdir -p ~/.config/powerline-shell && \
powerline-shell --generate-config > ~/.config/powerline-shell/config.json
powerline-shell --generate-config > ~/.powerline-shell.json
```
(As an example, my config file is located here:
[here](https://github.com/b-ryan/dotfiles/blob/master/home/config/powerline-shell/config.json))
(You can see an example config file
[here](https://github.com/b-ryan/dotfiles/blob/master/home/powerline-shell.json))
### Adding, Removing and Re-arranging segments
Once you have generated your config file, you can now start adding or removing
"segments" - the building blocks of your shell. The list of segments available
can be seen
[here](https://github.com/b-ryan/powerline-shell/tree/master/powerline_shell/segments).
are:
You can also create custom segments. Start by copying an existing segment like
[this](https://github.com/b-ryan/powerline-shell/blob/master/powerline_shell/segments/aws_profile.py).
Make sure to change any relative imports to absolute imports. Ie. change things
like:
```python
from ..utils import BasicSegment
```
to
```python
from powerline_shell.utils import BasicSegment
```
Then change the `add_to_powerline` function to do what you want. You can then
use this segment in your configuration by putting the path to your segment in
the segments section, like:
```json
"segments": [
"~/path/to/segment.py"
]
```
### Generic Segments
There are two special segments available. `stdout` accepts an arbitrary command
and the output of the command will be put into your prompt. `env` takes an
environment variable and the value of the variable will be set in your prompt.
For example, your config could look like this:
```
{
"segments": [
"cwd",
"git",
{
"type": "stdout",
"command": ["echo", "hi"],
"fg_color": 22,
"bg_color": 161
},
{
"type": "env",
"var": "DOCKER_MACHINE_NAME"
},
]
}
```
- `aws_profile` - Show which AWS profile is in use. See the
[AWS](http://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html)
documentation.
- `battery` - See percentage of battery charged and an icon when the battery is
charging.
- `bzr` - Details about the current Bazaar repo.
- `cwd` - Shows your current working directory. See [Segment
Configuration](#segment-configuration) for some options.
- `exit_code` - When the previous command ends in a non-zero status, shows the
value of the exit status in red.
- `fossil` - Details about the current Fossil repo.
- `git` - Details about the current Git repo.
- `hg` - Details about the current Mercurial repo.
- `hostname` - Current machine's hostname.
- `jobs` - Number of background jobs currently running.
- `newline` - Inserts a newline into the prompt.
- `node_version` - `node --version`
- `npm_version` - `npm --version`
- `php_version` - Version of php on the machine.
- `rbenv` - `rbenv local`
- `read_only` - Shows a lock icon if the current directory is read-only.
- `root` - Shows a `#` if logged in as root, `$` otherwise.
- `ruby_version` - `ruby --version`
- `set_term_title` - If able, sets the title of your terminal to include some
useful info.
- `ssh` - If logged into over SSH, shows a network icon.
- `svn` - Details about the current SVN repo.
- `time` - Shows the current time.
- `uptime` - Uptime of the current machine.
- `username` - Name of the logged-in user.
- `virtual_env` - Shows the name of the current virtual env or conda env.
### Segment Separator
@ -249,20 +216,9 @@ file. The available modes are:
The `powerline_shell/themes` directory stores themes for your prompt, which are
basically color values used by segments. The `default.py` defines a default
theme which can be used standalone, and every other theme falls back to it if
they miss colors for any segments.
If you want to create a custom theme, start by copying one of the existing
themes, like the
[basic](https://github.com/b-ryan/powerline-shell/blob/master/powerline_shell/themes/basic.py).
and update your `~/.config/powerline-shell/config.json`, setting the `"theme"`
to the path of the file. For example your configuration might have:
```
"theme": "~/mythemes/my-great-theme.py"
```
You can then modify the color codes to your liking. Theme colors are specified
using [Xterm-256 color codes](https://jonasjacek.github.io/colors/).
they miss colors for any segments. Create new themes by copying any other
existing theme and changing the values. To use a theme, set the `theme`
variable in `~/.powerline-shell.json` to the name of your theme.
A script for testing color combinations is provided at `colortest.py`. Note
that the colors you see may vary depending on your terminal. When designing a
@ -273,7 +229,7 @@ settings.
Some segments support additional configuration. The options for the segment are
nested under the name of the segment itself. For example, all of the options
for the `cwd` segment are set in `~/.config/powerline-shell/config.json` like:
for the `cwd` segment are set in `~/.powerline-shell.py` like:
```
{
@ -281,17 +237,13 @@ for the `cwd` segment are set in `~/.config/powerline-shell/config.json` like:
"cwd": {
options go here
}
"theme": "theme-name",
"vcs": {
options go here
}
}
```
The options for the `cwd` segment are:
- `mode`: If `plain`, then simple text will be used to show the cwd. If
`dironly`, only the current directory will be shown. Otherwise expands the
- `mode`: If "plain" then simple text will be used to show the cwd. If
"dironly," only the current directory will be shown. Otherwise expands the
cwd into individual directories.
- `max_depth`: Maximum number of directories to show in path.
- `max_dir_size`: Maximum number of characters displayed for each directory in
@ -304,21 +256,11 @@ The `hostname` segment provides one option:
- `colorize`: If true, the hostname will be colorized based on a hash of
itself.
The `vcs` segment provides one option:
- `show_symbol`: If `true`, the version control system segment will start with
a symbol representing the specific version control system in use in the
current directory.
The options for the `battery` segment are:
- `always_show_percentage`: If true, show percentage when fully charged on AC.
- `low_threshold`: Threshold percentage for low-battery indicator color.
The options for the `time` segment are:
- `format`: Format string as used by strftime function, e.g. `%H:%M`.
### Contributing new types of segments
The `powerline_shell/segments` directory contains python scripts which are
@ -342,6 +284,6 @@ requirements in `requirements-dev.txt`.
## Troubleshooting
See the [FAQ](https://github.com/b-ryan/powerline-shell/wiki/FAQ). If you
See the [FAQ](https://github.com/banga/powerline-shell/wiki/FAQ). If you
continue to have issues, please open an
[issue](https://github.com/b-ryan/powerline-shell/issues/new).
[issue](https://github.com/banga/powerline-shell/issues/new).

View file

@ -6,7 +6,7 @@ import os
import sys
import importlib
import json
from .utils import warn, py3, import_file
from .utils import warn, py3
import re
@ -114,9 +114,7 @@ class Powerline(object):
def bgcolor(self, code):
return self.color('48', code)
def append(self, content, fg, bg, separator=None, separator_fg=None, sanitize=True):
if self.args.shell == "bash" and sanitize:
content = re.sub(r"([`$])", r"\\\1", content)
def append(self, content, fg, bg, separator=None, separator_fg=None):
self.segments.append((content, fg, bg,
separator if separator is not None else self.separator,
separator_fg if separator_fg is not None else bg))
@ -131,12 +129,16 @@ class Powerline(object):
def draw_segment(self, idx):
segment = self.segments[idx]
if self.args.shell == "bash":
sanitized = re.sub(r"([`$])", r"\\\1", segment[0])
else:
sanitized = segment[0]
next_segment = self.segments[idx + 1] if idx < len(self.segments)-1 else None
return ''.join((
self.fgcolor(segment[1]),
self.bgcolor(segment[2]),
segment[0],
sanitized,
self.bgcolor(next_segment[2]) if next_segment else self.reset,
self.fgcolor(segment[4]),
segment[3]))
@ -146,7 +148,6 @@ def find_config():
for location in [
"powerline-shell.json",
"~/.powerline-shell.json",
os.path.join(os.environ.get("XDG_CONFIG_HOME", "~/.config"), "powerline-shell", "config.json"),
]:
full = os.path.expanduser(location)
if os.path.exists(full):
@ -167,28 +168,6 @@ DEFAULT_CONFIG = {
}
class ModuleNotFoundException(Exception):
pass
class CustomImporter(object):
def __init__(self):
self.file_import_count = 0
def import_(self, module_prefix, module_or_file, description):
try:
mod = importlib.import_module(module_prefix + module_or_file)
except ImportError:
try:
module_name = "_custom_mod_{0}".format(self.file_import_count)
mod = import_file(module_name, os.path.expanduser(module_or_file))
self.file_import_count += 1
except (ImportError, IOError):
msg = "{0} {1} cannot be found".format(description, module_or_file)
raise ModuleNotFoundException( msg)
return mod
def main():
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('--generate-config', action='store_true',
@ -207,33 +186,19 @@ def main():
config_path = find_config()
if config_path:
with open(config_path) as f:
try:
config = json.loads(f.read())
except Exception as e:
warn("Config file ({0}) could not be decoded! Error: {1}"
.format(config_path, e))
config = DEFAULT_CONFIG
config = json.loads(f.read())
else:
config = DEFAULT_CONFIG
custom_importer = CustomImporter()
theme_mod = custom_importer.import_(
"powerline_shell.themes.",
config.get("theme", "default"),
"Theme")
theme = getattr(theme_mod, "Color")
theme_name = config.get("theme", "default")
mod = importlib.import_module("powerline_shell.themes." + theme_name)
theme = getattr(mod, "Color")
powerline = Powerline(args, config, theme)
segments = []
for seg_conf in config["segments"]:
if not isinstance(seg_conf, dict):
seg_conf = {"type": seg_conf}
seg_name = seg_conf["type"]
seg_mod = custom_importer.import_(
"powerline_shell.segments.",
seg_name,
"Segment")
segment = getattr(seg_mod, "Segment")(powerline, seg_conf)
for seg_name in config["segments"]:
mod = importlib.import_module("powerline_shell.segments." + seg_name)
segment = getattr(mod, "Segment")(powerline)
segment.start()
segments.append(segment)
for segment in segments:

View file

@ -10,7 +10,6 @@ from .utils import py3
def getOppositeColor(r,g,b):
r, g, b = [x/255.0 for x in [r, g, b]] # convert to float before getting hls value
hls = rgb_to_hls(r,g,b)
opp = list(hls[:])
opp[0] = (opp[0]+0.2)%1 # shift hue (a.k.a. color)

View file

@ -1,11 +1,23 @@
import os
import subprocess
from ..utils import RepoStats, ThreadedSegment, get_subprocess_env
from ..utils import RepoStats, ThreadedSegment
def get_PATH():
"""Normally gets the PATH from the OS. This function exists to enable
easily mocking the PATH in tests.
"""
return os.getenv("PATH")
def bzr_subprocess_env():
return {"PATH": get_PATH()}
def _get_bzr_branch():
p = subprocess.Popen(['bzr', 'nick'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=get_subprocess_env())
env=bzr_subprocess_env())
branch = p.communicate()[0].decode("utf-8").rstrip('\n')
return branch
@ -35,7 +47,7 @@ def build_stats():
try:
p = subprocess.Popen(['bzr', 'status'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=get_subprocess_env())
env=bzr_subprocess_env())
except OSError:
# Popen will throw an OSError if bzr is not found
return (None, None)
@ -61,9 +73,6 @@ class Segment(ThreadedSegment):
if self.stats.dirty:
bg = self.powerline.theme.REPO_DIRTY_BG
fg = self.powerline.theme.REPO_DIRTY_FG
if self.powerline.segment_conf("vcs", "show_symbol"):
symbol = RepoStats().symbols["bzr"] + " "
else:
symbol = ""
self.powerline.append(" " + symbol + self.branch + " ", fg, bg)
self.powerline.append(" " + self.branch + " ", fg, bg)
self.stats.add_to_powerline(self.powerline)

View file

@ -58,6 +58,10 @@ def add_cwd_segment(powerline):
cwd = cwd.decode("utf-8")
cwd = replace_home_dir(cwd)
if powerline.segment_conf("cwd", "mode") == 'plain':
powerline.append(' %s ' % (cwd,), powerline.theme.CWD_FG, powerline.theme.PATH_BG)
return
names = split_path_into_names(cwd)
full_cwd = powerline.segment_conf("cwd", "full_cwd", False)
@ -80,12 +84,6 @@ def add_cwd_segment(powerline):
# displayed, so chop everything else off
names = names[-1:]
elif powerline.segment_conf("cwd", "mode") == "plain":
joined = os.path.sep.join(names)
powerline.append(" %s " % (joined,), powerline.theme.CWD_FG,
powerline.theme.PATH_BG)
return
for i, name in enumerate(names):
is_last_dir = (i == len(names) - 1)
fg, bg = get_fg_bg(powerline, name, is_last_dir)

View file

@ -1,10 +0,0 @@
import os
from ..utils import BasicSegment
class Segment(BasicSegment):
def add_to_powerline(self):
self.powerline.append(
" %s " % os.getenv(self.segment_def["var"]),
self.segment_def.get("fg_color", self.powerline.theme.PATH_FG),
self.segment_def.get("bg_color", self.powerline.theme.PATH_BG))

View file

@ -1,6 +1,17 @@
import os
import subprocess
from ..utils import RepoStats, ThreadedSegment, get_subprocess_env
from ..utils import RepoStats, ThreadedSegment
def get_PATH():
"""Normally gets the PATH from the OS. This function exists to enable
easily mocking the PATH in tests.
"""
return os.getenv("PATH")
def fossil_subprocess_env():
return {"PATH": get_PATH()}
def _get_fossil_branch():
@ -38,7 +49,7 @@ def build_stats():
try:
subprocess.Popen(['fossil'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=get_subprocess_env()).communicate()
env=fossil_subprocess_env()).communicate()
except OSError:
# Popen will throw an OSError if fossil is not found
return (None, None)
@ -63,9 +74,6 @@ class Segment(ThreadedSegment):
if self.stats.dirty:
bg = self.powerline.theme.REPO_DIRTY_BG
fg = self.powerline.theme.REPO_DIRTY_FG
if self.powerline.segment_conf("vcs", "show_symbol"):
symbol = RepoStats().symbols["fossil"] + " "
else:
symbol = ""
self.powerline.append(" " + symbol + self.branch + " ", fg, bg)
self.powerline.append(" " + self.branch + " ", fg, bg)
self.stats.add_to_powerline(self.powerline)

View file

@ -1,6 +1,28 @@
import re
import subprocess
from ..utils import RepoStats, ThreadedSegment, get_git_subprocess_env
import os
from ..utils import RepoStats, ThreadedSegment
def get_PATH():
"""Normally gets the PATH from the OS. This function exists to enable
easily mocking the PATH in tests.
"""
return os.getenv("PATH")
def git_subprocess_env():
return {
# LANG is specified to ensure git always uses a language we are expecting.
# Otherwise we may be unable to parse the output.
"LANG": "C",
# https://github.com/milkbikis/powerline-shell/pull/126
"HOME": os.getenv("HOME"),
# https://github.com/milkbikis/powerline-shell/pull/153
"PATH": get_PATH(),
}
def parse_git_branch_info(status):
@ -11,7 +33,7 @@ def parse_git_branch_info(status):
def _get_git_detached_branch():
p = subprocess.Popen(['git', 'describe', '--tags', '--always'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=get_git_subprocess_env())
env=git_subprocess_env())
detached_ref = p.communicate()[0].decode("utf-8").rstrip('\n')
if p.returncode == 0:
branch = u'{} {}'.format(RepoStats.symbols['detached'], detached_ref)
@ -41,7 +63,7 @@ def build_stats():
try:
p = subprocess.Popen(['git', 'status', '--porcelain', '-b'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=get_git_subprocess_env())
env=git_subprocess_env())
except OSError:
# Popen will throw an OSError if git is not found
return (None, None)
@ -76,9 +98,6 @@ class Segment(ThreadedSegment):
if self.stats.dirty:
bg = self.powerline.theme.REPO_DIRTY_BG
fg = self.powerline.theme.REPO_DIRTY_FG
if self.powerline.segment_conf("vcs", "show_symbol"):
symbol = RepoStats().symbols["git"] + " "
else:
symbol = ""
self.powerline.append(" " + symbol + self.branch + " ", fg, bg)
self.powerline.append(" " + self.branch + " ", fg, bg)
self.stats.add_to_powerline(self.powerline)

View file

@ -1,34 +0,0 @@
import subprocess
from ..utils import RepoStats, ThreadedSegment, get_git_subprocess_env
def get_stash_count():
try:
p = subprocess.Popen(['git', 'stash', 'list'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=get_git_subprocess_env())
except OSError:
return 0
pdata = p.communicate()
if p.returncode != 0:
return 0
return pdata[0].count(b'\n')
class Segment(ThreadedSegment):
def run(self):
self.stash_count = get_stash_count()
def add_to_powerline(self):
self.join()
if not self.stash_count:
return
bg = self.powerline.theme.GIT_STASH_BG
fg = self.powerline.theme.GIT_STASH_FG
sc = self.stash_count if self.stash_count > 1 else ''
stash_str = u' {}{} '.format(sc, RepoStats.symbols['stash'])
self.powerline.append(stash_str, fg, bg)

View file

@ -1,12 +1,24 @@
import os
import subprocess
from ..utils import RepoStats, ThreadedSegment, get_subprocess_env
from ..utils import RepoStats, ThreadedSegment
def get_PATH():
"""Normally gets the PATH from the OS. This function exists to enable
easily mocking the PATH in tests.
"""
return os.getenv("PATH")
def hg_subprocess_env():
return {"PATH": get_PATH()}
def _get_hg_branch():
p = subprocess.Popen(["hg", "branch"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=get_subprocess_env())
env=hg_subprocess_env())
branch = p.communicate()[0].decode("utf-8").rstrip('\n')
return branch
@ -34,7 +46,7 @@ def build_stats():
p = subprocess.Popen(["hg", "status"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=get_subprocess_env())
env=hg_subprocess_env())
except OSError:
# Will be thrown if hg cannot be found
return None, None
@ -60,9 +72,5 @@ class Segment(ThreadedSegment):
if self.stats.dirty:
bg = self.powerline.theme.REPO_DIRTY_BG
fg = self.powerline.theme.REPO_DIRTY_FG
if self.powerline.segment_conf("vcs", "show_symbol"):
symbol = RepoStats().symbols["hg"] + " "
else:
symbol = ""
self.powerline.append(" " + symbol + self.branch + " ", fg, bg)
self.powerline.append(" " + self.branch + " ", fg, bg)
self.stats.add_to_powerline(self.powerline)

View file

@ -6,30 +6,26 @@ from ..utils import ThreadedSegment
class Segment(ThreadedSegment):
def run(self):
self.num_jobs = 0
system = platform.system()
if system.startswith("CYGWIN") or system.startswith("MINGW"):
if platform.system().startswith('CYGWIN'):
# cygwin ps is a special snowflake...
output_proc = subprocess.Popen(["ps", "-af"], stdout=subprocess.PIPE)
output = [int(l.split()[2].strip()) for l in output_proc.communicate()[0].decode("utf-8").splitlines()[1:]]
output_proc = subprocess.Popen(['ps', '-af'], stdout=subprocess.PIPE)
output = map(lambda l: int(l.split()[2].strip()),
output_proc.communicate()[0].decode("utf-8").splitlines()[1:])
self.num_jobs = output.count(os.getppid()) - 1
else:
# The following logic was tested on:
# - fish, version 3.3.1
# - GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
# - zsh 5.8.1 (x86_64-ubuntu-linux-gnu)
# If you change the behavior to account for another shell's
# behavior, please provide details of the shell version you tested
# on in this comment.
output_proc = subprocess.Popen(["ps", "-a", "-o", "ppid"], stdout=subprocess.PIPE)
pppid_proc = subprocess.Popen(['ps', '-p', str(os.getppid()), '-oppid='],
stdout=subprocess.PIPE)
pppid = pppid_proc.communicate()[0].decode("utf-8").strip()
output_proc = subprocess.Popen(['ps', '-a', '-o', 'ppid'],
stdout=subprocess.PIPE)
output = output_proc.communicate()[0].decode("utf-8")
self.num_jobs = len(re.findall(str(os.getppid()), output)) - 1
self.num_jobs = len(re.findall(str(pppid), output)) - 1
def add_to_powerline(self):
self.join()
if self.num_jobs > 0:
self.powerline.append(" %d " % self.num_jobs,
self.powerline.append(' %d ' % self.num_jobs,
self.powerline.theme.JOBS_FG,
self.powerline.theme.JOBS_BG)

View file

@ -1,14 +1,12 @@
import subprocess
from ..utils import ThreadedSegment, decode
from ..utils import ThreadedSegment
class Segment(ThreadedSegment):
def run(self):
self.version = None
try:
output = decode(
subprocess.check_output(['php', '-r', 'echo PHP_VERSION;'],
stderr=subprocess.STDOUT))
output = subprocess.check_output(['php', '-r', 'echo PHP_VERSION;'],
stderr=subprocess.STDOUT)
self.version = output.split('-')[0] if '-' in output else output
except OSError:
self.version = None

View file

@ -15,4 +15,4 @@ class Segment(BasicSegment):
if powerline.args.prev_error != 0:
fg = powerline.theme.CMD_FAILED_FG
bg = powerline.theme.CMD_FAILED_BG
powerline.append(root_indicators[powerline.args.shell], fg, bg, sanitize=False)
powerline.append(root_indicators[powerline.args.shell], fg, bg)

View file

@ -6,17 +6,14 @@ from ..utils import BasicSegment
class Segment(BasicSegment):
def add_to_powerline(self):
powerline = self.powerline
try:
p1 = subprocess.Popen(['ruby', '-v'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['sed', "s/ (.*//"], stdin=p1.stdout, stdout=subprocess.PIPE)
ruby_and_gemset = p2.communicate()[0].decode('utf-8').rstrip()
gem_set = os.environ.get('GEM_HOME', '@').split('@')
if len(gem_set) > 1:
ruby_and_gemset += "@{}".format(gem_set.pop())
powerline.append(ruby_and_gemset, 15, 1)
p1 = subprocess.Popen(["ruby", "-v"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["sed", "s/ (.*//"], stdin=p1.stdout, stdout=subprocess.PIPE)
version = p2.communicate()[0].decode("utf-8").rstrip()
if os.environ.has_key("GEM_HOME"):
gem = os.environ["GEM_HOME"].split("@")
if len(gem) > 1:
version += " " + gem[1]
powerline.append(version, 15, 1)
except OSError:
return

View file

@ -1,17 +0,0 @@
import subprocess
from ..utils import ThreadedSegment
class Segment(ThreadedSegment):
def run(self):
cmd = self.segment_def["command"]
self.output = subprocess.check_output(cmd).decode("utf-8").strip()
# TODO handle OSError
# TODO handle no command defined or malformed
def add_to_powerline(self):
self.join()
self.powerline.append(
" %s " % self.output,
self.segment_def.get("fg_color", self.powerline.theme.PATH_FG),
self.segment_def.get("bg_color", self.powerline.theme.PATH_BG))

View file

@ -1,57 +1,41 @@
import subprocess
from ..utils import ThreadedSegment, RepoStats, get_subprocess_env
def _get_svn_revision():
p = subprocess.Popen(["svn", "info", "--xml"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=get_subprocess_env())
for line in p.communicate()[0].decode("utf-8").splitlines():
if "revision" in line:
revision = line.split("=")[1].split('"')[1]
break
return revision
def parse_svn_stats(status):
stats = RepoStats()
for line in status:
if line[0] == "?":
stats.new += 1
elif line[0] == "C":
stats.conflicted += 1
elif line[0] in ["A", "D", "I", "M", "R", "!", "~"]:
stats.changed += 1
return stats
def _get_svn_status(output):
"""This function exists to enable mocking the `svn status` output in tests.
"""
return output[0].decode("utf-8").splitlines()
def build_stats():
try:
p = subprocess.Popen(['svn', 'status'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=get_subprocess_env())
except OSError:
# Popen will throw an OSError if svn is not found
return None, None
pdata = p.communicate()
if p.returncode != 0 or pdata[1][:22] == b'svn: warning: W155007:':
return None, None
status = _get_svn_status(pdata)
stats = parse_svn_stats(status)
revision = _get_svn_revision()
return stats, revision
from ..utils import ThreadedSegment, RepoStats
class Segment(ThreadedSegment):
def __init__(self, powerline):
super(Segment, self).__init__(powerline)
self.stats = None
self.revision = ""
def run(self):
self.stats, self.revision = build_stats()
try:
svn_status = subprocess.Popen(["svn", "status"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
svn_info = subprocess.Popen(["svn", "info"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
svn_stdout, svn_stderr = svn_status.communicate()
svn_info, _ = svn_info.communicate()
except OSError:
return
if len(svn_stderr.decode("utf-8").strip()) != 0:
return
self.stats = RepoStats()
for line in svn_stdout.splitlines():
line = line.decode("utf-8").strip()
if line[0] == "?":
self.stats.new += 1
elif line[0] == "C":
self.stats.conflicted += 1
elif line[0] in ["A", "D", "I", "M", "R", "!", "~"]:
self.stats.changed += 1
for line in svn_info.splitlines():
line = line.decode("utf-8").strip()
if "Revision: " in line:
self.revision = line.split(" ", 1)[1]
def add_to_powerline(self):
self.join()
@ -62,9 +46,6 @@ class Segment(ThreadedSegment):
if self.stats.dirty:
bg = self.powerline.theme.REPO_DIRTY_BG
fg = self.powerline.theme.REPO_DIRTY_FG
if self.powerline.segment_conf("vcs", "show_symbol"):
symbol = " " + RepoStats().symbols["svn"]
else:
symbol = ""
self.powerline.append(symbol + " rev " + self.revision + " ", fg, bg)
self.powerline.append(" rev " + self.revision + " ", fg, bg)
self.stats.add_to_powerline(self.powerline)

View file

@ -6,15 +6,12 @@ import time
class Segment(BasicSegment):
def add_to_powerline(self):
powerline = self.powerline
format = powerline.segment_conf('time', 'format')
if format:
time_ = ' %s ' % time.strftime(format)
elif powerline.args.shell == 'bash':
if powerline.args.shell == 'bash':
time_ = ' \\t '
elif powerline.args.shell == 'zsh':
time_ = ' %* '
else:
time_ = ' %s ' % time.strftime('%H:%M:%S')
powerline.append(time_,
powerline.theme.TIME_FG,
powerline.theme.TIME_BG)
powerline.theme.HOSTNAME_FG,
powerline.theme.HOSTNAME_BG)

View file

@ -1,13 +1,13 @@
import subprocess
import re
from ..utils import BasicSegment, decode
from ..utils import BasicSegment
class Segment(BasicSegment):
def add_to_powerline(self):
powerline = self.powerline
try:
output = decode(subprocess.check_output(['uptime'], stderr=subprocess.STDOUT))
output = subprocess.check_output(['uptime'], stderr=subprocess.STDOUT).decode("utf-8")
raw_uptime = re.search('(?<=up).+(?=,\s+\d+\s+user)', output).group(0)
day_search = re.search('\d+(?=\s+day)', output)
days = '' if not day_search else '%sd ' % day_search.group(0)

View file

@ -7,9 +7,6 @@ class Segment(BasicSegment):
env = os.getenv('VIRTUAL_ENV') \
or os.getenv('CONDA_ENV_PATH') \
or os.getenv('CONDA_DEFAULT_ENV')
if os.getenv('VIRTUAL_ENV') \
and os.path.basename(env) == '.venv':
env = os.path.basename(os.path.dirname(env))
if not env:
return
env_name = os.path.basename(env)

View file

@ -1,4 +1,4 @@
from powerline_shell.themes.default import DefaultColor
from .default import DefaultColor
class Color(DefaultColor):
@ -40,6 +40,3 @@ class Color(DefaultColor):
AWS_PROFILE_FG = 14
AWS_PROFILE_BG = 8
TIME_FG = 8
TIME_BG = 7

View file

@ -58,9 +58,6 @@ class DefaultColor(object):
GIT_CONFLICTED_BG = 9
GIT_CONFLICTED_FG = 15
GIT_STASH_BG = 221
GIT_STASH_FG = 0
VIRTUAL_ENV_BG = 35 # a mid-tone green
VIRTUAL_ENV_FG = 00
@ -72,10 +69,6 @@ class DefaultColor(object):
AWS_PROFILE_FG = 39
AWS_PROFILE_BG = 238
TIME_FG = 250
TIME_BG = 238
class Color(DefaultColor):
"""
This subclass is required when the user chooses to use 'default' theme.

View file

@ -1,111 +0,0 @@
from powerline_shell.themes.default import DefaultColor
"""
absolute colors based on
https://github.com/morhetz/gruvbox/blob/master/colors/gruvbox.vim
"""
dark0 = 235
dark1 = 237
dark2 = 239
dark3 = 241
dark4 = 243
light0 = 229
light1 = 223
light2 = 250
light3 = 248
light4 = 246
dark_gray = 245
light_gray = 244
neutral_red = 124
neutral_green = 106
neutral_yellow = 172
neutral_blue = 66
neutral_purple = 132
neutral_aqua = 72
neutral_orange = 166
bright_red = 167
bright_green = 142
bright_yellow = 214
bright_blue = 109
bright_purple = 175
bright_aqua = 108
bright_orange = 208
faded_red = 88
faded_green = 100
faded_yellow = 136
faded_blue = 24
faded_purple = 96
faded_aqua = 66
faded_orange = 130
class Color(DefaultColor):
USERNAME_ROOT_BG = faded_red
USERNAME_BG = dark2
USERNAME_FG = bright_purple
HOSTNAME_BG = dark1
HOSTNAME_FG = bright_purple
HOME_SPECIAL_DISPLAY = True
HOME_BG = neutral_blue
HOME_FG = light2
PATH_BG = dark3
PATH_FG = light3
CWD_FG = light2
SEPARATOR_FG = dark_gray
READONLY_BG = bright_red
READONLY_FG = light0
SSH_BG = faded_purple
SSH_FG = light0
REPO_CLEAN_BG = faded_green
REPO_CLEAN_FG = dark1
REPO_DIRTY_BG = faded_orange
REPO_DIRTY_FG = light0
JOBS_FG = neutral_aqua
JOBS_BG = dark1
CMD_PASSED_FG = light4
CMD_PASSED_BG = dark1
CMD_FAILED_FG = light0
CMD_FAILED_BG = neutral_red
SVN_CHANGES_FG = REPO_DIRTY_FG
SVN_CHANGES_BG = REPO_DIRTY_BG
GIT_AHEAD_BG = dark2
GIT_AHEAD_FG = light3
GIT_BEHIND_BG = dark2
GIT_BEHIND_FG = light3
GIT_STAGED_BG = neutral_green
GIT_STAGED_FG = light0
GIT_NOTSTAGED_BG = neutral_orange
GIT_NOTSTAGED_FG = light0
GIT_UNTRACKED_BG = faded_red
GIT_UNTRACKED_FG = light0
GIT_CONFLICTED_BG = neutral_red
GIT_CONFLICTED_FG = light0
GIT_STASH_BG = neutral_yellow
GIT_STASH_FG = dark0
VIRTUAL_ENV_BG = faded_green
VIRTUAL_ENV_FG = light0
BATTERY_NORMAL_BG = neutral_green
BATTERY_NORMAL_FG = dark2
BATTERY_LOW_BG = neutral_red
BATTERY_LOW_FG = light1
AWS_PROFILE_FG = neutral_aqua
AWS_PROFILE_BG = dark1
TIME_FG = light2
TIME_BG = dark4

View file

@ -1,89 +0,0 @@
from powerline_shell.themes.default import DefaultColor
"""
colors from https://www.nordtheme.com/docs/colors-and-palettes
"""
night0 = 236 # nord0
night1 = 237 # nord1
night2 = 238 # nord2
night3 = 239 # nord3
snow0 = 253 # nord4
snow1 = 254 # nord5
snow2 = 255 # nord6
frost0 = 109 # nord7
frost1 = 111 # nord8
frost2 = 110 # nord9
frost3 = 68 # nord10
red = 167 # nord11
orange = 173 # nord12
yellow = 179 # nord13
green = 150 # nord14
purple = 139 # nord15
class Color(DefaultColor):
USERNAME_BG = night3
USERNAME_FG = snow0
HOSTNAME_FG = snow0
HOSTNAME_BG = night0
HOME_BG = frost2
HOME_FG = snow2
PATH_BG = night0
PATH_FG = snow0
CWD_FG = snow0
SEPARATOR_FG = night3
READONLY_BG = red
READONLY_FG = snow2
SSH_BG = orange
SSH_FG = snow2
REPO_CLEAN_BG = green
REPO_CLEAN_FG = night1
REPO_DIRTY_BG = red
REPO_DIRTY_FG = snow2
JOBS_FG = frost3
JOBS_BG = night0
CMD_PASSED_BG = night0
CMD_PASSED_FG = snow2
CMD_FAILED_BG = yellow
CMD_FAILED_FG = snow2
SVN_CHANGES_BG = REPO_DIRTY_FG
SVN_CHANGES_FG = REPO_DIRTY_BG
GIT_AHEAD_BG = night3
GIT_AHEAD_FG = snow0
GIT_BEHIND_BG = night3
GIT_BEHIND_FG = snow0
GIT_STAGED_BG = frost0
GIT_STAGED_FG = night1
GIT_NOTSTAGED_BG = orange
GIT_NOTSTAGED_FG = snow2
GIT_UNTRACKED_BG = purple
GIT_UNTRACKED_FG = snow2
GIT_CONFLICTED_BG = red
GIT_CONFLICTED_FG = snow2
GIT_STASH_BG = yellow
GIT_STASH_FG = night1
VIRTUAL_ENV_BG = green
VIRTUAL_ENV_FG = night1
BATTERY_NORMAL_BG = green
BATTERY_NORMAL_FG = night1
BATTERY_LOW_BG = red
BATTERY_LOW_FG = snow2
AWS_PROFILE_FG = frost3
AWS_PROFILE_BG = night0
TIME_BG = night3
TIME_FG = snow0

View file

@ -1,4 +1,4 @@
from powerline_shell.themes.default import DefaultColor
from .default import DefaultColor
class Color(DefaultColor):
@ -39,6 +39,3 @@ class Color(DefaultColor):
AWS_PROFILE_FG = 7
AWS_PROFILE_BG = 2
TIME_FG = 15
TIME_BG = 10

View file

@ -1,4 +1,4 @@
from powerline_shell.themes.default import DefaultColor
from .default import DefaultColor
class Color(DefaultColor):
@ -36,6 +36,3 @@ class Color(DefaultColor):
VIRTUAL_ENV_BG = 15
VIRTUAL_ENV_FG = 2
TIME_FG = 15
TIME_BG = 10

View file

@ -1,4 +1,4 @@
from powerline_shell.themes.default import DefaultColor
from .default import DefaultColor
class Color(DefaultColor):
@ -39,6 +39,3 @@ class Color(DefaultColor):
AWS_PROFILE_FG = 0
AWS_PROFILE_BG = 7
TIME_FG = 8
TIME_BG = 7

View file

@ -1,17 +1,11 @@
import sys
import os
import threading
py3 = sys.version_info[0] == 3
if py3:
def unicode_(x):
def unicode(x):
return str(x)
def decode(x):
return x.decode("utf-8")
else:
unicode_ = unicode
decode = unicode
class RepoStats(object):
@ -22,13 +16,7 @@ class RepoStats(object):
'staged': u'\u2714',
'changed': u'\u270E',
'new': u'?',
'conflicted': u'\u273C',
'stash': u'\u2398',
'git': u'\uE0A0',
'hg': u'\u263F',
'bzr': u'\u2B61\u20DF',
'fossil': u'\u2332',
'svn': u'\u2446'
'conflicted': u'\u273C'
}
def __init__(self, ahead=0, behind=0, new=0, changed=0, staged=0, conflicted=0):
@ -73,7 +61,7 @@ class RepoStats(object):
segment = repo_stats.n_or_empty("new") + icon_string
"""
return unicode_(self[_key]) if int(self[_key]) > 1 else u''
return unicode(self[_key]) if int(self[_key]) > 1 else u''
def add_to_powerline(self, powerline):
def add(_key, fg, bg):
@ -94,59 +82,14 @@ def warn(msg):
class BasicSegment(object):
def __init__(self, powerline, segment_def):
def __init__(self, powerline):
self.powerline = powerline
self.segment_def = segment_def # type: dict
def start(self):
pass
class ThreadedSegment(threading.Thread):
def __init__(self, powerline, segment_def):
def __init__(self, powerline):
super(ThreadedSegment, self).__init__()
self.powerline = powerline
self.segment_def = segment_def # type: dict
def import_file(module_name, path):
# An implementation of https://stackoverflow.com/a/67692/683436
if py3 and sys.version_info[1] >= 5:
import importlib.util
spec = importlib.util.spec_from_file_location(module_name, path)
if not spec:
raise ImportError()
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
elif py3:
from importlib.machinery import SourceFileLoader
return SourceFileLoader(module_name, path).load_module()
else:
import imp
return imp.load_source(module_name, path)
def get_PATH():
"""Normally gets the PATH from the OS. This function exists to enable
easily mocking the PATH in tests.
"""
return os.getenv("PATH")
def get_subprocess_env(**envs):
defaults = {
# https://github.com/milkbikis/powerline-shell/pull/153
"PATH": get_PATH(),
}
defaults.update(envs)
env = dict(os.environ)
env.update(defaults)
return env
def get_git_subprocess_env():
# LANG is specified to ensure git always uses a language we are expecting.
# Otherwise we may be unable to parse the output.
return get_subprocess_env(LANG="C")

View file

@ -1,4 +1,3 @@
nose>=1.3.7
mock>=1.3.0
sh>=1.11
parameterized>=0.6.1

View file

@ -3,20 +3,11 @@ from setuptools import setup, find_packages
setup(
name="powerline-shell",
version="0.7.0",
version="0.4.6",
description="A pretty prompt for your shell",
author="Buck Ryan",
author_email="buck@buckryan.com",
license="MIT",
url="https://github.com/b-ryan/powerline-shell",
classifiers=[
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
],
url="https://github.com/banga/powerline-shell",
classifiers=[],
packages=[
"powerline_shell",
"powerline_shell.segments",

View file

@ -1,6 +1,4 @@
#!/bin/sh
set -eu
docker build -t powerline-shell .
docker run --rm --interactive --tty \
--volume $PWD:/code \
powerline-shell "$@"
docker run --rm -it powerline-shell -c nosetests

View file

View file

@ -1,49 +0,0 @@
import unittest
from parameterized import parameterized
from powerline_shell.color_compliment import getOppositeColor
def build_inputs():
# Build 768 hex/rgb values to test against getOppositeColor
input_bytes = map(hex, xrange(pow(2,8)))
input_list = []
for x in input_bytes:
#Building hex range of [00-ff]:00:00
combined1 = hex((int(x,16)<<16)| ((int(input_bytes[0],16)<<8)|int(input_bytes[0],16)))
test_input1 = tuple((int(x,16), int(input_bytes[0],16), int(input_bytes[0],16)))
#Building hex range of 00:[00-ff]:00
combined2 = hex((int(input_bytes[0],16)<<16)| ((int(x,16)<<8)|int(input_bytes[0],16)))
test_input2 = tuple((int(input_bytes[0],16), int(x,16), int(input_bytes[0],16)))
#Building hex range of 00:00:[00-ff]
combined3 = hex((int(input_bytes[0],16)<<16)| ((int(input_bytes[0],16)<<8)|int(x,16)))
test_input3 = tuple((int(input_bytes[0],16), int(input_bytes[0],16), int(x,16)))
input_list.append(tuple((combined1, test_input1)))
input_list.append(tuple((combined2, test_input2)))
input_list.append(tuple((combined3, test_input3)))
return input_list
class getOppositeColorTestCase(unittest.TestCase):
'''
Test only runs against 768 combinations of rgb values.
Trying to run parameterized unittest against 16.77M rgb values
was near impossible (need lots of memory and time). Of the 768
values tested, the test has proven to catch 192 exceptions (and 3
ZeroDivisionError exceptions from rgb_to_hls). This can be tested
by commenting out the first line of getOppositeColor, which
converts the rgb values to float.
'''
@parameterized.expand(build_inputs)
def test_rgb_input_get_opposite_not_negative(self, name, test_input):
negative = -1
self.assertNotIn(negative, getOppositeColor(*test_input), u'{0:#08x} returns negative number in rgb tuple'.format(int(name,16)))

View file

@ -5,7 +5,6 @@ import shutil
import sh
import powerline_shell.segments.bzr as bzr
from powerline_shell.utils import RepoStats
from ..testing_utils import dict_side_effect_fn
test_cases = (
@ -23,9 +22,6 @@ class BzrTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.powerline.segment_conf.side_effect = dict_side_effect_fn({
("vcs", "show_symbol"): False,
})
self.dirname = tempfile.mkdtemp()
sh.cd(self.dirname)
@ -34,7 +30,7 @@ class BzrTest(unittest.TestCase):
sh.cd("trunk")
sh.bzr("init")
self.segment = bzr.Segment(self.powerline, {})
self.segment = bzr.Segment(self.powerline)
def tearDown(self):
shutil.rmtree(self.dirname)
@ -49,7 +45,7 @@ class BzrTest(unittest.TestCase):
sh.bzr("branch", "trunk", branch)
sh.cd(branch)
@mock.patch("powerline_shell.utils.get_PATH")
@mock.patch("powerline_shell.segments.bzr.get_PATH")
def test_bzr_not_installed(self, get_PATH):
get_PATH.return_value = "" # so bzr can't be found
self.segment.start()

View file

@ -5,7 +5,6 @@ import shutil
import sh
import powerline_shell.segments.fossil as fossil
from powerline_shell.utils import RepoStats
from ..testing_utils import dict_side_effect_fn
test_cases = {
"EXTRA new-file": RepoStats(new=1),
@ -19,16 +18,13 @@ class FossilTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.powerline.segment_conf.side_effect = dict_side_effect_fn({
("vcs", "show_symbol"): False,
})
self.dirname = tempfile.mkdtemp()
sh.cd(self.dirname)
sh.fossil("init", "test.fossil")
sh.fossil("open", "test.fossil")
self.segment = fossil.Segment(self.powerline, {})
self.segment = fossil.Segment(self.powerline)
def tearDown(self):
shutil.rmtree(self.dirname)
@ -42,7 +38,7 @@ class FossilTest(unittest.TestCase):
sh.fossil("branch", "new", branch, "trunk")
sh.fossil("checkout", branch)
@mock.patch("powerline_shell.utils.get_PATH")
@mock.patch("powerline_shell.segments.fossil.get_PATH")
def test_fossil_not_installed(self, get_PATH):
get_PATH.return_value = "" # so fossil can't be found
self.segment.start()

View file

@ -1,77 +0,0 @@
import unittest
import mock
import tempfile
import shutil
import sh
import powerline_shell.segments.git_stash as git_stash
from powerline_shell.utils import RepoStats
class GitStashTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.dirname = tempfile.mkdtemp()
sh.cd(self.dirname)
sh.git("init", ".")
self.segment = git_stash.Segment(self.powerline, {})
def tearDown(self):
shutil.rmtree(self.dirname)
def _add_and_commit(self, filename):
sh.touch(filename)
sh.git("add", filename)
sh.git("commit", "-m", "add file " + filename)
def _overwrite_file(self, filename, content):
sh.echo(content, _out=filename)
def _stash(self):
sh.git("stash")
@mock.patch('powerline_shell.utils.get_PATH')
def test_git_not_installed(self, get_PATH):
get_PATH.return_value = "" # so git can't be found
self.segment.start()
self.segment.add_to_powerline()
self.assertEqual(self.powerline.append.call_count, 0)
def test_non_git_directory(self):
shutil.rmtree(".git")
self.segment.start()
self.segment.add_to_powerline()
self.assertEqual(self.powerline.append.call_count, 0)
def test_no_stashes(self):
self._add_and_commit("foo")
self.segment.start()
self.segment.add_to_powerline()
self.assertEqual(self.powerline.append.call_count, 0)
def test_one_stash(self):
self._add_and_commit("foo")
self._overwrite_file("foo", "some new content")
self._stash()
self.segment.start()
self.segment.add_to_powerline()
expected = u' {} '.format(RepoStats.symbols["stash"])
self.assertEqual(self.powerline.append.call_args[0][0], expected)
def test_multiple_stashes(self):
self._add_and_commit("foo")
self._overwrite_file("foo", "some new content")
self._stash()
self._overwrite_file("foo", "some different content")
self._stash()
self._overwrite_file("foo", "more different content")
self._stash()
self.segment.start()
self.segment.add_to_powerline()
expected = u' 3{} '.format(RepoStats.symbols["stash"])
self.assertEqual(self.powerline.append.call_args[0][0], expected)

View file

@ -4,22 +4,18 @@ import tempfile
import shutil
import sh
import powerline_shell.segments.git as git
from ..testing_utils import dict_side_effect_fn
class GitTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.powerline.segment_conf.side_effect = dict_side_effect_fn({
("vcs", "show_symbol"): False,
})
self.dirname = tempfile.mkdtemp()
sh.cd(self.dirname)
sh.git("init", ".")
self.segment = git.Segment(self.powerline, {})
self.segment = git.Segment(self.powerline)
def tearDown(self):
shutil.rmtree(self.dirname)
@ -35,7 +31,7 @@ class GitTest(unittest.TestCase):
def _get_commit_hash(self):
return sh.git("rev-parse", "HEAD")
@mock.patch('powerline_shell.utils.get_PATH')
@mock.patch('powerline_shell.segments.git.get_PATH')
def test_git_not_installed(self, get_PATH):
get_PATH.return_value = "" # so git can't be found
self.segment.start()

View file

@ -5,7 +5,6 @@ import shutil
import sh
import powerline_shell.segments.hg as hg
from powerline_shell.utils import RepoStats
from ..testing_utils import dict_side_effect_fn
test_cases = {
@ -21,15 +20,12 @@ class HgTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.powerline.segment_conf.side_effect = dict_side_effect_fn({
("vcs", "show_symbol"): False,
})
self.dirname = tempfile.mkdtemp()
sh.cd(self.dirname)
sh.hg("init", ".")
self.segment = hg.Segment(self.powerline, {})
self.segment = hg.Segment(self.powerline)
def tearDown(self):
shutil.rmtree(self.dirname)
@ -42,7 +38,7 @@ class HgTest(unittest.TestCase):
def _checkout_new_branch(self, branch):
sh.hg("branch", branch)
@mock.patch("powerline_shell.utils.get_PATH")
@mock.patch("powerline_shell.segments.hg.get_PATH")
def test_hg_not_installed(self, get_PATH):
get_PATH.return_value = "" # so hg can"t be found
self.segment.start()

View file

@ -9,7 +9,7 @@ class HostnameTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.powerline.theme = Color
self.segment = hostname.Segment(self.powerline, {})
self.segment = hostname.Segment(self.powerline)
def test_colorize(self):
self.powerline.segment_conf.return_value = True

View file

@ -1,32 +0,0 @@
import tempfile
import unittest
import shutil
import mock
import sh
import powerline_shell.segments.svn as svn
from ..testing_utils import dict_side_effect_fn
class SvnTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.powerline.segment_conf.side_effect = dict_side_effect_fn({
("vcs", "show_symbol"): False,
})
self.dirname = tempfile.mkdtemp()
sh.cd(self.dirname)
# sh.svn("init", ".")
self.segment = svn.Segment(self.powerline, {})
def tearDown(self):
shutil.rmtree(self.dirname)
@mock.patch("powerline_shell.utils.get_PATH")
def test_svn_not_installed(self, get_PATH):
get_PATH.return_value = "" # so svn can't be found
self.segment.start()
self.segment.add_to_powerline()
self.assertEqual(self.powerline.append.call_count, 0)

View file

@ -19,7 +19,7 @@ class UptimeTest(unittest.TestCase):
def setUp(self):
self.powerline = mock.MagicMock()
self.segment = uptime.Segment(self.powerline, {})
self.segment = uptime.Segment(self.powerline)
@mock.patch('subprocess.check_output')
def test_all(self, check_output):

View file

@ -1,4 +0,0 @@
def dict_side_effect_fn(dict_):
def func(*args):
return dict_[args]
return func