def _gcs_list(args, _):
  """ List the buckets or the contents of a bucket.

  This command is a bit different in that we allow wildchars in the bucket name and will list
  the buckets that match.
  """
  target = args['objects']
  project = args['project']
  if target is None:
    return _gcs_list_buckets(project, '*')  # List all buckets.

  bucket_name, key = google.datalab.storage._bucket.parse_name(target)
  if bucket_name is None:
    raise Exception('Cannot list %s; not a valid bucket name' % target)

  # If a target was specified, list keys inside it
  if target:
    if not re.search('\?|\*|\[', target):
      # If no wild characters are present in the key string, append a '/*' suffix to show all keys
      key = key.strip('/') + '/*' if key else '*'

    if project:
      # Only list if the bucket is in the project
      for bucket in google.datalab.storage.Buckets(_make_context(project)):
        if bucket.name == bucket_name:
          break
      else:
        raise Exception('%s does not exist in project %s' % (target, project))
    else:
      bucket = google.datalab.storage.Bucket(bucket_name)

    if bucket.exists():
      return _gcs_list_keys(bucket, key)
    else:
      raise Exception('Bucket %s does not exist' % target)

  else:
    # Treat the bucket name as a pattern and show matches. We don't use bucket_name as that
    # can strip off wildchars and so we need to strip off gs:// here.
    return _gcs_list_buckets(project, target.strip('/')[5:])
List the buckets or the contents of a bucket.

  This command is a bit different in that we allow wildchars in the bucket name and will list
  the buckets that match.