101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
import importlib
|
|
import importlib.util
|
|
import os
|
|
import glob
|
|
import json
|
|
from typing import Iterator
|
|
|
|
import requests
|
|
|
|
import dbt.exceptions
|
|
import dbt.semver
|
|
|
|
|
|
PYPI_VERSION_URL = 'https://pypi.org/pypi/dbt/json'
|
|
|
|
|
|
def get_latest_version():
|
|
try:
|
|
resp = requests.get(PYPI_VERSION_URL)
|
|
data = resp.json()
|
|
version_string = data['info']['version']
|
|
except (json.JSONDecodeError, KeyError, requests.RequestException):
|
|
return None
|
|
|
|
return dbt.semver.VersionSpecifier.from_version_string(version_string)
|
|
|
|
|
|
def get_installed_version():
|
|
return dbt.semver.VersionSpecifier.from_version_string(__version__)
|
|
|
|
|
|
def get_version_information():
|
|
installed = get_installed_version()
|
|
latest = get_latest_version()
|
|
|
|
installed_s = installed.to_version_string(skip_matcher=True)
|
|
if latest is None:
|
|
latest_s = 'unknown'
|
|
else:
|
|
latest_s = latest.to_version_string(skip_matcher=True)
|
|
|
|
version_msg = ("installed version: {}\n"
|
|
" latest version: {}\n\n".format(installed_s, latest_s))
|
|
|
|
plugin_version_msg = "Plugins:\n"
|
|
for plugin_name, version in _get_dbt_plugins_info():
|
|
plugin_version_msg += ' - {plugin_name}: {version}\n'.format(
|
|
plugin_name=plugin_name, version=version
|
|
)
|
|
if latest is None:
|
|
return ("{}The latest version of dbt could not be determined!\n"
|
|
"Make sure that the following URL is accessible:\n{}\n\n{}"
|
|
.format(version_msg, PYPI_VERSION_URL, plugin_version_msg))
|
|
|
|
if installed == latest:
|
|
return "{}Up to date!\n\n{}".format(version_msg, plugin_version_msg)
|
|
|
|
elif installed > latest:
|
|
return ("{}Your version of dbt is ahead of the latest "
|
|
"release!\n\n{}".format(version_msg, plugin_version_msg))
|
|
|
|
else:
|
|
return ("{}Your version of dbt is out of date! "
|
|
"You can find instructions for upgrading here:\n"
|
|
"https://docs.getdbt.com/docs/installation\n\n{}"
|
|
.format(version_msg, plugin_version_msg))
|
|
|
|
|
|
def _get_adapter_plugin_names() -> Iterator[str]:
|
|
spec = importlib.util.find_spec('dbt.adapters')
|
|
# If None, then nothing provides an importable 'dbt.adapters', so we will
|
|
# not be reporting plugin versions today
|
|
if spec is None or spec.submodule_search_locations is None:
|
|
return
|
|
for adapters_path in spec.submodule_search_locations:
|
|
version_glob = os.path.join(adapters_path, '*', '__version__.py')
|
|
for version_path in glob.glob(version_glob):
|
|
# the path is like .../dbt/adapters/{plugin_name}/__version__.py
|
|
# except it could be \\ on windows!
|
|
plugin_root, _ = os.path.split(version_path)
|
|
_, plugin_name = os.path.split(plugin_root)
|
|
yield plugin_name
|
|
|
|
|
|
def _get_dbt_plugins_info():
|
|
for plugin_name in _get_adapter_plugin_names():
|
|
if plugin_name == 'core':
|
|
continue
|
|
try:
|
|
mod = importlib.import_module(
|
|
f'dbt.adapters.{plugin_name}.__version__'
|
|
)
|
|
except ImportError:
|
|
# not an adpater
|
|
continue
|
|
yield plugin_name, mod.version
|
|
|
|
|
|
__version__ = '0.21.1'
|
|
installed = get_installed_version()
|