Skip to content

Commit

Permalink
load: Add --log-file, rename tmuxp --log_level to --log-level (#647)
Browse files Browse the repository at this point in the history
  • Loading branch information
tony committed Nov 22, 2020
2 parents 8858179 + 287fcc1 commit 21b4639
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 64 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ jobs:
run: |
curl -O -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py
python get-poetry.py -y --version 1.0.10
echo "::set-env name=PATH::$HOME/.poetry/bin:$PATH"
echo "PATH=${HOME}/.poetry/bin:${PATH}" >> $GITHUB_ENV
rm get-poetry.py
- name: Get poetry cache paths from config
run: |
echo ::set-env name=poetry_cache_dir::$(poetry config --list | sed -n 's/.*cache-dir = //p' | sed -e 's/^"//' -e 's/"$//')
echo ::set-env name=poetry_virtualenvs_path::$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^"//' -e 's/"$//')
echo "poetry_cache_dir=$(poetry config --list | sed -n 's/.*cache-dir = //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
- name: Configure poetry
shell: bash
Expand Down
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Here you can find the recent changes to tmuxp

current
-------
- Adding option to dump `load` output to log file
- *Insert changes/features/fixes for next release here*

tmuxp 1.6.2 (2020-11-08)
Expand Down
10 changes: 9 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,16 @@ You can auto confirm the prompt. In this case no preview will be shown.
$ tmuxp convert --yes filename
Debug Info
Debugging Helpers
----------
The `load` command provides a way to log output to a log file for debugging
purposes.
.. code-block:: sh
$ tmuxp load --log-file <log-file-name> .
Collect system info to submit with a Github issue:
.. code-block:: sh
Expand All @@ -192,6 +199,7 @@ Collect system info to submit with a Github issue:
# ... so on
Docs / Reading material
-----------------------
Expand Down
13 changes: 12 additions & 1 deletion docs/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,23 @@ are created, the last session is named from the terminal.
$ tmxup load -s <new_session_name> <filename1> ...
The output of the ``load`` command can be logged to a file for
debugging purposes. the log level can be controlled with the global
``--log-level`` option (defaults to INFO).

.. code-block:: bash
$ tmuxp load <filename> --log-file <log_filename>
$ tmuxp --log-level <LEVEL> load <filename> --log-file <log_filename>
.. _cli_debug_info:

Debug Info
----------

Use to collect all relevant information for submitting an issue to the project.
Use to collect all relevant information for submitting an issue to
the project.

.. code-block:: bash
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ skip-string-normalization = true

[tool.poetry]
name = "tmuxp"
version = "1.6.2"
version = "1.6.3"
description = "tmux session manager"
license = "MIT"
authors = ["Tony Narlock <tony@git-pull.com>"]
Expand Down
27 changes: 27 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,33 @@ def test_load_zsh_autotitle_warning(cli_args, tmpdir, monkeypatch):
assert 'Please set' not in result.output


@pytest.mark.parametrize(
"cli_args",
[
(['load', '.', '--log-file', 'log.txt']),
],
)
def test_load_log_file(cli_args, tmpdir, monkeypatch):
# create dummy tmuxp yaml that breaks to prevent actually loading tmux
tmpdir.join('.tmuxp.yaml').write(
"""
session_name: hello
"""
)
tmpdir.join('.oh-my-zsh').ensure(dir=True)
monkeypatch.setenv('HOME', str(tmpdir))

with tmpdir.as_cwd():
print('tmpdir: {0}'.format(tmpdir))
runner = CliRunner()

# If autoconfirm (-y) no need to prompt y
input_args = 'y\ny\n' if '-y' not in cli_args else ''

runner.invoke(cli.cli, cli_args, input=input_args)
assert 'Loading' in tmpdir.join('log.txt').open().read()


@pytest.mark.parametrize("cli_cmd", ['shell', ('shell', '--pdb')])
@pytest.mark.parametrize(
"cli_args,inputs,env,expected_output",
Expand Down
2 changes: 1 addition & 1 deletion tmuxp/__about__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__title__ = 'tmuxp'
__package_name__ = 'tmuxp'
__version__ = '1.6.2'
__version__ = '1.6.3'
__description__ = 'tmux session manager'
__email__ = 'tony@git-pull.com'
__author__ = 'Tony Narlock'
Expand Down
79 changes: 50 additions & 29 deletions tmuxp/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ def get_cwd():
return os.getcwd()


def tmuxp_echo(message=None, log_level='INFO', style_log=False, **click_kwargs):
"""
Combines logging.log and click.echo
"""
if style_log:
logger.log(log.LOG_LEVELS[log_level], message)
else:
logger.log(log.LOG_LEVELS[log_level], click.unstyle(message))

click.echo(message, **click_kwargs)


def get_config_dir():
"""
Return tmuxp configuration directory.
Expand Down Expand Up @@ -246,8 +258,8 @@ def scan_config_argument(ctx, param, value, config_dir=None):
config_dir = config_dir()

if not config:
click.echo("Enter at least one CONFIG")
click.echo(ctx.get_help(), color=ctx.color)
tmuxp_echo("Enter at least one CONFIG")
tmuxp_echo(ctx.get_help(), color=ctx.color)
ctx.exit()

if isinstance(value, string_types):
Expand Down Expand Up @@ -357,11 +369,14 @@ def scan_config(config, config_dir=None):
]

if len(candidates) > 1:
click.secho(
'Multiple .tmuxp.{yml,yaml,json} configs in %s' % dirname(config),
fg="red",
tmuxp_echo(
click.style(
'Multiple .tmuxp.{yml,yaml,json} configs in %s'
% dirname(config),
fg="red",
)
)
click.echo(
tmuxp_echo(
click.wrap_text(
'This is undefined behavior, use only one. '
'Use file names e.g. myproject.json, coolproject.yaml. '
Expand Down Expand Up @@ -505,6 +520,11 @@ def load_workspace(
# get the canonical path, eliminating any symlinks
config_file = os.path.realpath(config_file)

tmuxp_echo(
click.style('[Loading] ', fg='green')
+ click.style(config_file, fg='blue', bold=True)
)

# kaptan allows us to open a yaml or json file as a dict
sconfig = kaptan.Kaptan()
sconfig = sconfig.import_config(config_file).get()
Expand All @@ -525,7 +545,7 @@ def load_workspace(
try: # load WorkspaceBuilder object for tmuxp config / tmux server
builder = WorkspaceBuilder(sconf=sconfig, server=t)
except exc.EmptyConfigException:
click.echo('%s is empty or parsed no config data' % config_file, err=True)
tmuxp_echo('%s is empty or parsed no config data' % config_file, err=True)
return

session_name = sconfig['session_name']
Expand All @@ -545,11 +565,6 @@ def load_workspace(
return

try:
click.echo(
click.style('[Loading] ', fg='green')
+ click.style(config_file, fg='blue', bold=True)
)

builder.build() # load tmux session via workspace builder

if 'TMUX' in os.environ: # tmuxp ran from inside tmux
Expand Down Expand Up @@ -586,8 +601,8 @@ def load_workspace(
except exc.TmuxpException as e:
import traceback

click.echo(traceback.format_exc(), err=True)
click.echo(e, err=True)
tmuxp_echo(traceback.format_exc(), err=True)
tmuxp_echo(e, err=True)

choice = click.prompt(
'Error loading workspace. (k)ill, (a)ttach, (d)etach?',
Expand All @@ -597,7 +612,7 @@ def load_workspace(

if choice == 'k':
builder.session.kill_session()
click.echo('Session killed.')
tmuxp_echo('Session killed.')
elif choice == 'a':
if 'TMUX' in os.environ:
builder.session.switch_client()
Expand All @@ -612,7 +627,7 @@ def load_workspace(
@click.group(context_settings={'obj': {}})
@click.version_option(__version__, '-V', '--version', message='%(prog)s %(version)s')
@click.option(
'--log_level',
'--log-level',
default='INFO',
help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)',
)
Expand All @@ -625,12 +640,12 @@ def cli(log_level):
try:
has_minimum_version()
except TmuxCommandNotFound:
click.echo('tmux not found. tmuxp requires you install tmux first.')
tmuxp_echo('tmux not found. tmuxp requires you install tmux first.')
sys.exit()
except exc.TmuxpException as e:
click.echo(e, err=True)
tmuxp_echo(e, err=True)
sys.exit()
setup_logger(level=log_level.upper())
setup_logger(logger=logger, level=log_level.upper())


def setup_logger(logger=None, level='INFO'):
Expand All @@ -649,12 +664,12 @@ def setup_logger(logger=None, level='INFO'):
logger = logging.getLogger()

if not logger.handlers: # setup logger handlers
channel = logging.StreamHandler()
channel.setFormatter(log.DebugLogFormatter())

# channel = logging.StreamHandler()
# channel.setFormatter(log.DebugLogFormatter())
# channel.setFormatter(log.LogFormatter())

logger.setLevel(level)
logger.addHandler(channel)
# logger.addHandler(channel)


def startup(config_dir):
Expand Down Expand Up @@ -875,6 +890,7 @@ def command_freeze(session_name, socket_name, socket_path, force):
flag_value=88,
help='Like -2, but indicates that the terminal supports 88 colours.',
)
@click.option('--log-file', help='File to log errors/output to')
def command_load(
ctx,
config,
Expand All @@ -884,6 +900,7 @@ def command_load(
answer_yes,
detached,
colors,
log_file,
):
"""Load a tmux workspace from each CONFIG.
Expand All @@ -908,6 +925,10 @@ def command_load(
detached mode.
"""
util.oh_my_zsh_auto_title()
if log_file:
logfile_handler = logging.FileHandler(log_file)
logfile_handler.setFormatter(log.LogFormatter())
logger.addHandler(logfile_handler)

tmux_options = {
'socket_name': socket_name,
Expand All @@ -919,8 +940,8 @@ def command_load(
}

if not config:
click.echo("Enter at least one CONFIG")
click.echo(ctx.get_help(), color=ctx.color)
tmuxp_echo("Enter at least one CONFIG")
tmuxp_echo(ctx.get_help(), color=ctx.color)
ctx.exit()

if isinstance(config, string_types):
Expand Down Expand Up @@ -962,7 +983,7 @@ def import_config(configfile, importfunc):
else:
sys.exit('Unknown config format.')

click.echo(
tmuxp_echo(
newconfig + '---------------------------------------------------------------'
'\n'
'Configuration import does its best to convert files.\n'
Expand All @@ -984,9 +1005,9 @@ def import_config(configfile, importfunc):
buf.write(newconfig)
buf.close()

click.echo('Saved to %s.' % dest)
tmuxp_echo('Saved to %s.' % dest)
else:
click.echo(
tmuxp_echo(
'tmuxp has examples in JSON and YAML format at '
'<http://tmuxp.git-pull.com/examples.html>\n'
'View tmuxp docs at <http://tmuxp.git-pull.com/>'
Expand Down Expand Up @@ -1125,4 +1146,4 @@ def format_tmux_resp(std_resp):
% format_tmux_resp(tmux_cmd('show-window-options', '-g')),
]

click.echo('\n'.join(output))
tmuxp_echo('\n'.join(output))

0 comments on commit 21b4639

Please sign in to comment.