mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-12-24 16:10:33 -06:00
215 lines
5.6 KiB
Python
215 lines
5.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
##########################################################################
|
|
#
|
|
# pgAdmin 4 - PostgreSQL Tools
|
|
#
|
|
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
|
# This software is released under the PostgreSQL Licence
|
|
#
|
|
##########################################################################
|
|
|
|
# This utility will generate a iist of all dependencies, their upstream
|
|
# repos and licence information.
|
|
|
|
import os
|
|
import json
|
|
import pkg_resources
|
|
import sys
|
|
import textwrap
|
|
|
|
from subprocess import Popen, PIPE
|
|
|
|
# Column sizes
|
|
name_size = 64
|
|
version_size = 16
|
|
licence_size = 36
|
|
|
|
|
|
def print_title(title):
|
|
print(title)
|
|
print(("=" * len(title)) + "\n")
|
|
|
|
|
|
def print_row(name, version, licence, url):
|
|
print("{} {} {} {}".format(name.ljust(name_size),
|
|
version.ljust(version_size),
|
|
licence.ljust(licence_size), url))
|
|
|
|
|
|
def print_table_header():
|
|
print_row("Name", "Version", "Licence", "URL")
|
|
print_row("----", "-------", "-------", "---")
|
|
|
|
|
|
def print_summary(count):
|
|
print("\n{} dependencies listed.\n".format(count))
|
|
|
|
|
|
def get_python_deps():
|
|
# Get the path to the requirements.txt file
|
|
req_file = os.path.realpath(os.path.dirname(os.path.abspath(__file__)) +
|
|
"/../requirements.txt")
|
|
|
|
with open(req_file, 'r') as req_file_p:
|
|
required = req_file_p.read().splitlines()
|
|
|
|
# Get the package info from the requirements file
|
|
requirements = pkg_resources.parse_requirements(required)
|
|
|
|
have_unknowns = False
|
|
count = 0
|
|
|
|
# Iterate the packages and get the distribution info for each
|
|
for pkg in requirements:
|
|
|
|
try:
|
|
distribution = pkg_resources.get_distribution(pkg)
|
|
except IndexError as e:
|
|
# The package probably isn't required on this version of Python,
|
|
# thus we have no info about it.
|
|
have_unknowns = True
|
|
|
|
name = pkg.name
|
|
version = "Unknown"
|
|
|
|
for spec in pkg.specs:
|
|
if spec[0] == "==":
|
|
version = spec[1]
|
|
break
|
|
|
|
licence = "Unknown"
|
|
url = "Unknown"
|
|
if pkg.url is not None:
|
|
url = pkg.url
|
|
|
|
print_row(name, version, licence, url)
|
|
count = count + 1
|
|
|
|
# Next one....
|
|
continue
|
|
|
|
try:
|
|
metadata = distribution.get_metadata_lines('METADATA')
|
|
except IOError:
|
|
metadata = distribution.get_metadata_lines('PKG-INFO')
|
|
|
|
# Somewhere to store the info we need...
|
|
name = ""
|
|
version = "Unknown"
|
|
url = "Unknown"
|
|
licence = "Unknown"
|
|
|
|
# Loop over each line in the metadata and grab the info we need
|
|
for line in metadata:
|
|
if line.startswith("Name: "):
|
|
name = line[6:]
|
|
|
|
if line.startswith("Version: "):
|
|
version = line[9:]
|
|
|
|
if line.startswith("License: "):
|
|
licence = line[9:]
|
|
|
|
if line.startswith("Home-page: "):
|
|
url = line[11:]
|
|
|
|
if name != "":
|
|
print_row(name, version, licence, url)
|
|
count = count + 1
|
|
|
|
if have_unknowns:
|
|
major = sys.version_info.major
|
|
minor = sys.version_info.minor
|
|
|
|
print("")
|
|
print(textwrap.fill("NOTE: This report was generated using "
|
|
"Python {}.{}. Full information may not be shown "
|
|
"for Python modules that are not required with "
|
|
"this version.".format(
|
|
major, minor), width=79))
|
|
|
|
print_summary(count)
|
|
|
|
|
|
def get_js_deps():
|
|
# Get the path to package.json file
|
|
web_dir = os.path.realpath(os.path.dirname(os.path.abspath(__file__)) +
|
|
"/../web/")
|
|
|
|
# Build the Yarn command
|
|
cmd = ["yarn", "--cwd", web_dir, "licenses", "list", "--json"]
|
|
|
|
# Run the command
|
|
process = Popen(cmd, stdout=PIPE)
|
|
(output, err) = process.communicate()
|
|
process.wait()
|
|
|
|
# Cleanup the output
|
|
output_str = output.splitlines()[-1]
|
|
if hasattr(output_str, 'decode'):
|
|
output_str = output_str.decode('utf-8')
|
|
raw_data = json.loads(output_str)
|
|
|
|
modules = raw_data['data']['body']
|
|
|
|
# Loop through the modules, and output the data.
|
|
for module in modules:
|
|
name = module[0]
|
|
|
|
version = "Unknown"
|
|
if module[1] != "":
|
|
version = module[1]
|
|
|
|
licence = "Unknown"
|
|
if module[2] != "":
|
|
licence = module[2]
|
|
|
|
url = "Unknown"
|
|
if module[3] != "":
|
|
url = module[3]
|
|
|
|
print_row(name, version, licence, url)
|
|
|
|
print_summary(len(modules))
|
|
|
|
|
|
def dump_header():
|
|
print_title("pgAdmin 4 Dependency Inventory")
|
|
|
|
print(textwrap.fill(
|
|
"pgAdmin 4 is built on C++, Python and Javascript, and is "
|
|
"dependent on various third party libraries. These are "
|
|
"automatically compiled from the system, requirements.txt."
|
|
"and packages.json and list below.",
|
|
width=79) + "\n")
|
|
|
|
|
|
def dump_cplusplus():
|
|
print_title("C++ Dependencies")
|
|
print_table_header()
|
|
print_row("QT", "5+", "LGPL v2.1/3", "https://www.qt.io/")
|
|
print_row("Python", "3.4+", "PSF", "https://www.python.org/")
|
|
print_summary(2)
|
|
|
|
|
|
def dump_python():
|
|
print_title("Python Dependencies")
|
|
print_table_header()
|
|
|
|
get_python_deps()
|
|
|
|
|
|
def dump_js():
|
|
print_title("Javascript Dependencies")
|
|
print_table_header()
|
|
|
|
get_js_deps()
|
|
|
|
|
|
# Let's do this thing!
|
|
dump_header()
|
|
dump_cplusplus()
|
|
dump_python()
|
|
dump_js()
|