papis / papis

Powerful and highly extensible command-line based document and bibliography manager.

Home Page:http://papis.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

papis init: First-time usage is fragile and confusing

hseg opened this issue · comments

  • papis version ($ papis --version or commit number): 0.13

how to reproduce the issue

Command and output of papis --log INFO <command>:
If ~/Documents/papers and $XDG_CONFIG_HOME/papis/ don't exist:
(context for below: on my system, $XDG_CONFIG_HOME=~/.local/etc/)

No sections were found in the configuration file. Adding default ones (with a default library named 'papers')!
Traceback (most recent call last):
  File "/usr/bin/papis", line 33, in <module>
    sys.exit(load_entry_point('papis==0.13', 'console_scripts', 'papis')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1685, in invoke
    super().invoke(ctx)
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/papis/commands/default.py", line 224, in run
    raise RuntimeError(
RuntimeError: Library 'papers' does not have any existing folders attached to it. Please define and create the paths in the configuration file

If ~/Documents/papers/ exists:

Creating configuration folder in '/home/gesh/.local/etc/papis'.
Creating scripts folder in '/home/gesh/.local/etc/papis/scripts'
No sections were found in the configuration file. Adding default ones (with a default library named 'papers')!
[WARNING] commands.init: Config file '/home/gesh/.local/etc/papis/config' already exists!
[WARNING] commands.init: This command may change some of its contents, e.g. whitespace and comments are not preserved.

In addition, trying to tab-complete to papis init has papis checking for a config file, failing, and emitting

Creating configuration folder in '/home/gesh/.local/etc/papis'.
Creating scripts folder in '/home/gesh/.local/etc/papis/scripts'
No sections were found in the configuration file. Adding default ones (with a default library named 'papers')!

This is unnecessarily brittle. A better flow could be:

  • Tab-completion without a valid config file completes statically-knowable commands only (eg command-line arguments, builtin subcommands, etc)
  • papis init, if it notices no libraries have been configured so far, prompts for a path to a first library, and offers to set it at default
  • Under no circumstances should the flow of papis init create the config file before its check for the existence of a config file -- that's confusing and defeats the purpose of such a check.

I was just looking at this a bit and it seems to be pretty complicated to fix in a satisfying manner.

One thing to note is that papis init is meant to initialize a new library, so it kind of assumes that you have a configuration file already. However, all those errors are horrible and should definitely be better 😢

To address the suggestions a bit for future reference:

Tab-completion without a valid config file completes statically-knowable commands only (eg command-line arguments, builtin subcommands, etc)

We rely on click for the shell tab completion as described here. From what I can tell, the completion suggestions are generated dynamically by actually calling the Papis command and it's not exactly easy to customize that without rewriting it ourselves..

papis init, if it notices no libraries have been configured so far, prompts for a path to a first library, and offers to set it at default

It actually does that already over here

logger.info("Setting library location.")
dir_path = os.getcwd() if dir_path is None else dir_path
library_name = papis.tui.utils.prompt(
"Name of the library",
default=os.path.basename(dir_path),
bottom_toolbar="Known libraries: '{}'".format(
"', '".join(papis.config.get_libs())))

The issue is that the configuration file is read before that when constructing the command-line subcommands and things, so this check is already too late if no configuration file exists.

Under no circumstances should the flow of papis init create the config file before its check for the existence of a config file -- that's confusing and defeats the purpose of such a check.

This is again due to the check for the configuration happening outside of papis init.

@hseg #741 should be an improvement in this direction. Can you test if it works for you?

commented

OK, so testing:

$ papis Error while loading entrypoint 'EntryPoint(name='isbn',
value='papis.isbn:Importer', group='papis.importer')': The 'arxiv>=1.0.0'
distribution was not found and is required by papis.
Error while loading entrypoint 'EntryPoint(name='isbn',
value='papis.isbn:explorer', group='papis.explorer')': The 'arxiv>=1.0.0'
distribution was not found and is required by papis.
add browse config exec git merge rename serve
addto cache doctor explore init mv rm update
bibtex citations edit export list open run

The problem of papis creating the config directory, then warning that it might
overwrite the config it's already created still persists:

$ echo "$XDG_CONFIG_HOME"
/home/gesh/.local/etc
$ rm -r ~/.local/etc/papis/
$ papis init
Creating configuration folder in '/home/gesh/.local/etc/papis'.
Creating scripts folder in '/home/gesh/.local/etc/papis/scripts'
No sections were found in the configuration file. Adding default ones (with a default library named 'papers')!
Error while loading entrypoint 'EntryPoint(name='isbn', value='papis.isbn:Importer', group='papis.importer')': The 'arxiv>=1.0.0' distribution was not found and is required by papis.
Error while loading entrypoint 'EntryPoint(name='isbn', value='papis.isbn:explorer', group='papis.explorer')': The 'arxiv>=1.0.0' distribution was not found and is required by papis.
[ERROR] commands.default: Library 'papers' does not have any existing folders attached to it. Please define and create the paths in the configuration file.
[WARNING] commands.init: Config file '/home/gesh/.local/etc/papis/config' already exists!
[WARNING] commands.init: This command may change some of its contents, e.g. whitespace and comments are not preserved.
Do you want to continue? (Y/n): n

(Though the soft-fail works here, thanks! It no longer looks as scary and unexpected as it did before)

The error message could be improved, perhaps to

Library '{lib}' has the following nonexistent folders attached to it.
Please create them, or reconfigure '{lib}':
{dir1}
...


In re your remarks on the design, perhaps have the documentation suggest

papis config --edit

as an initial setup command, a la git?

In re click needing a valid papis configuration to be able to do anything,
perhaps the above suggestion could be a special case?
That is, at the top of the completion code, test if a valid configuration
exists. If so, pass control of completion to click.
Otherwise, complete to the above papis config --edit, perhaps even to

papis config --edit # NOTE: Full completion needs a valid configuration

The problem of papis creating the config directory, then warning that it might overwrite the config it's already created still persists:

Gave this another go and silenced all the duplicate / conflicting messages in there. Let me know if you spot anything that remains!

The error message could be improved, perhaps to

Improved this a bit. That message wasn't showing up correctly anyway. It was mostly meant for the case where you have a configuration file but the library you're trying to use is incorrectly set up.

I updated #741 with some more cleanup and the messages if there's no config look pretty reasonable to me. When calling any papis command (besides init), it will say

>> papis list --help
[WARNING] commands.default: No configuration file exists at '/mnt/data/code/projects/papis/papis/local-init-tmp/papis/config'.
[WARNING] commands.default: Create a configuration file and define your libraries before using papis. You can use 'papis init /path/to/my/library' for a quick interactive setup.

and when calling init it will just ask the questions

>> papis init
[INFO] commands.init: Initializing a new config file: '/mnt/data/code/projects/papis/papis/local-init-tmp/papis/config'.
[INFO] commands.init: Setting library location:
Name of the library (papis):

In re click needing a valid papis configuration to be able to do anything,

I think this should work now. The click generated completion was mostly broken in that case because it kept raising exceptions when the configuration file wasn't there. With the modifications from #741, it should be nicer, but it may show some extra messages.

@hseg It would be very helpful if you could test the new version too! Thanks a lot for helping to make this more user friendly ❤️