diff --git a/bin/is b/bin/is index c85f920b7d1cfdef0fc471a1563862257ce32044..de3e46fcbd00fa58a68b8039bc7b56b260a7804a 100755 --- a/bin/is +++ b/bin/is @@ -251,20 +251,11 @@ def c_list(parser, args): ''' List images in repository or image content ''' - # List available repositories repoman = load_repositories(args) - if len(args.object) == 0: - arrow("Repositories") - repoman.show('*', url=args.verbose) - else: - for o in args.object: - repos = fnmatch.filter(repoman.onlines, o) - if len(repos) > 0: - for reponame in repos: - repoman[reponame].show(verbose=args.verbose, aspath=args.as_path) - else: - img, repo = select_image(o, repoman, args.best) - img.show(verbose=args.verbose, changelog=args.changelog) + for pattern in args.image: + repoman.show_images(pattern, o_long=args.long, o_json=args.json, + o_md5=args.md5, o_date=args.date, o_author=args.author, + o_size=args.size, o_url=args.url, o_description=args.description) def c_move(parser, args): ''' @@ -300,12 +291,9 @@ def c_repo(parser, args): ''' Get information about repositories ''' - # List available repositories repoman = load_repositories(args, force_offline=args.local) - # if len(args.repository) == 0: - # args.repository = ['*'] for pattern in args.repository: - repoman.show(pattern, online=not args.offline, + repoman.show_repos(pattern, online=not args.offline, offline=not args.online, url=args.verbose, state=not args.no_state) def c_search(parser, args): @@ -499,16 +487,24 @@ p_install.set_defaults(func=c_install, subparser=p_install) # list command parser p_list = subparsers.add_parser("list", help=c_list.__doc__.lower()) -p_list.add_argument("-v", "--verbose", action="store_true", default=False, - help="verbose output") -p_list.add_argument("-b", "--best", action="store_true", default=False, - help="in best mode, image is the most recent in all repositories") -p_list.add_argument("-c", "--changelog", action="store_true", default=False, - help="display image changelog") -p_list.add_argument("-p", "--as-path", action="store_true", default=False, - help="display repository content as path") -p_list.add_argument("object", nargs="*", - help="object syntax is <path|repository|[repository/]image[:version]>") +p_list.add_argument("-j", "--json", action="store_true", default=False, + help="long display") +p_list.add_argument("-l", "--long", action="store_true", default=False, + help="long display") +p_list.add_argument("-m", "--md5", action="store_true", default=False, + help="display image md5") +p_list.add_argument("-s", "--size", action="store_true", default=False, + help="display image size") +p_list.add_argument("-d", "--date", action="store_true", default=False, + help="display image date") +p_list.add_argument("-a", "--author", action="store_true", default=False, + help="display image author") +p_list.add_argument("-u", "--url", action="store_true", default=False, + help="display image url") +p_list.add_argument("-D", "--description", action="store_true", default=False, + help="display image description") +p_list.add_argument("image", nargs="*", default=['*'], + help="image syntax is [repository/]image[:version]") p_list.set_defaults(func=c_list, subparser=p_list) # move command parser diff --git a/completion/bash/is b/completion/bash/is index eb7f3326d8de6389f850229929f6bd499a481bc0..41a80207b9d9bc10f6e5362e95b05f1dbc46e20a 100644 --- a/completion/bash/is +++ b/completion/bash/is @@ -6,8 +6,19 @@ _repo() { } # list all images available in any online repositories +_remote_image() { + COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is -q --no-color list)" -- "$cur")) +} + +# list all local (files) images +_local_image() { + COMPREPLY=("${COMPREPLY[@]}" $(compgen -f -X '!*.isimage' -- "$cur")) +} + +# list local and remote images _image() { - COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is -q --no-color list -p '*')" -- "$cur") $(compgen -f -X '!*.isimage' -- "$cur")) + _local_image + _remote_image } # generate completion from optional arguments @@ -75,17 +86,17 @@ _is() { copy) [[ "$cur" == -* ]] && _opt '-h --help -b --best' && return 0 _count_args - (( args == 2 )) && _image - (( args > 2 )) && _image && _repo + (( args == 2 )) && _remote_image + (( args > 2 )) && _remote_image && _repo ;; del) [[ "$cur" == -* ]] && _opt '-h --help -b --best -f --force -p --preserve' && return 0 - _image + _remote_image ;; diff) [[ "$cur" == -* ]] && _opt '-h --help -b --best' && return 0 _count_args - (( args < 4 )) && c_args=$(images) + (( args < 4 )) && _image ;; extract) [[ "$cur" == -* ]] && _opt '-h --help -f --force -b --best -p --payload -g --gen-description' && return 0 @@ -95,7 +106,7 @@ _is() { ;; get) [[ "$cur" == -* ]] && _opt '-h --help -f --force -b --best --payload -I --no-image' && return 0 - _image + _remote_image ;; help) _count_args @@ -116,13 +127,12 @@ _is() { (( args > 2 )) && _filedir ;; list) - [[ "$cur" == -* ]] && _opt '-h --help -b --best --verbose -c --changelog -p --as-path' && return 0 - _repo - _image + [[ "$cur" == -* ]] && _opt '-h --help -l --long -j --json -m --md5 -s --size -d --date -a --author -u --url -D --description' && return 0 + _remote_image ;; move) [[ "$cur" == -* ]] && _opt '-h --help -b --best -f --force' && return 0 - _image + _remote_image ;; new) [[ "$cur" == -* ]] && _opt '-h --help -f --force' && return 0 diff --git a/installsystems/repository.py b/installsystems/repository.py index 92165ba40e59d7470b206f4f971c2efb6f662754..9b03981baa59cd76e40aa2f7510a2376add9ba5d 100644 --- a/installsystems/repository.py +++ b/installsystems/repository.py @@ -12,6 +12,7 @@ import time import shutil import pwd import grp +import json import tempfile import fnmatch import cStringIO @@ -320,37 +321,20 @@ class Repository(object): # update last file self.update_last() - def show(self, verbose=False, aspath=False): + def images(self): ''' - List images in repository + Return a dict of informations on images ''' - if aspath: - images = self.db.ask("SELECT md5, name, version FROM image ORDER BY name, version").fetchall() - for (image_md5, image_name, image_version) in images: - s = "#light##blue#%s#reset#/#light##yellow#%s#reset#:#light##red#%s#reset#" % ( - self.config.name, image_name, image_version) - if verbose: - s += " [%s]" % image_md5 - out(s) - else: - arrow(self.config.name) - images = self.db.ask("SELECT md5, name, version, date,\ + db_images = self.db.ask("SELECT md5, name, version, date,\ author, description, size FROM image ORDER BY name, version").fetchall() - for (image_md5, image_name, image_version, image_date, image_author, - image_description, image_size) in images: - out("#light##yellow#%s #reset#v%s" % (image_name, image_version)) - if verbose: - out(" #yellow#Date:#reset# %s" % istools.time_rfc2822(image_date)) - out(" #yellow#Description:#reset# %s" % image_description) - out(" #yellow#Author:#reset# %s" % image_author) - out(" #yellow#MD5:#reset# %s" % image_md5) - payloads = self.db.ask("SELECT md5, name, size FROM payload\ - WHERE image_md5 = ?", (image_md5,)).fetchall() - for payload_md5, payload_name, payload_size in payloads: - out(" #light##yellow#Payload:#reset# %s" % payload_name) - out(" #yellow#Size:#reset# %s" % (istools.human_size(payload_size))) - out(" #yellow#MD5:#reset# %s" % payload_md5) - out() + images = [] + field = ("md5", "name", "version", "date", "author", "description", "size") + for info in db_images: + d = dict(zip(field, info)) + d["repo"] = self.config.name + d["url"] = os.path.join(self.config.path, d["md5"]) + images.append(d) + return images def search(self, pattern): ''' @@ -631,7 +615,7 @@ class RepositoryManager(object): return repo.get(name, version), repo raise Exception("Unable to find image %s v%s" % (name, version)) - def show(self, pattern, online=True, offline=True, url=False, state=True): + def show_repos(self, pattern, online=True, offline=True, url=False, state=True): ''' Show repository inside manager online: list online repository @@ -651,6 +635,50 @@ class RepositoryManager(object): s += " #light##red#[offline]#reset#" out(s) + def show_images(self, pattern, o_json=False, o_long=False, + o_md5=False, o_date=False, o_author=False, o_size=False, + o_url=False, o_description=False): + ''' + Show repository inside manager + json: display output in json + long: display output in long format + all images parameter can be given in arguments to displayed + ''' + # building image list + images = {} + for reponame in self.onlines: + for img in self[reponame].images(): + imgname = u"%s/%s:%s" % (reponame, img["name"], img["version"]) + images[imgname] = img + # filter with pattern + for k in images.keys(): + if not fnmatch.fnmatch(k, pattern): + del images[k] + # display result + if o_json: + s = json.dumps(images) + else: + l = [] + for imgp in sorted(images.keys()): + img = images[imgp] + l.append(u"#light##blue#%s#reset#/#light#%s#reset#:#light##purple#%s#reset#" % ( + img["repo"], img["name"], img["version"])) + if o_md5 or o_long: + l.append(u" #light#md5:#reset# %s" % img["md5"]) + if o_date or o_long: + l.append(u" #light#date:#reset# %s" % istools.time_rfc2822(img["date"])) + if o_author or o_long: + l.append(u" #light#author:#reset# %s" % img["author"]) + if o_size or o_long: + l.append(u" #light#size:#reset# %s" % istools.human_size(img["size"])) + if o_url or o_long: + l.append(u" #light#url:#reset# %s" % img["url"]) + if o_description or o_long: + l.append(u" #light#description:#reset# %s" % img["description"]) + s = os.linesep.join(l) + if len(s) > 0: + out(s) + def search(self, pattern): ''' Search pattern accross all registered repositories