Skip to content
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
16 changes: 6 additions & 10 deletions doc/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,27 +59,17 @@ session.

You can also `Import`_ configs `teamocil`_ and `tmuxinator`_.

.. _Import: http://tmuxp.readthedocs.io/en/latest/cli.html#import
.. _tmuxinator: https://github.com/aziz/tmuxinator
.. _teamocil: https://github.com/remiprev/teamocil



Pythonics
---------

.. seealso::
:ref:`libtmux python API documentation <libtmux:api>` and :ref:`developing`,
:ref:`internals`.


ORM - `Object Relational Mapper`_

AL - `Abstraction Layer`_

.. _Abstraction Layer: http://en.wikipedia.org/wiki/Abstraction_layer
.. _Object Relational Mapper: http://en.wikipedia.org/wiki/Object-relational_mapping

python abstraction layer
""""""""""""""""""""""""

Expand All @@ -94,3 +84,9 @@ python abstraction layer
:meth:`libtmux.Window.split_window` ``$ tmux split-window``
:meth:`libtmux.Pane.send_keys` ``$ tmux send-keys``
======================================== =================================

.. _Import: http://tmuxp.readthedocs.io/en/latest/cli.html#import
.. _tmuxinator: https://github.com/aziz/tmuxinator
.. _teamocil: https://github.com/remiprev/teamocil
.. _Abstraction Layer: http://en.wikipedia.org/wiki/Abstraction_layer
.. _Object Relational Mapper: http://en.wikipedia.org/wiki/Object-relational_mapping
119 changes: 64 additions & 55 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
from click.testing import CliRunner

from tmuxp import cli, config
from tmuxp.cli import is_pure_name, load_workspace, resolve_config
from tmuxp.cli import (
is_pure_name, load_workspace, scan_config, get_config_dir
)

from .fixtures._util import curjoin, loadfixture

Expand Down Expand Up @@ -74,6 +76,7 @@ def test_get_configs_cwd(tmpdir):
def test_is_pure_name(path, expect):
assert is_pure_name(path) == expect


