Skip to content

Commit

Permalink
Merge pull request #19 from timsschoen/master
Browse files Browse the repository at this point in the history
Adding autocompletion for commands and while installing packages
  • Loading branch information
sreiter authored Sep 3, 2020
2 parents 14d79f4 + a1dece4 commit 0a7d9fb
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 26 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ If you choose to edit your PATH variable, please make sure to reload your .bash_

source $HOME/.bash_profile

If you are interested in using auto-completion (in bash) while using ughub, add the following additional line to your $HOME/.bash_profile or $HOME/.bashrc file

source $HOME/ughub/autocompletions/ughub-completion.bash

and reload the file. Alternatively, you can place this line in '\~/.bash_completion'.
To use this in zsh, you need to use bashcompinit, see [here](https://stackoverflow.com/a/8492043).
Autocomplete is also availabl for fish. To use this, copy 'autocompletions/ughub-completion.fish' to '\~/.config/fish/completions/ughub.fish' (and reload your fish instance).

## Installing ughub (Windows)
ughub should run out of the box on Windows too. However, in order to execute it from any path, you should add

Expand All @@ -99,6 +107,19 @@ in your shell. This opens the _System Properties_ dialog and highlights the _Adv

When you're done, press 'OK' to close the dialog. Make sure to restart your Shell in order to apply the changes.

Autocompletion on windows only works in powershell. To use it, add the line

C:\Users\YOURNAME\ughub\autocompletions\ughub-completion.ps1

to the file (you might need to create it)

C:\Users\YOURNAME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

If you wish to use it, you need to [allow powershell scripts to execute](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7). Execute the following in an PowerShell session executed as Administrator:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted

Take a look at [this](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7#profiles-and-execution-policy) to learn about powershell profiles and execution policy.

# First steps
ughub serves as a package management tool for the UG4 simulation framework. Use the following command to get some help on ughub's usage:
Expand Down
8 changes: 8 additions & 0 deletions autocompletions/ughub-completion.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#/usr/bin/env bash
_ughub_completions()
{
local suggestions=$(ughub getcompletions ${COMP_WORDS[@]:1})
COMPREPLY=($(compgen -W "${suggestions[@]}" -- "${COMP_WORDS[-1]}"))
}

complete -F _ughub_completions ughub
13 changes: 13 additions & 0 deletions autocompletions/ughub-completion.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function __fish_ughub_packages
ughub list --namesonly
end

function __fish_ughub_installed_packages
ughub list --namesonly --installed
end

set -l ughub_commands (ughub help --commands)
for c in {$ughub_commands}
complete -f -c ughub -n "not __fish_seen_subcommand_from $ughub_commands" -a $c -d (ughub help $c --short)
complete -f -c ughub -n "__fish_seen_subcommand_from $c" -a "(ughub getcompletions $c)"
end
13 changes: 13 additions & 0 deletions autocompletions/ughub-completion.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$scriptblock = {
param($wordToComplete, $commandAst, $cursorPosition)

$tokens = $commandAst.Extent.Text.Trim() -split ' '
$first, $rest = $tokens
$completions = &"ughub" getcompletions $rest

$completions | Where-Object {$_ -like "${wordToComplete}*"} | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}

Register-ArgumentCompleter -Native -CommandName ughub -ScriptBlock $scriptblock
72 changes: 62 additions & 10 deletions ughub.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,14 +445,22 @@ def ListPackages(args):
for pkg in packages:
packageDict[pkg["name"]] = packageDict.get(pkg["name"], []) + [pkg]

print("{0:24.4} {1:10} {2:11} {3:}"
.format("NAME", "PREFIX", "SOURCE", "URL"))
namesonly = ughubUtil.HasCommandlineOption(args, ("--namesonly",))

for key in sorted(packageDict.keys()):
pkgs = packageDict[key]
for pkg in pkgs:
print("{0:24} {1:10} {2:11} {3:}"
.format(pkg["name"], pkg["prefix"], pkg["__SOURCE"], pkg["url"]))
if namesonly:
for key in sorted(packageDict.keys()):
pkgs = packageDict[key]
for pkg in pkgs:
print(pkg["name"], end=" ")
else:
print("{0:24.4} {1:10} {2:11} {3:}"
.format("NAME", "PREFIX", "SOURCE", "URL"))

for key in sorted(packageDict.keys()):
pkgs = packageDict[key]
for pkg in pkgs:
print("{0:24} {1:10} {2:11} {3:}"
.format(pkg["name"], pkg["prefix"], pkg["__SOURCE"], pkg["url"]))

except LookupError as e:
raise InvalidPackageError(e)
Expand Down Expand Up @@ -949,7 +957,47 @@ def GenerateProjectFiles(args):
else:
ughubProjectFileGenerator.Run(GetRootDirectory(), args[0], name, overwriteFiles)

def GetAutoCompletions(args):

if len(args) >= 1 and args[0] == "install":
try:
packages = LoadPackageDescs()
except:
return
result = ughubHelp.GetOptionStringsForCommand("install")
result += "\n"
for p in packages:
result += p["name"] + "\n"
print(result[:-1], end="")
return

if len(args) >= 1 and args[0] == "log":
try:
packages = LoadPackageDescs()
except:
return
result = ughubHelp.GetOptionStringsForCommand("log")
result += "\n"
for p in packages:
if PackageIsInstalled(p):
result += p["name"] + "\n"
print(result[:-1], end="")
return

if len(args) >= 1 and args[0] == "help":
ughubHelp.PrintCommandNames()
print("\n" + ughubHelp.GetOptionStringsForCommand(args[0]), end="")
return

if len(args) >= 1 and ughubHelp.IsCommandInHelp(args[0]):
print(ughubHelp.GetOptionStringsForCommand(args[0]), end="")
return

if len(args) == 1:
ughubHelp.PrintCommandNames()
return


def RunUGHub(args):

exitCode = 1
Expand All @@ -972,11 +1020,12 @@ def RunUGHub(args):
AddSource(args[1:])

elif cmd == "help":
print("")
if len(args) == 1:
ughubHelp.PrintHelp()
elif args[1] == "--commands":
ughubHelp.PrintCommandNames()
else:
ughubHelp.PrintCommandHelp(args[1])
ughubHelp.PrintCommandHelp(args[1], args[2:])

elif cmd == "genprojectfiles":
GenerateProjectFiles(args[1:])
Expand Down Expand Up @@ -1030,7 +1079,10 @@ def RunUGHub(args):
print("ughub, version {}".format(g_ughubVersionString))
print("Copyright 2015 G-CSC, Goethe University Frankfurt")
print("All rights reserved")


elif cmd == "getcompletions":
GetAutoCompletions(args[1:])

else:
print("Unknown command: '{0}'".format(cmd))
ughubHelp.PrintUsage()
Expand Down
93 changes: 80 additions & 13 deletions ughubHelp.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ def GetCommandsInHelp():

return out

def IsCommandInHelp(command):
try:
d = GetHelpEntry("commands")
if type(d) == list:
for e in d:
name = e["name"]
if type(name) == str and name == command:
return True
elif type(name) == list and command in name:
return True
else:
raise MalformedHelpContentsError("'commands' entry has to be a list")
except ughubUtil.NestedTableEntryNotFoundError as e:
raise MalformedHelpContentsError("'commands' list required in help contents")
return False

def PrintUsage():
try:
Expand All @@ -69,33 +84,85 @@ def PrintCommands():
for cmd in GetCommandsInHelp():
print(" {0}".format(cmd))

def PrintCommandNames():
result = ""
for cmd in GetCommandsInHelp():
for c in cmd.split(","):
result += c.strip() + "\n"
print(result[:-1], end ="")

# Prints help for the command specified in 'cmd'.
def PrintCommandHelp(cmdName):
def PrintCommandHelp(cmdName, args=[]):

shortdesc = ughubUtil.HasCommandlineOption(args, ("--short",))

try:
cmdDict = GetHelpEntry("commands.{0}".format(cmdName))
print("Usage: ughub {0}".format(cmdDict["usage"]))
print("")
for line in cmdDict["description"].splitlines():
print(" {0}".format(line))

except ughubUtil.NestedTableEntryNotFoundError:
raise MalformedHelpContentsError("Requested command '{0}' not found in help database"
.format(cmdName))

if shortdesc:
if "shortdescription" in cmdDict:
print(cmdDict["shortdescription"], end="")
return

print("Usage: ughub {0}".format(cmdDict["usage"]))
print("")
for line in cmdDict["description"].splitlines():
print(" {0}".format(line))

try:
options = ughubUtil.GetFromNestedTable(cmdDict, "options")
except ughubUtil.NestedTableEntryNotFoundError:
return

print("")
print("Valid options:")
for opt in options:
name = opt["name"]
sep = ":"
for line in opt["description"].splitlines():
print(" {0:20}{1} {2}".format(name, sep, line))
name = ""
sep = " "




def GetOptionStringsForCommand(cmdName):
result = ""
try:
cmdDict = GetHelpEntry("commands.{0}".format(cmdName))

try:
options = ughubUtil.GetFromNestedTable(cmdDict, "options")
print("")
print("Valid options:")

for opt in options:
name = opt["name"]
sep = ":"
for line in opt["description"].splitlines():
print(" {0:20}{1} {2}".format(name, sep, line))
name = ""
sep = " "
optionstrings = opt["name"]

# filter out [ ]
optionstrings = optionstrings.replace("[", "").replace("]", "")

# split
optionstrings = optionstrings.split(" ")

# which of those start with - or --?
optionstrings = list(filter(lambda s: s.startswith('-') or s.startswith('--'), optionstrings))

for s in optionstrings:
result += s + "\n"

except ughubUtil.NestedTableEntryNotFoundError:
pass

except ughubUtil.NestedTableEntryNotFoundError:
raise MalformedHelpContentsError("Requested command '{0}' not found in help database"
.format(cmdName))

return result[:-1]

# Prints help on how to use the help command and a list of all available commands
def PrintHelp():
PrintCommandHelp("help")
Expand Down
Loading

0 comments on commit 0a7d9fb

Please sign in to comment.