Skip to content

Add --log-file option to load command #647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 22, 2020
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
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 <[email protected]>"]
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__ = '[email protected]'
__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))
Loading