-
-
Save eko/9144662 to your computer and use it in GitHub Desktop.
#!/usr/bin/python | |
# | |
# This script will provides a reverse-search on Packagist to find which libraries uses a given library package | |
# as a dependency. | |
# | |
# Usage: | |
# First, you need to fetch dependencies: ./packagist.py --fetch | |
# After, you can start checking packages: ./packagist.py --package <package-name> | |
# | |
# Author: Vincent Composieux <[email protected]> | |
import sys, getopt, os | |
import json | |
import requests | |
def fetch_packages(url = None, page = 0, packages = None): | |
""" | |
This function fetch all Packagist packages and stores them into a JSON file | |
""" | |
if packages == None: | |
packages = [] | |
if url == None: | |
url = 'https://packagist.org/packages/list.json' | |
request = requests.get(url) | |
json = request.json() | |
current = 0 | |
total = len(json['packageNames']) | |
for library in json['packageNames']: | |
current += 1 | |
percent = (current * 100) / total | |
sys.stdout.write("\r> fetching dependencies of %d out of %s libraries... %d%%\r" % (current, total, percent)) | |
sys.stdout.flush() | |
library_request = requests.get('https://packagist.org/packages/%s.json' % library) | |
library_json = library_request.json() | |
library_array = {'name': None, 'versions': []} | |
if 'package' in library_json: | |
library_name = library_json['package']['name'] | |
versions = library_json['package']['versions'] | |
if len(versions) > 0: | |
for version in versions.keys(): | |
items = library_json['package']['versions'][version] | |
library_version = { | |
'version': version, | |
'packages': {'require': [], 'require-dev': [], 'suggest': []} | |
} | |
for type in ['require', 'require-dev', 'suggest']: | |
if type in items: | |
for item in items[type]: | |
library_version['packages'][type].append(item) | |
library_array['versions'].append(library_version) | |
library_array['name'] = library_name | |
packages.append(library_array) | |
if 'next' in json: | |
page += 1 | |
packages = fetch_packages(json['next'] + '&q=', page, packages) | |
return packages | |
def get_package_dependencies(libraries, package): | |
""" | |
This function research for libraries using given package as a dependency using dumped JSON file | |
""" | |
packages = {'require': [], 'require-dev': [], 'suggest': []} | |
current = 0 | |
total = len(libraries) | |
for library in libraries: | |
current += 1 | |
sys.stdout.write("\r> parsing dependency %d out of %s libraries...\r" % (current, total)) | |
sys.stdout.flush() | |
library_name = library['name'] | |
for version in library['versions']: | |
for type in ['require', 'require-dev', 'suggest']: | |
for item in version['packages'][type]: | |
if item == package and library_name not in packages[type]: | |
packages[type].append(library_name) | |
return packages | |
def main(argv): | |
""" | |
Script usage: ./packagist.py [--fetch|--package <package-name>] | |
""" | |
usage = 'usage: ./%s [--fetch|--package <package-name>]' % os.path.basename(__file__) | |
try: | |
opts, args = getopt.getopt(argv, 'f:p', ['fetch', 'package=']) | |
except getopt.GetoptError: | |
print usage | |
sys.exit(2) | |
if len(opts) == 0: | |
print usage | |
sys.exit(2) | |
for opt, arg in opts: | |
if opt in ['-f', '--fetch']: | |
print '> start fetching...' | |
packages = fetch_packages() | |
with open('packages.json', 'w') as file: | |
json.dump(packages, file) | |
print 'Packages dependencies has been dumped into packages.json file.' | |
elif opt in ['-p', '--package']: | |
print '> start parsing, please wait...' | |
try: | |
file = open('packages.json') | |
except IOError: | |
print '[error] no packages.json file found, you should run: ./%s --fetch' % os.path.basename(__file__) | |
sys.exit(2) | |
data = json.load(file) | |
packages = get_package_dependencies(data, arg) | |
print "\r" | |
print json.dumps(packages, sort_keys=True, indent=4, separators=(',', ': ')) | |
if __name__ == '__main__': | |
main(sys.argv[1:]) |
Thanks for the script, very useful :) I published an updated version here if you are interested.
It adds an option to fetch the packages using multiple threads (--threads=4
for example), considering the current number of packages, it does speed up the fetch process.
Also improves the lookup part by adding version information to the depending packages, and corrects a bug where some packages are incorrectly detected as dependant of the looked up package because they have empty package names in require/require-dev/suggest (don't ask me why, but some do).
Great script, thanks for that.
I just found this website https://www.versioneye.com, pretty good too.
Working link for solution by @fabre-thibaud
https://gist.github.com/fabre-thibaud/c651be55b2f114236be2
Also link to the author's post
https://vincent.composieux.fr/article/packagist-which-package-use-mine-as-a-dependency
Usage:
Start by fetching dependencies in a dumped
packages.json
file:After that, you can use
--package <package-name>
to check a package and get the following JSON result:Here,
eko/feedbundle
is a dependency ofcobase/cobase
in therequire
section and also insymfony-cmf/block-bundle
in thesuggest
section.