"""
scans for .tmuxp.{yaml,yml,json} in directory, returns first result
log warning if multiple found:
Expand Down Expand Up @@ -108,6 +111,12 @@ def projectdir(homedir):
return homedir.join('work').join('project')


def test_tmuxp_configdir_env_var(tmpdir, monkeypatch):
monkeypatch.setenv('TMUXP_CONFIGDIR', tmpdir)

assert get_config_dir() == tmpdir


def test_resolve_dot(tmpdir, homedir, configdir, projectdir, monkeypatch):
monkeypatch.setenv('HOME', homedir)
projectdir.join('.tmuxp.yaml').ensure()
Expand All @@ -118,107 +127,107 @@ def test_resolve_dot(tmpdir, homedir, configdir, projectdir, monkeypatch):

with projectdir.as_cwd():
expect = project_config
assert resolve_config('.') == expect
assert resolve_config('./') == expect
assert resolve_config('') == expect
assert resolve_config('../project') == expect
assert resolve_config('../project/') == expect
assert resolve_config('.tmuxp.yaml') == expect
assert resolve_config(
assert scan_config('.') == expect
assert scan_config('./') == expect
assert scan_config('') == expect
assert scan_config('../project') == expect
assert scan_config('../project/') == expect
assert scan_config('.tmuxp.yaml') == expect
assert scan_config(
'../../.tmuxp/%s.yaml' % user_config_name) == str(user_config)
assert resolve_config('myconfig') == str(user_config)
assert resolve_config(
assert scan_config('myconfig') == str(user_config)
assert scan_config(
'~/.tmuxp/myconfig.yaml') == str(user_config)

with pytest.raises(Exception):
resolve_config('.tmuxp.json')
scan_config('.tmuxp.json')
with pytest.raises(Exception):
resolve_config('.tmuxp.ini')
scan_config('.tmuxp.ini')
with pytest.raises(Exception):
resolve_config('../')
scan_config('../')
with pytest.raises(Exception):
resolve_config('mooooooo')
scan_config('mooooooo')

with homedir.as_cwd():
expect = project_config
assert resolve_config('work/project') == expect
assert resolve_config('work/project/') == expect
assert resolve_config('./work/project') == expect
assert resolve_config('./work/project/') == expect
assert resolve_config(
assert scan_config('work/project') == expect
assert scan_config('work/project/') == expect
assert scan_config('./work/project') == expect
assert scan_config('./work/project/') == expect
assert scan_config(
'.tmuxp/%s.yaml' % user_config_name) == str(user_config)
assert resolve_config(
assert scan_config(
'./.tmuxp/%s.yaml' % user_config_name) == str(user_config)
assert resolve_config('myconfig') == str(user_config)
assert resolve_config(
assert scan_config('myconfig') == str(user_config)
assert scan_config(
'~/.tmuxp/myconfig.yaml') == str(user_config)

with pytest.raises(Exception):
resolve_config('')
scan_config('')
with pytest.raises(Exception):
resolve_config('.')
scan_config('.')
with pytest.raises(Exception):
resolve_config('.tmuxp.yaml')
scan_config('.tmuxp.yaml')
with pytest.raises(Exception):
resolve_config('../')
scan_config('../')
with pytest.raises(Exception):
resolve_config('mooooooo')
scan_config('mooooooo')

with configdir.as_cwd():
expect = project_config
assert resolve_config('../work/project') == expect
assert resolve_config('../../home/work/project') == expect
assert resolve_config('../work/project/') == expect
assert resolve_config(
assert scan_config('../work/project') == expect
assert scan_config('../../home/work/project') == expect
assert scan_config('../work/project/') == expect
assert scan_config(
'%s.yaml' % user_config_name) == str(user_config)
assert resolve_config(
assert scan_config(
'./%s.yaml' % user_config_name) == str(user_config)
assert resolve_config('myconfig') == str(user_config)
assert resolve_config(
assert scan_config('myconfig') == str(user_config)
assert scan_config(
'~/.tmuxp/myconfig.yaml') == str(user_config)

with pytest.raises(Exception):
resolve_config('')
scan_config('')
with pytest.raises(Exception):
resolve_config('.')
scan_config('.')
with pytest.raises(Exception):
resolve_config('.tmuxp.yaml')
scan_config('.tmuxp.yaml')
with pytest.raises(Exception):
resolve_config('../')
scan_config('../')
with pytest.raises(Exception):
resolve_config('mooooooo')
scan_config('mooooooo')

with tmpdir.as_cwd():
expect = project_config
assert resolve_config('home/work/project') == expect
assert resolve_config('./home/work/project/') == expect
assert resolve_config(
assert scan_config('home/work/project') == expect
assert scan_config('./home/work/project/') == expect
assert scan_config(
'home/.tmuxp/%s.yaml' % user_config_name) == str(user_config)
assert resolve_config(
assert scan_config(
'./home/.tmuxp/%s.yaml' % user_config_name) == str(user_config)
assert resolve_config('myconfig') == str(user_config)
assert resolve_config(
assert scan_config('myconfig') == str(user_config)
assert scan_config(
'~/.tmuxp/myconfig.yaml') == str(user_config)

with pytest.raises(Exception):
resolve_config('')
scan_config('')
with pytest.raises(Exception):
resolve_config('.')
scan_config('.')
with pytest.raises(Exception):
resolve_config('.tmuxp.yaml')
scan_config('.tmuxp.yaml')
with pytest.raises(Exception):
resolve_config('../')
scan_config('../')
with pytest.raises(Exception):
resolve_config('mooooooo')
scan_config('mooooooo')


def test_resolve_config_arg(homedir, configdir, projectdir, monkeypatch):
def test_scan_config_arg(homedir, configdir, projectdir, monkeypatch):
runner = CliRunner()

@click.command()
@click.argument(
'config', click.Path(exists=True), nargs=-1,
callback=cli.resolve_config_argument)
callback=cli.scan_config_argument)
def config_cmd(config):
click.echo(config)

Expand Down Expand Up @@ -430,21 +439,21 @@ def test_validate_choices():
assert validate('choice3')


def test_create_resolve_config_arg(tmpdir):
def test_create_scan_config_arg(tmpdir):
configdir = tmpdir.join('myconfigdir')
configdir.mkdir()
user_config_name = 'myconfig'
user_config = configdir.join('%s.yaml' % user_config_name).ensure()

expect = str(configdir.join('myconfig.yaml'))
my_resolve_config = cli._create_resolve_config_argument(str(configdir))
my_scan_config = cli._create_scan_config_argument(str(configdir))

runner = CliRunner()

@click.command()
@click.argument(
'config', click.Path(exists=True), nargs=-1,
callback=my_resolve_config)
callback=my_scan_config)
def config_cmd(config):
click.echo(config)

Expand Down
25 changes: 14 additions & 11 deletions tmuxp/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@


def get_config_dir():
if 'TMUXP_CONFIGDIR' in os.environ:
return os.path.expanduser(os.environ['TMUXP_CONFIGDIR'])

return os.path.expanduser('~/.tmuxp/')


Expand Down Expand Up @@ -69,18 +72,18 @@ def is_pure_name(path):
)


def _create_resolve_config_argument(config_dir):
def _create_scan_config_argument(config_dir):
"""For finding configurations in tmuxinator/teamocil"""
def func(ctx, param, value):
return resolve_config_argument(ctx, param, value, config_dir)
return scan_config_argument(ctx, param, value, config_dir)

return func


def resolve_config_argument(ctx, param, value, config_dir=None):
def scan_config_argument(ctx, param, value, config_dir=None):
"""Validate / translate config name/path values for click config arg.

