Skip to content
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

Provide support for ncc bash completion #1303

Closed
llucax opened this issue Jul 23, 2021 · 5 comments
Closed

Provide support for ncc bash completion #1303

llucax opened this issue Jul 23, 2021 · 5 comments
Assignees

Comments

@llucax
Copy link
Contributor

llucax commented Jul 23, 2021

Description

The ncc command should have a bash completion so it's easier to discover and auto-complete commands.

Example

ncc <TAB> should complete.

Necessary changes

There are 3 main necessary changes needed for this:

  1. Add the bash completion script itself, which can be done, sort of, as described here: https://docs.nextcloud.com/server/21/admin_manual/configuration_server/occ_command.html#enabling-autocompletion
  2. Adapt the generated bash script to nextcloudpi's ncc idiosyncrasies.
  3. Adapt the /usr/local/bin/ncc command so sudo forwards (at least) these three environment variables: CMDLINE_CONTENTS CMDLINE_CURSOR_INDEX and CMDLINE_WORDBREAKS

The generated script by 1 seems pretty static and can probably generate once at install time and maybe, just in case, each time the nextcloud instance is updated. Step 2 can also be automated (to some degree, as if the generated script changes too much the update can fail). I'm doing this in the current version to adapt it:

ncc _completion --generate-hook --shell-type bash \
        | sed -e 's/occ/ncc/g' -e 's|/var/www/nextcloud/|/usr/local/bin/|' \
        > ~/.local/share/bash-completion/completions/ncc

(for a system install ~/.local/share/bash-completion/completions/ncc can be replaced with /usr/share/bash-completion/completions for example)

Step 3 can be easily done by adding --preserve-env=CMDLINE_CONTENTS,CMDLINE_CURSOR_INDEX,CMDLINE_WORDBREAKS to /usr/local/bin/ncc.

@nachoparker
Copy link
Member

this is cool, please provide a PR

@llucax
Copy link
Contributor Author

llucax commented Jul 24, 2021

Thanks! Thinking a bit more about it, I think this solution is quite dirty and weak, as the generated completion file needs to be changed, if what's generated is changed, it could easily break. There is actually another option to occ _completion that can be used to improve the situation: --program=ncc can avoid some of the steps, but then there is /var/www/nextcloud/occ used because this is the script that is actually invoked at the end, but this script is not executable (is run through php by ncc). To fix this, the script needs to be executable, but doing so for a file in /var/www seems quite risky. Even when there are mechanisms to avoid the execution, a misconfiguration could leave the server completely vulnerable.

To fix this one option would to make a copy of the occ script somewhere else and make that executable, but again, even when occ is just a require_once line, it might break if this changes in the future.

I don't see any solution elegant enough to be comfortable to send a PR. I guess the only elegant solution would be to add an option to occ _completion to override what command to use internally to generate the completion (overriding the hardcoded use of the invoking script as that command, so we can specify ncc instead, something like ncc _completion -p ncc --override-command=/usr/local/bin/ncc ...). But this could take ages to get merged, used by NC and then finally by NCP.

Anyway, I'd be glad to hear opinions about the trade-offs and what to do about this.

@theCalcaholic
Copy link
Collaborator

I think, something like ncc _completion -g --shell-type bash -p ncc | sed 's|/var/www/nextcloud/occ|ncc|g' would be stable enough to use, since ncc should always be valid replacement for /var/www/nextcloud/occ

The above command results in:

function _ncc_9cbb1906d0cf7a74_complete {


    local CMDLINE_CONTENTS="$COMP_LINE";
    local CMDLINE_CURSOR_INDEX="$COMP_POINT";
    local CMDLINE_WORDBREAKS="$COMP_WORDBREAKS";

    export CMDLINE_CONTENTS CMDLINE_CURSOR_INDEX CMDLINE_WORDBREAKS;

    local RESULT STATUS;

    local IFS=$'\n';

    RESULT="$(ncc _completion --shell-type bash </dev/null)";
    STATUS=$?;

    local cur mail_check_backup;

    mail_check_backup=$MAILCHECK;
    MAILCHECK=-1;

    _get_comp_words_by_ref -n : cur;


    if [ $STATUS -eq 200 ]; then

        compopt -o default;
        return 0;

    elif [ $STATUS -ne 0 ]; then
        echo -e "$RESULT";
        return $?;
    fi;

    COMPREPLY=(`compgen -W "$RESULT" -- $cur`);

    __ltrim_colon_completions "$cur";

    MAILCHECK=mail_check_backup;
};

if [ "$(type -t _get_comp_words_by_ref)" == "function" ]; then
    complete -F _ncc_9cbb1906d0cf7a74_complete "ncc";
else
    >&2 echo "Completion was not registered for ncc:";
    >&2 echo "The 'bash-completion' package is required but doesn't appear to be installed.";
fi;

@nachoparker nachoparker self-assigned this Sep 30, 2021
@nachoparker
Copy link
Member

this seems to work pretty well :)

c037c11

thanks

@RonaldBarnes
Copy link

Just stumbled on this issue page.

I don't know if this PR for nextcloud/server will help anyone trying to get simple bash tab completion working:

nextcloud/server#35451

Two bash scripts:

  • one to generate an alias and optionally make it persistent
  • one to do the completion processing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants