Hello community,

here is the log from the commit of package azure-cli-extension for 
openSUSE:Factory checked in at 2019-05-22 11:00:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/azure-cli-extension (Old)
 and      /work/SRC/openSUSE:Factory/.azure-cli-extension.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "azure-cli-extension"

Wed May 22 11:00:05 2019 rev:5 rq:696835 version:0.2.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/azure-cli-extension/azure-cli-extension.changes  
2018-10-15 10:48:06.691090754 +0200
+++ 
/work/SRC/openSUSE:Factory/.azure-cli-extension.new.5148/azure-cli-extension.changes
        2019-05-22 11:00:08.126758252 +0200
@@ -1,0 +2,15 @@
+Tue Apr 16 14:46:24 UTC 2019 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- New upstream release
+  + Version 0.2.3
+  + For detailed information about changes see the
+    HISTORY.txt file provided with this package
+- Bump minimum version for Python Azure SDK namespace
+  packages to 3.0.0 in BuildRequires and Requires
+- Remove python3-devel package from BuildRequires
+- Remove unzip package from BuildRequires
+- Run fdupes to hardlink duplicate files
+  + Add fdupes to BuildRequires
+  + Add %fdupes invocation to %install
+
+-------------------------------------------------------------------

Old:
----
  azure-cli-extension-0.2.1.tar.gz

New:
----
  azure-cli-extension-0.2.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ azure-cli-extension.spec ++++++
--- /var/tmp/diff_new_pack.iFoYzu/_old  2019-05-22 11:00:09.842756030 +0200
+++ /var/tmp/diff_new_pack.iFoYzu/_new  2019-05-22 11:00:09.882755978 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package azure-cli-extension
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           azure-cli-extension
-Version:        0.2.1
+Version:        0.2.3
 Release:        0
 Summary:        Microsoft Azure CLI 'extension' Command Module
 License:        MIT
@@ -27,14 +27,13 @@
 Source1:        LICENSE.txt
 BuildRequires:  azure-cli-command-modules-nspkg
 BuildRequires:  azure-cli-nspkg
-BuildRequires:  python3-azure-nspkg
-BuildRequires:  python3-devel
+BuildRequires:  fdupes
+BuildRequires:  python3-azure-nspkg >= 3.0.0
 BuildRequires:  python3-setuptools
-BuildRequires:  unzip
 Requires:       azure-cli-command-modules-nspkg
 Requires:       azure-cli-core
 Requires:       azure-cli-nspkg
-Requires:       python3-azure-nspkg
+Requires:       python3-azure-nspkg >= 3.0.0
 Requires:       python3-pip
 Requires:       python3-wheel >= 0.30.0
 Conflicts:      azure-cli < 2.0.0
@@ -56,6 +55,7 @@
 
 %install
 python3 setup.py install --root=%{buildroot} --prefix=%{_prefix} 
--install-lib=%{python3_sitelib}
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 rm -rf %{buildroot}%{python3_sitelib}/azure/cli/command_modules/__init__.*
 rm -rf %{buildroot}%{python3_sitelib}/azure/cli/command_modules/__pycache__
 rm -rf %{buildroot}%{python3_sitelib}/azure/cli/__init__.*

++++++ azure-cli-extension-0.2.1.tar.gz -> azure-cli-extension-0.2.3.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-extension-0.2.1/HISTORY.rst 
new/azure-cli-extension-0.2.3/HISTORY.rst
--- old/azure-cli-extension-0.2.1/HISTORY.rst   2018-07-26 19:30:50.000000000 
+0200
+++ new/azure-cli-extension-0.2.3/HISTORY.rst   2018-11-01 23:22:37.000000000 
+0100
@@ -3,6 +3,14 @@
 Release History
 ===============
 
+0.2.3
++++++
+* Minor fixes.
+
+0.2.2
++++++
+* Attempting to add an extension that is already installed will not raise an 
exception.
+
 0.2.1
 +++++
 * Fix index url failing requests.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-extension-0.2.1/PKG-INFO 
new/azure-cli-extension-0.2.3/PKG-INFO
--- old/azure-cli-extension-0.2.1/PKG-INFO      2018-07-26 19:31:58.000000000 
+0200
+++ new/azure-cli-extension-0.2.3/PKG-INFO      2018-11-01 23:22:54.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: azure-cli-extension
-Version: 0.2.1
+Version: 0.2.3
 Summary: Microsoft Azure Command-Line Tools Extension Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
@@ -20,6 +20,14 @@
         Release History
         ===============
         
+        0.2.3
+        +++++
+        * Minor fixes.
+        
+        0.2.2
+        +++++
+        * Attempting to add an extension that is already installed will not 
raise an exception.
+        
         0.2.1
         +++++
         * Fix index url failing requests.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_completers.py
 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_completers.py
--- 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_completers.py
    2018-07-26 19:30:50.000000000 +0200
+++ 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_completers.py
    2018-11-01 23:22:37.000000000 +0100
@@ -6,7 +6,7 @@
 from azure.cli.core.decorators import Completer
 from azure.cli.core.extension import get_extension_names
 
-from azure.cli.command_modules.extension.custom import get_index_extensions
+from azure.cli.core.extension.operations import get_index_extensions
 
 
 @Completer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_homebrew_patch.py
 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_homebrew_patch.py
--- 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_homebrew_patch.py
        2018-07-26 19:30:50.000000000 +0200
+++ 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_homebrew_patch.py
        1970-01-01 01:00:00.000000000 +0100
@@ -1,50 +0,0 @@
-# 
--------------------------------------------------------------------------------------------
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License. See License.txt in the project root for 
license information.
-# 
--------------------------------------------------------------------------------------------
-import os
-import sys
-
-from knack.log import get_logger
-
-logger = get_logger(__name__)
-
-
-HOMEBREW_CELLAR_PATH = '/usr/local/Cellar/azure-cli/'
-
-
-def is_homebrew():
-    return any((p.startswith(HOMEBREW_CELLAR_PATH) for p in sys.path))
-
-
-# A workaround for https://github.com/Azure/azure-cli/issues/4428
-class HomebrewPipPatch(object):  # pylint: disable=too-few-public-methods
-
-    CFG_FILE = os.path.expanduser(os.path.join('~', '.pydistutils.cfg'))
-
-    def __init__(self):
-        self.our_cfg_file = False
-
-    def __enter__(self):
-        if not is_homebrew():
-            return
-        if os.path.isfile(HomebrewPipPatch.CFG_FILE):
-            logger.debug("Homebrew patch: The file %s already exists and we 
will not overwrite it. "
-                         "If extension installation fails, temporarily rename 
this file and try again.",
-                         HomebrewPipPatch.CFG_FILE)
-            logger.warning("Unable to apply Homebrew patch for extension 
installation. "
-                           "Attempting to continue anyway...")
-            self.our_cfg_file = False
-        else:
-            logger.debug("Homebrew patch: Temporarily creating %s to support 
extension installation on Homebrew.",
-                         HomebrewPipPatch.CFG_FILE)
-            with open(HomebrewPipPatch.CFG_FILE, "w") as f:
-                f.write("[install]\nprefix=")
-            self.our_cfg_file = True
-
-    def __exit__(self, exc_type, exc_value, tb):
-        if not is_homebrew():
-            return
-        if self.our_cfg_file and os.path.isfile(HomebrewPipPatch.CFG_FILE):
-            logger.debug("Homebrew patch: Deleting the temporarily created 
%s", HomebrewPipPatch.CFG_FILE)
-            os.remove(HomebrewPipPatch.CFG_FILE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_index.py 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_index.py
--- old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_index.py 
2018-07-26 19:30:50.000000000 +0200
+++ new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_index.py 
1970-01-01 01:00:00.000000000 +0100
@@ -1,53 +0,0 @@
-# 
--------------------------------------------------------------------------------------------
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License. See License.txt in the project root for 
license information.
-# 
--------------------------------------------------------------------------------------------
-import requests
-
-from knack.log import get_logger
-from knack.util import CLIError
-
-logger = get_logger(__name__)
-
-DEFAULT_INDEX_URL = "https://aka.ms/azure-cli-extension-index-v1";
-
-ERR_TMPL_EXT_INDEX = 'Unable to get extension index.\n'
-ERR_TMPL_NON_200 = '{}Server returned status code {{}} for 
{{}}'.format(ERR_TMPL_EXT_INDEX)
-ERR_TMPL_NO_NETWORK = '{}Please ensure you have network connection. Error 
detail: {{}}'.format(ERR_TMPL_EXT_INDEX)
-ERR_TMPL_BAD_JSON = '{}Response body does not contain valid json. Error 
detail: {{}}'.format(ERR_TMPL_EXT_INDEX)
-
-ERR_UNABLE_TO_GET_EXTENSIONS = 'Unable to get extensions from index. Improper 
index format.'
-TRIES = 3
-
-
-# pylint: disable=inconsistent-return-statements
-def get_index(index_url=None):
-    from azure.cli.core.util import should_disable_connection_verify
-    index_url = index_url or DEFAULT_INDEX_URL
-
-    for try_number in range(TRIES):
-        try:
-            response = requests.get(index_url, verify=(not 
should_disable_connection_verify()))
-            if response.status_code == 200:
-                return response.json()
-            msg = ERR_TMPL_NON_200.format(response.status_code, index_url)
-            raise CLIError(msg)
-        except (requests.exceptions.ConnectionError, 
requests.exceptions.HTTPError) as err:
-            msg = ERR_TMPL_NO_NETWORK.format(str(err))
-            raise CLIError(msg)
-        except ValueError as err:
-            # Indicates that url is not redirecting properly to intended index 
url, we stop retrying after TRIES calls
-            if try_number == TRIES - 1:
-                msg = ERR_TMPL_BAD_JSON.format(str(err))
-                raise CLIError(msg)
-            import time
-            time.sleep(0.5)
-            continue
-
-
-def get_index_extensions(index_url=None):
-    index = get_index(index_url=index_url)
-    extensions = index.get('extensions')
-    if extensions is None:
-        logger.warning(ERR_UNABLE_TO_GET_EXTENSIONS)
-    return extensions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_resolve.py 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_resolve.py
--- 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/_resolve.py   
    2018-07-26 19:30:50.000000000 +0200
+++ 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/_resolve.py   
    1970-01-01 01:00:00.000000000 +0100
@@ -1,78 +0,0 @@
-# 
--------------------------------------------------------------------------------------------
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License. See License.txt in the project root for 
license information.
-# 
--------------------------------------------------------------------------------------------
-from wheel.install import WHEEL_INFO_RE
-from pkg_resources import parse_version
-
-from knack.log import get_logger
-
-from azure.cli.core.extension import ext_compat_with_cli
-
-from azure.cli.command_modules.extension._index import get_index_extensions
-
-
-logger = get_logger(__name__)
-
-
-class NoExtensionCandidatesError(Exception):
-    pass
-
-
-def _is_not_platform_specific(item):
-    parsed_filename = WHEEL_INFO_RE(item['filename'])
-    p = parsed_filename.groupdict()
-    if p.get('pyver') == 'py2.py3' and p.get('abi') == 'none' and 
p.get('plat') == 'any':
-        return True
-    logger.debug("Skipping '%s' as not universal wheel."
-                 "We do not currently support platform specific extension 
detection. "
-                 "They can be installed with the full URL %s", 
item['filename'], item.get('downloadUrl'))
-    return False
-
-
-def _is_compatible_with_cli_version(item):
-    is_compatible, cli_core_version, min_required, max_required = 
ext_compat_with_cli(item['metadata'])
-    if is_compatible:
-        return True
-    logger.debug("Skipping '%s' as not compatible with this version of the 
CLI. "
-                 "Extension compatibility result: is_compatible=%s 
cli_core_version=%s min_required=%s "
-                 "max_required=%s", item['filename'], is_compatible, 
cli_core_version, min_required, max_required)
-    return False
-
-
-def _is_greater_than_cur_version(cur_version):
-    if not cur_version:
-        return None
-    cur_version_parsed = parse_version(cur_version)
-
-    def filter_func(item):
-        item_version = parse_version(item['metadata']['version'])
-        if item_version > cur_version_parsed:
-            return True
-        logger.debug("Skipping '%s' as %s not greater than current version 
%s", item['filename'],
-                     item_version, cur_version_parsed)
-        return False
-    return filter_func
-
-
-def resolve_from_index(extension_name, cur_version=None, index_url=None):
-    candidates = get_index_extensions(index_url=index_url).get(extension_name, 
[])
-    if not candidates:
-        raise NoExtensionCandidatesError("No extension found with name 
'{}'".format(extension_name))
-
-    filters = [_is_not_platform_specific, _is_compatible_with_cli_version, 
_is_greater_than_cur_version(cur_version)]
-    for f in filters:
-        logger.debug("Candidates %s", [c['filename'] for c in candidates])
-        candidates = list(filter(f, candidates))
-    if not candidates:
-        raise NoExtensionCandidatesError("No suitable extensions found.")
-
-    candidates_sorted = sorted(candidates, key=lambda c: 
parse_version(c['metadata']['version']), reverse=True)
-    logger.debug("Candidates %s", [c['filename'] for c in candidates_sorted])
-    logger.debug("Choosing the latest of the remaining candidates.")
-    chosen = candidates_sorted[0]
-    logger.debug("Chosen %s", chosen)
-    download_url, digest = chosen.get('downloadUrl'), 
chosen.get('sha256Digest')
-    if not download_url:
-        raise NoExtensionCandidatesError("No download url found.")
-    return download_url, digest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/custom.py 
new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/custom.py
--- old/azure-cli-extension-0.2.1/azure/cli/command_modules/extension/custom.py 
2018-07-26 19:30:50.000000000 +0200
+++ new/azure-cli-extension-0.2.3/azure/cli/command_modules/extension/custom.py 
2018-11-01 23:22:37.000000000 +0100
@@ -2,346 +2,37 @@
 # Copyright (c) Microsoft Corporation. All rights reserved.
 # Licensed under the MIT License. See License.txt in the project root for 
license information.
 # 
--------------------------------------------------------------------------------------------
-import sys
-import os
-import tempfile
-import shutil
-import zipfile
-import traceback
-import hashlib
-from subprocess import check_output, STDOUT, CalledProcessError
-from six.moves.urllib.parse import urlparse  # pylint: disable=import-error
-from collections import OrderedDict
-
-import requests
-from wheel.install import WHEEL_INFO_RE
-from pkg_resources import parse_version
-
 from knack.log import get_logger
 
-from azure.cli.core.util import CLIError
-from azure.cli.core.extension import (extension_exists, get_extension_path, 
get_extensions,
-                                      get_extension, ext_compat_with_cli, 
EXT_METADATA_ISPREVIEW,
-                                      WheelExtension, 
ExtensionNotInstalledException)
-from azure.cli.core.telemetry import set_extension_management_detail
-
-from ._homebrew_patch import HomebrewPipPatch
-from ._index import get_index_extensions
-from ._resolve import resolve_from_index, NoExtensionCandidatesError
+from azure.cli.core.extension.operations import (
+    add_extension, remove_extension, list_extensions, show_extension,
+    list_available_extensions, update_extension)
 
 logger = get_logger(__name__)
 
-OUT_KEY_NAME = 'name'
-OUT_KEY_VERSION = 'version'
-OUT_KEY_TYPE = 'extensionType'
-OUT_KEY_METADATA = 'metadata'
-
-IS_WINDOWS = sys.platform.lower() in ['windows', 'win32']
-LIST_FILE_PATH = os.path.join(os.sep, 'etc', 'apt', 'sources.list.d', 
'azure-cli.list')
-LSB_RELEASE_FILE = os.path.join(os.sep, 'etc', 'lsb-release')
-
-
-def _run_pip(pip_exec_args):
-    cmd = [sys.executable, '-m', 'pip'] + pip_exec_args + ['-vv', 
'--disable-pip-version-check', '--no-cache-dir']
-    logger.debug('Running: %s', cmd)
-    try:
-        log_output = check_output(cmd, stderr=STDOUT, universal_newlines=True)
-        logger.debug(log_output)
-        returncode = 0
-    except CalledProcessError as e:
-        logger.debug(e.output)
-        logger.debug(e)
-        returncode = e.returncode
-    return returncode
-
-
-def _whl_download_from_url(url_parse_result, ext_file):
-    from azure.cli.core.util import should_disable_connection_verify
-    url = url_parse_result.geturl()
-    r = requests.get(url, stream=True, verify=(not 
should_disable_connection_verify()))
-    if r.status_code != 200:
-        raise CLIError("Request to {} failed with {}".format(url, 
r.status_code))
-    with open(ext_file, 'wb') as f:
-        for chunk in r.iter_content(chunk_size=1024):
-            if chunk:  # ignore keep-alive new chunks
-                f.write(chunk)
-
-
-def _validate_whl_cli_compat(azext_metadata):
-    is_compatible, cli_core_version, min_required, max_required = 
ext_compat_with_cli(azext_metadata)
-    logger.debug("Extension compatibility result: is_compatible=%s 
cli_core_version=%s min_required=%s "
-                 "max_required=%s", is_compatible, cli_core_version, 
min_required, max_required)
-    if not is_compatible:
-        min_max_msg_fmt = "The extension is not compatible with this version 
of the CLI.\n" \
-                          "You have CLI core version {} and this extension " \
-                          "requires ".format(cli_core_version)
-        if min_required and max_required:
-            min_max_msg_fmt += 'a min of {} and max of 
{}.'.format(min_required, max_required)
-        elif min_required:
-            min_max_msg_fmt += 'a min of {}.'.format(min_required)
-        elif max_required:
-            min_max_msg_fmt += 'a max of {}.'.format(max_required)
-        raise CLIError(min_max_msg_fmt)
-
-
-def _validate_whl_extension(ext_file):
-    tmp_dir = tempfile.mkdtemp()
-    zip_ref = zipfile.ZipFile(ext_file, 'r')
-    zip_ref.extractall(tmp_dir)
-    zip_ref.close()
-    azext_metadata = WheelExtension.get_azext_metadata(tmp_dir)
-    shutil.rmtree(tmp_dir)
-    _validate_whl_cli_compat(azext_metadata)
-
-
-def _add_whl_ext(source, ext_sha256=None, pip_extra_index_urls=None, 
pip_proxy=None):  # pylint: disable=too-many-statements
-    if not source.endswith('.whl'):
-        raise ValueError('Unknown extension type. Only Python wheels are 
supported.')
-    url_parse_result = urlparse(source)
-    is_url = (url_parse_result.scheme == 'http' or url_parse_result.scheme == 
'https')
-    logger.debug('Extension source is url? %s', is_url)
-    whl_filename = os.path.basename(url_parse_result.path) if is_url else 
os.path.basename(source)
-    parsed_filename = WHEEL_INFO_RE(whl_filename)
-    # Extension names can have - but .whl format changes it to _ (PEP 0427). 
Undo this.
-    extension_name = parsed_filename.groupdict().get('name').replace('_', '-') 
if parsed_filename else None
-    if not extension_name:
-        raise CLIError('Unable to determine extension name from {}. Is the 
file name correct?'.format(source))
-    if extension_exists(extension_name):
-        raise CLIError('The extension {} already 
exists.'.format(extension_name))
-    ext_file = None
-    if is_url:
-        # Download from URL
-        tmp_dir = tempfile.mkdtemp()
-        ext_file = os.path.join(tmp_dir, whl_filename)
-        logger.debug('Downloading %s to %s', source, ext_file)
-        try:
-            _whl_download_from_url(url_parse_result, ext_file)
-        except (requests.exceptions.ConnectionError, 
requests.exceptions.HTTPError) as err:
-            raise CLIError('Please ensure you have network connection. Error 
detail: {}'.format(str(err)))
-        logger.debug('Downloaded to %s', ext_file)
-    else:
-        # Get file path
-        ext_file = os.path.realpath(os.path.expanduser(source))
-        if not os.path.isfile(ext_file):
-            raise CLIError("File {} not found.".format(source))
-    # Validate the extension
-    logger.debug('Validating the extension %s', ext_file)
-    if ext_sha256:
-        valid_checksum, computed_checksum = is_valid_sha256sum(ext_file, 
ext_sha256)
-        if valid_checksum:
-            logger.debug("Checksum of %s is OK", ext_file)
-        else:
-            logger.debug("Invalid checksum for %s. Expected '%s', computed 
'%s'.",
-                         ext_file, ext_sha256, computed_checksum)
-            raise CLIError("The checksum of the extension does not match the 
expected value. "
-                           "Use --debug for more information.")
-    try:
-        _validate_whl_extension(ext_file)
-    except AssertionError:
-        logger.debug(traceback.format_exc())
-        raise CLIError('The extension is invalid. Use --debug for more 
information.')
-    except CLIError as e:
-        raise e
-    logger.debug('Validation successful on %s', ext_file)
-    # Check for distro consistency
-    check_distro_consistency()
-    # Install with pip
-    extension_path = get_extension_path(extension_name)
-    pip_args = ['install', '--target', extension_path, ext_file]
-
-    if pip_proxy:
-        pip_args = pip_args + ['--proxy', pip_proxy]
-    if pip_extra_index_urls:
-        for extra_index_url in pip_extra_index_urls:
-            pip_args = pip_args + ['--extra-index-url', extra_index_url]
-
-    logger.debug('Executing pip with args: %s', pip_args)
-    with HomebrewPipPatch():
-        pip_status_code = _run_pip(pip_args)
-    if pip_status_code > 0:
-        logger.debug('Pip failed so deleting anything we might have installed 
at %s', extension_path)
-        shutil.rmtree(extension_path, ignore_errors=True)
-        raise CLIError('An error occurred. Pip failed with status code {}. '
-                       'Use --debug for more 
information.'.format(pip_status_code))
-    # Save the whl we used to install the extension in the extension dir.
-    dst = os.path.join(extension_path, whl_filename)
-    shutil.copyfile(ext_file, dst)
-    logger.debug('Saved the whl to %s', dst)
-
-
-def is_valid_sha256sum(a_file, expected_sum):
-    sha256 = hashlib.sha256()
-    with open(a_file, 'rb') as f:
-        sha256.update(f.read())
-    computed_hash = sha256.hexdigest()
-    return expected_sum == computed_hash, computed_hash
-
-
-def _augment_telemetry_with_ext_info(extension_name):
-    # The extension must be available before calling this otherwise we can't 
get the version from metadata
-    if not extension_name:
-        return
-    try:
-        ext = get_extension(extension_name)
-        ext_version = ext.version
-        set_extension_management_detail(extension_name, ext_version)
-    except Exception:  # nopa pylint: disable=broad-except
-        # Don't error on telemetry
-        pass
-
-
-def add_extension(source=None, extension_name=None, index_url=None, yes=None,  
# pylint: disable=unused-argument
-                  pip_extra_index_urls=None, pip_proxy=None):
-    ext_sha256 = None
-    if extension_name:
-        if extension_exists(extension_name):
-            raise CLIError('The extension {} already 
exists.'.format(extension_name))
-        try:
-            source, ext_sha256 = resolve_from_index(extension_name, 
index_url=index_url)
-        except NoExtensionCandidatesError as err:
-            logger.debug(err)
-            raise CLIError("No matching extensions for '{}'. Use --debug for 
more information.".format(extension_name))
-    _add_whl_ext(source, ext_sha256=ext_sha256, 
pip_extra_index_urls=pip_extra_index_urls, pip_proxy=pip_proxy)
-    _augment_telemetry_with_ext_info(extension_name)
-    try:
-        if extension_name and get_extension(extension_name).preview:
-            logger.warning("The installed extension '%s' is in preview.", 
extension_name)
-    except ExtensionNotInstalledException:
-        pass
-
-
-def remove_extension(extension_name):
-    def log_err(func, path, exc_info):
-        logger.debug("Error occurred attempting to delete item from the 
extension '%s'.", extension_name)
-        logger.debug("%s: %s - %s", func, path, exc_info)
-
-    try:
-        # Get the extension and it will raise an error if it doesn't exist
-        get_extension(extension_name)
-        # We call this just before we remove the extension so we can get the 
metadata before it is gone
-        _augment_telemetry_with_ext_info(extension_name)
-        shutil.rmtree(get_extension_path(extension_name), onerror=log_err)
-    except ExtensionNotInstalledException as e:
-        raise CLIError(e)
-
-
-def list_extensions():
-    return [{OUT_KEY_NAME: ext.name, OUT_KEY_VERSION: ext.version, 
OUT_KEY_TYPE: ext.ext_type}
-            for ext in get_extensions()]
-
-
-def show_extension(extension_name):
-    try:
-        extension = get_extension(extension_name)
-        return {OUT_KEY_NAME: extension.name,
-                OUT_KEY_VERSION: extension.version,
-                OUT_KEY_TYPE: extension.ext_type,
-                OUT_KEY_METADATA: extension.metadata}
-    except ExtensionNotInstalledException as e:
-        raise CLIError(e)
-
-
-def update_extension(extension_name, index_url=None, 
pip_extra_index_urls=None, pip_proxy=None):
-    try:
-        ext = get_extension(extension_name)
-        cur_version = ext.get_version()
-        try:
-            download_url, ext_sha256 = resolve_from_index(extension_name, 
cur_version=cur_version, index_url=index_url)
-        except NoExtensionCandidatesError as err:
-            logger.debug(err)
-            raise CLIError("No updates available for '{}'. Use --debug for 
more information.".format(extension_name))
-        # Copy current version of extension to tmp directory in case we need 
to restore it after a failed install.
-        backup_dir = os.path.join(tempfile.mkdtemp(), extension_name)
-        extension_path = get_extension_path(extension_name)
-        logger.debug('Backing up the current extension: %s to %s', 
extension_path, backup_dir)
-        shutil.copytree(extension_path, backup_dir)
-        # Remove current version of the extension
-        shutil.rmtree(extension_path)
-        # Install newer version
-        try:
-            _add_whl_ext(download_url, ext_sha256=ext_sha256,
+
+def add_extension_cmd(source=None, extension_name=None, index_url=None, 
yes=None,
+                      pip_extra_index_urls=None, pip_proxy=None):
+    return add_extension(source=source, extension_name=extension_name, 
index_url=index_url, yes=yes,
                          pip_extra_index_urls=pip_extra_index_urls, 
pip_proxy=pip_proxy)
-            logger.debug('Deleting backup of old extension at %s', backup_dir)
-            shutil.rmtree(backup_dir)
-            # This gets the metadata for the extension *after* the update
-            _augment_telemetry_with_ext_info(extension_name)
-        except Exception as err:
-            logger.error('An error occurred whilst updating.')
-            logger.error(err)
-            logger.debug('Copying %s to %s', backup_dir, extension_path)
-            shutil.copytree(backup_dir, extension_path)
-            raise CLIError('Failed to update. Rolled {} back to 
{}.'.format(extension_name, cur_version))
-    except ExtensionNotInstalledException as e:
-        raise CLIError(e)
-
-
-def list_available_extensions(index_url=None, show_details=False):
-    index_data = get_index_extensions(index_url=index_url)
-    if show_details:
-        return index_data
-    installed_extensions = get_extensions()
-    installed_extension_names = [e.name for e in installed_extensions]
-    results = []
-    for name, items in OrderedDict(sorted(index_data.items())).items():
-        # exclude extensions/versions incompatible with current CLI version
-        items = [item for item in items if 
ext_compat_with_cli(item['metadata'])[0]]
-        if not items:
-            continue
-
-        latest = max(items, key=lambda c: 
parse_version(c['metadata']['version']))
-        installed = False
-        if name in installed_extension_names:
-            installed = True
-            ext_version = get_extension(name).version
-            if ext_version and parse_version(latest['metadata']['version']) > 
parse_version(ext_version):
-                installed = str(True) + ' (upgrade available)'
-        results.append({
-            'name': name,
-            'version': latest['metadata']['version'],
-            'summary': latest['metadata']['summary'],
-            'preview': latest['metadata'].get(EXT_METADATA_ISPREVIEW, False),
-            'installed': installed
-        })
-    return results
-
-
-def get_lsb_release():
-    try:
-        with open(LSB_RELEASE_FILE, 'r') as lr:
-            lsb = lr.readlines()
-            desc = lsb[2]
-            desc_split = desc.split('=')
-            rel = desc_split[1]
-            return rel.strip()
-    except Exception:  # pylint: disable=broad-except
-        return None
-
-
-def check_distro_consistency():
-    if IS_WINDOWS:
-        return
-
-    try:
-        logger.debug('Linux distro check: Reading from: %s', LIST_FILE_PATH)
-
-        with open(LIST_FILE_PATH, 'r') as list_file:
-            package_source = list_file.read()
-            stored_linux_dist_name = package_source.split(" ")[3]
-            logger.debug('Linux distro check: Found in list file: %s', 
stored_linux_dist_name)
-            current_linux_dist_name = get_lsb_release()
-            logger.debug('Linux distro check: Reported by API: %s', 
current_linux_dist_name)
-
-    except Exception as err:  # pylint: disable=broad-except
-        current_linux_dist_name = None
-        stored_linux_dist_name = None
-        logger.debug('Linux distro check: An error occurred while checking '
-                     'linux distribution version source list consistency.')
-        logger.debug(err)
-
-    if current_linux_dist_name != stored_linux_dist_name:
-        logger.debug("Linux distro check: Mismatch distribution "
-                     "name in %s file", LIST_FILE_PATH)
-        logger.debug("Linux distro check: If command fails, install the 
appropriate package "
-                     "for your distribution or change the above file 
accordingly.")
-        logger.debug("Linux distro check: %s has '%s', current distro is '%s'",
-                     LIST_FILE_PATH, stored_linux_dist_name, 
current_linux_dist_name)
+
+
+def remove_extension_cmd(extension_name):
+    return remove_extension(extension_name)
+
+
+def list_extensions_cmd():
+    return list_extensions()
+
+
+def show_extension_cmd(extension_name):
+    return show_extension(extension_name)
+
+
+def update_extension_cmd(extension_name, index_url=None, 
pip_extra_index_urls=None, pip_proxy=None):
+    return update_extension(extension_name, index_url=index_url, 
pip_extra_index_urls=pip_extra_index_urls,
+                            pip_proxy=pip_proxy)
+
+
+def list_available_extensions_cmd(index_url=None, show_details=False):
+    return list_available_extensions(index_url=index_url, 
show_details=show_details)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure_cli_extension.egg-info/PKG-INFO 
new/azure-cli-extension-0.2.3/azure_cli_extension.egg-info/PKG-INFO
--- old/azure-cli-extension-0.2.1/azure_cli_extension.egg-info/PKG-INFO 
2018-07-26 19:31:58.000000000 +0200
+++ new/azure-cli-extension-0.2.3/azure_cli_extension.egg-info/PKG-INFO 
2018-11-01 23:22:54.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: azure-cli-extension
-Version: 0.2.1
+Version: 0.2.3
 Summary: Microsoft Azure Command-Line Tools Extension Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
@@ -20,6 +20,14 @@
         Release History
         ===============
         
+        0.2.3
+        +++++
+        * Minor fixes.
+        
+        0.2.2
+        +++++
+        * Attempting to add an extension that is already installed will not 
raise an exception.
+        
         0.2.1
         +++++
         * Fix index url failing requests.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-extension-0.2.1/azure_cli_extension.egg-info/SOURCES.txt 
new/azure-cli-extension-0.2.3/azure_cli_extension.egg-info/SOURCES.txt
--- old/azure-cli-extension-0.2.1/azure_cli_extension.egg-info/SOURCES.txt      
2018-07-26 19:31:58.000000000 +0200
+++ new/azure-cli-extension-0.2.3/azure_cli_extension.egg-info/SOURCES.txt      
2018-11-01 23:22:54.000000000 +0100
@@ -9,9 +9,6 @@
 azure/cli/command_modules/extension/__init__.py
 azure/cli/command_modules/extension/_completers.py
 azure/cli/command_modules/extension/_help.py
-azure/cli/command_modules/extension/_homebrew_patch.py
-azure/cli/command_modules/extension/_index.py
-azure/cli/command_modules/extension/_resolve.py
 azure/cli/command_modules/extension/custom.py
 azure_cli_extension.egg-info/PKG-INFO
 azure_cli_extension.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-extension-0.2.1/setup.py 
new/azure-cli-extension-0.2.3/setup.py
--- old/azure-cli-extension-0.2.1/setup.py      2018-07-26 19:30:50.000000000 
+0200
+++ new/azure-cli-extension-0.2.3/setup.py      2018-11-01 23:22:37.000000000 
+0100
@@ -14,7 +14,7 @@
     logger.warn("Wheel is not available, disabling bdist_wheel hook")
     cmdclass = {}
 
-VERSION = "0.2.1"
+VERSION = "0.2.3"
 
 CLASSIFIERS = [
     'Development Status :: 5 - Production/Stable',


Reply via email to