Wrapper on top of :func:`cli.resolve_config`."""
Wrapper on top of :func:`cli.scan_config`."""
if callable(config_dir):
config_dir = config_dir()

Expand All @@ -90,11 +93,11 @@ def resolve_config_argument(ctx, param, value, config_dir=None):
ctx.exit()

if isinstance(value, string_types):
value = resolve_config(value, config_dir=config_dir)
value = scan_config(value, config_dir=config_dir)

elif isinstance(value, tuple):
value = tuple(
[resolve_config(v, config_dir=config_dir) for v in value])
[scan_config(v, config_dir=config_dir) for v in value])

return value

Expand All @@ -120,7 +123,7 @@ def _resolve_path_no_overwrite(config):
return path


def resolve_config(config, config_dir=None):
def scan_config(config, config_dir=None):
"""Return the real config path or raise an exception.

:param config: config file, valid examples:
Expand Down Expand Up @@ -445,7 +448,7 @@ def command_freeze(session_name, socket_name, socket_path):
@cli.command(name='load', short_help='Load tmuxp workspaces.')
@click.pass_context
@click.argument('config', click.Path(exists=True), nargs=-1,
callback=resolve_config_argument)
callback=scan_config_argument)
@click.option('-S', 'socket_path', help='pass-through for tmux -L')
@click.option('-L', 'socket_name', help='pass-through for tmux -L')
@click.option('--yes', '-y', 'answer_yes', help='yes', is_flag=True)
Expand Down Expand Up @@ -576,7 +579,7 @@ def import_config(configfile, importfunc):
short_help='Convert and import a teamocil config.')
@click.argument(
'configfile', click.Path(exists=True), nargs=1,
callback=_create_resolve_config_argument(get_teamocil_dir)
callback=_create_scan_config_argument(get_teamocil_dir)
)
def command_import_teamocil(configfile):
"""Convert a teamocil config from CONFIGFILE to tmuxp format and import
Expand All @@ -590,7 +593,7 @@ def command_import_teamocil(configfile):
short_help='Convert and import a tmuxinator config.')
@click.argument(
'configfile', click.Path(exists=True), nargs=1,
callback=_create_resolve_config_argument(get_tmuxinator_dir)
callback=_create_scan_config_argument(get_tmuxinator_dir)
)
def command_import_tmuxinator(configfile):
"""Convert a tmuxinator config from CONFIGFILE to tmuxp format and import
Expand All @@ -600,7 +603,7 @@ def command_import_tmuxinator(configfile):

@cli.command(name='convert')
@click.argument('config', click.Path(exists=True), nargs=1,
callback=resolve_config_argument)
callback=scan_config_argument)
def command_convert(config):
"""Convert a tmuxp config between JSON and YAML."""

Expand Down