diff --git a/.travis.yml b/.travis.yml index 58d90c21..73b875e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: python python: - "2.7" + - "3.6" install: - ./configure etc/conf/dev diff --git a/MANIFEST.in b/MANIFEST.in index 8a09b241..3fd2b3fb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,10 +1,29 @@ -include *.ABOUT -include about* -include *LICENSE* -include *NOTICE* -include *README* +graft src +graft tests +graft docs +graft etc +graft example +graft thirdparty + +prune src/aboutcode_toolkit.egg-info + +include about.ABOUT +include about +include about.bat +include about.cfg +include apache-2.0.LICENSE +include about.bat +include apache-2.0.LICENSE +include configure +include configure.bat +include MANIFEST.in +include NOTICE +include README.rst +include setup.cfg +include setup.py +include SPEC include USAGE.rst -include *SPEC* +include .travis.yml +include appveyor.yml -recursive-include tests/testdata * -recursive-include about_code_tool/templates * \ No newline at end of file +global-exclude *.py[co] __pycache__ *.*~ diff --git a/README.rst b/README.rst index 9d99f79d..09599085 100644 --- a/README.rst +++ b/README.rst @@ -1,11 +1,20 @@ AboutCode toolkit ================= -.. image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=develop - :target: https://travis-ci.org/nexB/aboutcode-toolkit - -.. image:: https://coveralls.io/repos/nexB/aboutcode-toolkit/badge.png?branch=develop - :target: https://coveralls.io/r/nexB/aboutcode-toolkit?branch=develop +Build and tests status +---------------------- + ++-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ +|Branch | **Linux (Travis)** | **MacOSX (Travis)** | **Windows (AppVeyor)** | ++=======+===============================================================================+===============================================================================+======================================================================================================+ +| |.. image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=master |.. image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=master |.. image:: https://ci.appveyor.com/api/projects/status/nexB/aboutcode-toolkit/branch/master?png=true | +|Master | :target: https://travis-ci.org/nexB/aboutcode-toolkit | :target: https://travis-ci.org/nexB/aboutcode-toolkit | :target: https://ci.appveyor.com/project/nexB/aboutcode-toolkit | +| | :alt: Linux Master branch tests status | :alt: MacOSX Master branch tests status | :alt: Windows Master branch tests status | ++-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ +| |.. image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=develop |.. image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=develop |.. image:: https://ci.appveyor.com/api/projects/status/nexB/aboutcode-toolkit/branch/develop?png=true | +|Develop| :target: https://travis-ci.org/nexB/aboutcode-toolkit | :target: https://travis-ci.org/nexB/aboutcode-toolkit | :target: https://ci.appveyor.com/project/nexB/aboutcode-toolkit | +| | :alt: Linux Develop branch tests status | :alt: MacOSX Develop branch tests status | :alt: Windows Develop branch tests status | ++-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ The AboutCode toolkit and ABOUT files provide a simple way to document the @@ -32,7 +41,7 @@ https://github.com/nexB/aboutcode-toolkit/blob/master/SPEC REQUIREMENTS ------------ -The AboutCode toolkit is tested with 2.7 on Linux, Mac and Windows. +The AboutCode toolkit is tested with Python 2.7 and 3.6 on Linux, Mac and Windows. You will need to install a Python interpreter if you do not have one already installed. @@ -40,9 +49,8 @@ On Linux and Mac, Python is typically pre-installed. To verify which version may be pre-installed, open a terminal and type:: python --version - python2.7 --version -On Windows or Mac, you can download the latest Python 2.7.x here: +On Windows or Mac, you can download the latest Python here: https://www.python.org/downloads/ Download the .msi installer for Windows or the .dmg archive for Mac. @@ -55,7 +63,7 @@ Checkout or download and extract the AboutCode toolkit from: https://github.com/nexB/aboutcode-toolkit/ To install all the needed dependencies in a virtualenv, run (on posix):: - source configure + source configure or on windows:: configure @@ -65,8 +73,8 @@ USAGE See https://github.com/nexB/aboutcode-toolkit/blob/master/USAGE.rst for USAGE. -TESTS and DEVLOPMENT --------------------- +TESTS and DEVELOPMENT +--------------------- To install all the needed development dependencies, run (on posix):: source configure etc/conf/dev or on windows:: @@ -76,7 +84,6 @@ To verify that everything works fine you can run the test suite with:: py.test - HELP and SUPPORT ---------------- If you have a question or find a bug, enter a ticket at: diff --git a/about.ABOUT b/about.ABOUT index fb5311a1..42494d7c 100644 --- a/about.ABOUT +++ b/about.ABOUT @@ -1,12 +1,12 @@ about_resource: . -name: AboutCode -version: 3.0.0.dev4 +name: AboutCode-toolkit +version: 3.0.0.dev6 owner: nexB Inc. author: Jillian Daguil, Chin Yeung Li, Philippe Ombredanne, Thomas Druez -home_url: http://dejacode.org +home_url: https://aboutcode.org vcs_tool: git vcs_repository: https://github.com/dejacode/about-code-tool.git diff --git a/configure b/configure index 550fed9f..ab3837c2 100755 --- a/configure +++ b/configure @@ -27,7 +27,7 @@ fi CONFIGURE_ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -python2.7 $CONFIGURE_ROOT_DIR/etc/configure.py $CFG_CMD_LINE_ARGS +python $CONFIGURE_ROOT_DIR/etc/configure.py $CFG_CMD_LINE_ARGS if [ -f "$CONFIGURE_ROOT_DIR/bin/activate" ]; then source $CONFIGURE_ROOT_DIR/bin/activate fi diff --git a/etc/conf/base.txt b/etc/conf/base.txt index 6407ab6c..339a23f0 100644 --- a/etc/conf/base.txt +++ b/etc/conf/base.txt @@ -6,18 +6,15 @@ pip wincertstore # used for templating -jinja2==2.7.3 -MarkupSafe==0.23 +jinja2==2.9.6 +MarkupSafe==1.0.0 -click==3.3 +click==6.7 # used by schematics six -pyyaml==3.11 - - -unicodecsv==0.9.4 +pyyaml==3.12 # license expression support license_expression diff --git a/setup.cfg b/setup.cfg index b6d86417..b19142d9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,9 +5,9 @@ universal = 1 license_file = NOTICE [aliases] -release = clean --all sdist --formats=bztar,zip bdist_wheel register upload +release = clean --all sdist --formats=bztar,zip bdist_wheel -[pytest] +[tool:pytest] norecursedirs = .git bin diff --git a/setup.py b/setup.py index 7fba3e4e..26e0a312 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- +# -*- encoding: utf-8 -*- from __future__ import absolute_import from __future__ import print_function @@ -10,6 +10,7 @@ from os.path import dirname from os.path import join from os.path import splitext + from setuptools import find_packages from setuptools import setup @@ -22,16 +23,20 @@ def read(*names, **kwargs): setup( - name='attributecode', - version='3.0.0.dev4', + name='aboutcode-toolkit', + version='3.0.0.dev6', license='Apache-2.0', - description=('Document the provenance (origin and license) of ' - 'third-party software using small text files. ' - 'Collect inventories, generate attribution documentation.'), - long_description=('AttributeCode provides a simple way to document the' + description=( + 'AboutCode-toolkit is a tool to document the provenance (origin and license) of ' + 'third-party software using small text files. ' + 'Collect inventories, generate attribution documentation.' + ), + long_description=( + 'AttributeCode provides a simple way to document the' 'provenance (i.e. origin and license) of software components that' 'you use in your project. This documentation is stored in *.ABOUT' - 'files, side-by-side with the documented code.'), + 'files, side-by-side with the documented code.' + ), author='Chin-Yeung Li, Jillian Daguil, Thomas Druez, Philippe Ombredanne and others.', author_email='info@nexb.com', url='http://aboutcode.org', @@ -46,9 +51,11 @@ def read(*names, **kwargs): 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Intended Audience :: Developers', 'License :: OSI Approved :: Apache Software License', 'Operating System :: OS Independent', - 'Intended Audience :: Developers', 'Topic :: Software Development', 'Topic :: Software Development :: Documentation', 'Topic :: Software Development :: Quality Assurance', @@ -56,49 +63,23 @@ def read(*names, **kwargs): 'Topic :: Utilities', ], keywords=[ - 'license', 'about', 'metadata', 'package', 'copyright', + 'license', 'about', 'metadata', 'package', 'copyright', 'attribution', 'software', 'inventory', ], - data_files=[('about', - [ - 'about.ABOUT', - 'about.bat', - 'about', - 'configure.bat', - 'configure', - 'about.cfg', - 'README.rst', - 'apache-2.0.LICENSE', - 'NOTICE', - 'SPEC', - 'USAGE.rst', - ]), - ], - - entry_points=''' - [console_scripts] - about-code=attributecode.cmd:cli - ''', install_requires=[ - 'jinja2 >= 2.7.3, < 2.8', - 'click >= 3.2, < 4', - 'unicodecsv >= 0.9.4, < 1.0', + 'jinja2 >= 2.9, < 3.0', + 'click >= 6.7, < 7.0', + "backports.csv ; python_version<'3.6'", 'pyyaml >= 3.11, < 3.13', - 'boolean.py', - 'license_expression', - ], - + 'boolean.py >= 3.5, < 4.0', + 'license_expression >= 0.94, < 1.0', + ], extras_require={ - 'base': [ - 'certifi', - 'setuptools', - 'wheel', - 'pip', - 'wincertstore', - ], - 'dev': [ - 'pytest', - 'py', - ], - } + ":python_version < '3.6'": ['backports.csv'], + }, + entry_points={ + 'console_scripts': [ + 'about-code=attributecode.cmd:cli', + ] + }, ) diff --git a/src/attributecode/__init__.py b/src/attributecode/__init__.py index eb999244..173fa370 100644 --- a/src/attributecode/__init__.py +++ b/src/attributecode/__init__.py @@ -14,19 +14,26 @@ # limitations under the License. # ============================================================================ - from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals from collections import namedtuple import logging -__version__ = '3.0.0.dev5' +try: + basestring # Python 2 +except NameError: + basestring = str # Python 3 + + +__version__ = '3.0.0.dev6' + __about_spec_version__ = '2.0.0.dev2' __copyright__ = """ -Copyright (c) 2013-2016 nexB Inc. All rights reserved. http://dejacode.org +Copyright (c) 2013-2017 nexB Inc. All rights reserved. http://dejacode.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -38,15 +45,46 @@ limitations under the License. """ -Error = namedtuple('Error', ['severity', 'message']) -def error_repr(self): - sev = severities[self.severity] - msg = self.message - return 'Error(%(sev)s, %(msg)r)' % locals() +class Error(namedtuple('Error', ['severity', 'message'])): + """ + An Error data with a severity and message. + """ + def __new__(self, severity, message): + if message: + if isinstance(message, basestring): + message = clean_string(message) + else: + message = clean_string(repr(message)) + + return super(Error, self).__new__( + Error, severity, message) + + def __repr__(self, *args, **kwargs): + sev = severities[self.severity] + msg = clean_string(repr(self.message)) + return 'Error(%(sev)s, %(msg)s)' % locals() -Error.__repr__ = error_repr +def clean_string(s): + """ + Return a cleaned string for `s`, stripping eventual "u" prefixes + from unicode representations. + """ + if not s: + return s + if s.startswith(('u"', "u'")): + s = s.lstrip('u') + s = s.replace('[u"', '["') + s = s.replace("[u'", "['") + s = s.replace("(u'", "('") + s = s.replace("(u'", "('") + s = s.replace("{u'", "{'") + s = s.replace("{u'", "{'") + s = s.replace(" u'", " '") + s = s.replace(" u'", " '") + s = s.replace("\\\\", "\\") + return s # modeled after the logging levels CRITICAL = 50 diff --git a/src/attributecode/__main__.py b/src/attributecode/__main__.py index e1de409f..977d906f 100644 --- a/src/attributecode/__main__.py +++ b/src/attributecode/__main__.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2013-2015 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,6 +14,10 @@ # limitations under the License. # ============================================================================ +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + if __name__ == '__main__': from attributecode import cmd diff --git a/src/attributecode/api.py b/src/attributecode/api.py index b34898d7..b97c8193 100644 --- a/src/attributecode/api.py +++ b/src/attributecode/api.py @@ -16,10 +16,17 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals -import json -import urllib from collections import namedtuple +import json + +try: + from urllib import urlencode + from urllib import quote +except ImportError: + from urllib.parse import urlencode + from urllib.parse import quote try: import httplib # Python 2 @@ -48,12 +55,12 @@ def build_api_url(url, api_username, api_key, license_key): payload = {'username': api_username, 'api_key': api_key, 'format': 'json'} - encoded_payload = urllib.urlencode(payload) + encoded_payload = urlencode(payload) api_url = '%(url)s/%(license_key)s/?%(encoded_payload)s' % locals() # handle special characters in URL such as space etc. - api_url = urllib.quote(api_url, safe="%/:=&?~#+!$,;'@()*[]") + api_url = quote(api_url, safe="%/:=&?~#+!$,;'@()*[]") return api_url @@ -127,10 +134,10 @@ def request_license_data(url, api_key, license_key): } url = url.rstrip('/') - encoded_payload = urllib.urlencode(payload) + encoded_payload = urlencode(payload) full_url = '%(url)s/?%(encoded_payload)s' % locals() # handle special characters in URL such as space etc. - full_url = urllib.quote(full_url, safe="%/:=&?~#+!$,;'@()*[]") + full_url = quote(full_url, safe="%/:=&?~#+!$,;'@()*[]") headers = {'Authorization': 'Token %s' % api_key} license_data = {} errors = [] diff --git a/src/attributecode/attrib.py b/src/attributecode/attrib.py index 2340251e..f1bf8e6a 100644 --- a/src/attributecode/attrib.py +++ b/src/attributecode/attrib.py @@ -16,16 +16,18 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals import codecs import collections -import jinja2 import os from posixpath import basename from posixpath import dirname from posixpath import exists from posixpath import join +import jinja2 + import attributecode from attributecode import ERROR from attributecode import Error @@ -36,7 +38,7 @@ def generate(abouts, template_string=None): """ - Generate and return attribution text from a list of ABOUT objects and a + Generate and return attribution text from a list of About objects and a template string. The returned rendered text may contain template processing error messages. """ @@ -73,7 +75,7 @@ def generate(abouts, template_string=None): if about.license_expression.value and about.license_name.value: # Split the license expression into list with license key and condition keyword lic_expression_list = about.license_expression.value.split() - + lic_name_list = about.license_name.value lic_name_expression_list = [] @@ -96,7 +98,7 @@ def generate(abouts, template_string=None): lic_name_expression = ' '.join(lic_name_expression_list) # Add the license name expression string into the about object - about.license_name_expression = lic_name_expression + about.license_name_expression = lic_name_expression rendered = template.render(abouts=abouts, common_licenses=COMMON_LICENSES, license_key_and_context=sorted_license_key_and_context, license_file_name_and_key=license_file_name_and_key, license_key_to_license_name=license_key_to_license_name) @@ -125,7 +127,7 @@ def check_template(template_string): def generate_from_file(abouts, template_loc=None): """ - Generate and return attribution string from a list of ABOUT objects and a + Generate and return attribution string from a list of About objects and a template location. """ if not template_loc: @@ -136,12 +138,18 @@ def generate_from_file(abouts, template_loc=None): return generate(abouts, template_string=tpls) -def generate_and_save(abouts, output_location, mapping, template_loc=None, - inventory_location=None): +def generate_and_save(abouts, output_location, use_mapping=False, + template_loc=None, inventory_location=None): """ - Generate attribution using template and save at output_location. - Filter the list of about object based on the inventory CSV at - inventory_location. + Generate attribution file using the `abouts` list of About object + at `output_location`. + + Use the optional `template_loc` custom temaplte or a default template. + + Optionally filter `abouts` object based on the inventory JSON or + CSV at `inventory_location`. + + Optionally use the mapping.config file is `use_mapping` is True """ updated_abouts = [] lstrip_afp = [] @@ -154,21 +162,28 @@ def generate_and_save(abouts, output_location, mapping, template_loc=None, # Do the following if an filter list (inventory_location) is provided else: if not exists(inventory_location): - msg = (u'"INVENTORY_LOCATOIN" does not exist. Generation halted.') + # FIXME: this message does not make sense + msg = (u'"INVENTORY_LOCATION" does not exist. Generation halted.') errors.append(Error(ERROR, msg)) return errors if inventory_location.endswith('.csv') or inventory_location.endswith('.json'): + # FIXME: we should use the same inventory lodaing that we use everywhere!!!! + try: # Return a list which contains only the about file path - about_list = attributecode.util.get_about_file_path(mapping, inventory_location) + about_list = attributecode.util.get_about_file_path( + inventory_location, use_mapping=use_mapping) + # FIXME: why catching all exceptions? except Exception: # 'about_file_path' key/column doesn't exist - msg = (u"The required key: 'about_file_path' does not exist. Generation halted.") + + msg = u"The required key: 'about_file_path' does not exist. Generation halted." errors.append(Error(ERROR, msg)) return errors else: - msg = (u'Only .csv and .json are supported for the "INVENTORY_LOCATOIN". Generation halted.') + # FIXME: this message does not make sense + msg = u'Only .csv and .json are supported for the "INVENTORY_LOCATION". Generation halted.' errors.append(Error(ERROR, msg)) return errors @@ -189,12 +204,12 @@ def generate_and_save(abouts, output_location, mapping, template_loc=None, if not_match_path: if len(not_match_path) == len(about_files_list): - msg = ("None of the paths in the provided 'inventory_location' match with the 'LOCATION'.") + msg = "None of the paths in the provided 'inventory_location' match with the 'LOCATION'." errors.append(Error(ERROR, msg)) return errors else: for path in not_match_path: - msg = ('Path: ' + path + ' cannot be found.') + msg = 'Path: ' + path + ' cannot be found.' errors.append(Error(ERROR, msg)) for about in abouts: @@ -222,16 +237,19 @@ def generate_and_save(abouts, output_location, mapping, template_loc=None, return errors + def as_about_paths(paths): """ - Given a list of paths, return a list of paths that point all to .ABOUT files. + Return a list of paths to .ABOUT files from a list of `paths` + strings. """ - normalized_paths = [] + about_paths = [] for path in paths: if path.endswith('.ABOUT'): - normalized_paths.append(path) + about_paths.append(path) else: + # FIXME: this is not the way to check that a path is a directory, too weak if path.endswith('/'): path += basename(dirname(path)) - normalized_paths.append(path + '.ABOUT') - return normalized_paths + about_paths.append(path + '.ABOUT') + return about_paths diff --git a/src/attributecode/cmd.py b/src/attributecode/cmd.py index 45d3b258..a869818a 100644 --- a/src/attributecode/cmd.py +++ b/src/attributecode/cmd.py @@ -16,15 +16,17 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals import codecs import logging import os from os.path import exists, join +import sys import click -import unicodecsv -import sys +# silence unicode literals warnings +click.disable_unicode_literals_warning = True import attributecode from attributecode import CRITICAL @@ -32,14 +34,14 @@ from attributecode import INFO from attributecode import NOTSET from attributecode import WARNING -from attributecode import Error from attributecode import __about_spec_version__ from attributecode import __version__ from attributecode import attrib +from attributecode import Error from attributecode import gen from attributecode import model -from attributecode import severities from attributecode.model import About +from attributecode import severities from attributecode.util import extract_zip from attributecode.util import to_posix @@ -57,55 +59,88 @@ limitations under the License.""" -prog_name = 'AttributeCode' +prog_name = 'AboutCode-toolkit' + -intro = '''%(prog_name)s, version %(__version__)s -ABOUT spec version: %(__about_spec_version__)s http://dejacode.org +intro = '''%(prog_name)s version %(__version__)s +ABOUT spec version: %(__about_spec_version__)s +https://aboutcode.org %(__copyright__)s ''' % locals() + problematic_errors = [u'CRITICAL', u'ERROR', u'WARNING'] + +def print_version(): + click.echo('Running aboutcode-toolkit version ' + __version__) + + class AboutCommand(click.Command): def main(self, args=None, prog_name=None, complete_var=None, standalone_mode=True, **extra): """ Workaround click 4.0 bug https://github.com/mitsuhiko/click/issues/365 """ - return click.Command.main(self, args=args, prog_name=self.name, - complete_var=complete_var, - standalone_mode=standalone_mode, **extra) + return click.Command.main( + self, args=args, prog_name=self.name, + complete_var=complete_var, standalone_mode=standalone_mode, **extra) + +# we define a main entry command with subcommands @click.group(name='about') @click.version_option(version=__version__, prog_name=prog_name, message=intro) +@click.help_option('-h', '--help') def cli(): - pass + """ +Generate licensing attribution and credit notices from .ABOUT files and inventories. + +Read, write and collect provenance and license inventories from .ABOUT files to and from JSON or CSV files. +Use about-code --help for help on a command. + """ + + +###################################################################### +# inventory subcommand +###################################################################### + +@cli.command(cls=AboutCommand, + short_help='Collect .ABOUT files and write an inventory as CSV or JSON.') -@cli.command(cls=AboutCommand, short_help='LOCATION: directory, OUTPUT: csv file') @click.argument('location', nargs=1, required=True, - type=click.Path(exists=True, file_okay=True, dir_okay=True, readable=True, resolve_path=True)) + type=click.Path( + exists=True, file_okay=True, dir_okay=True, readable=True, resolve_path=True)) + @click.argument('output', nargs=1, required=True, - type=click.Path(exists=False, dir_okay=False, resolve_path=True)) -@click.option('-f', '--format', is_flag=False, default='csv', show_default=True, type=click.Choice(['json', 'csv']), - help='Set OUTPUT file format.') -@click.option('-q', '--quiet', is_flag=True, help='Do not print any error/warning.') + type=click.Path(exists=False, dir_okay=False, resolve_path=True)) + +@click.option('-f', '--format', is_flag=False, default='csv', show_default=True, + type=click.Choice(['json', 'csv']), + help='Set OUTPUT inventory file format.') + +@click.option('-q', '--quiet', is_flag=True, + help='Do not print error or warning messages.') + +@click.help_option('-h', '--help') + def inventory(location, output, quiet, format): """ -Collect a JSON or CSV inventory of components from ABOUT files. +Collect a JSON or CSV inventory of components from .ABOUT files. -LOCATION: Path to an ABOUT file or a directory with ABOUT files. +LOCATION: Path to an .ABOUT file or a directory with .ABOUT files. OUTPUT: Path to the JSON or CSV inventory file to create. """ - click.echo('Running attributecode version ' + __version__) - # Check that the parent directory exists + print_version() + if not exists(os.path.dirname(output)): # FIXME: there is likely a better way to return an error - click.echo('ERROR: Path to the OUTPUT does not exists. Please check and correct the .') + click.echo('ERROR: path does not exists.') + # FIXME: return error code? return - click.echo('Collecting inventory from: ''%(location)s and writing output to: %(output)s' % locals()) + click.echo('Collecting inventory from: %(location)r and writing output to: %(output)r' % locals()) # FIXME: do we really want to continue support zip as an input? if location.lower().endswith('.zip'): @@ -120,110 +155,165 @@ def inventory(location, output, quiet, format): log_errors(errors, quiet, os.path.dirname(output)) -@cli.command(cls=AboutCommand, short_help='LOCATION: input file, OUTPUT: directory',) +###################################################################### +# gen subcommand +###################################################################### + +@cli.command(cls=AboutCommand, + short_help='Generate .ABOUT files from an inventory as CSV or JSON.') + @click.argument('location', nargs=1, required=True, - type=click.Path(exists=True, file_okay=True, readable=True, resolve_path=True)) + type=click.Path(exists=True, file_okay=True, readable=True, resolve_path=True)) + @click.argument('output', nargs=1, required=True, - type=click.Path(exists=True, writable=True, dir_okay=True, resolve_path=True)) + type=click.Path(exists=True, writable=True, dir_okay=True, resolve_path=True)) + @click.option('--fetch-license', type=str, nargs=2, - help=('Fetch licenses text from a DejaCode API. and create .LICENSE side-by-side ' - 'with the generated .ABOUT file using data fetched from a DejaCode License Library. ' - 'The "license" key is needed in the input. ' - 'The following additional options are required:\n\n' - 'api_url - URL to the DejaCode License Library API endpoint\n\n' - 'api_key - DejaCode API key' - - '\nExample syntax:\n\n' - "about gen --fetch-license 'api_url' 'api_key'") - ) + help=('Fetch licenses text from a DejaCode API. and create .LICENSE side-by-side ' + 'with the generated .ABOUT file using data fetched from a DejaCode License Library. ' + 'The "license" key is needed in the input. ' + 'The following additional options are required:\n\n' + 'api_url - URL to the DejaCode License Library API endpoint\n\n' + 'api_key - DejaCode API key' + '\nExample syntax:\n\n' + "about gen --fetch-license 'api_url' 'api_key'") + ) + +# TODO: this option help and long name is obscure and would need to be refactored @click.option('--license-notice-text-location', nargs=1, - type=click.Path(exists=True, dir_okay=True, readable=True, resolve_path=True), - help="Copy the 'license_file' from the directory to the generated location") -@click.option('--mapping', is_flag=True, help='Use for mapping between the input keys and the ABOUT field names - mapping.config') -@click.option('-q', '--quiet', is_flag=True, help='Do not print any error/warning.') + type=click.Path(exists=True, dir_okay=True, readable=True, resolve_path=True), + help="Copy the 'license_file' from the directory to the generated location") + +@click.option('--mapping', is_flag=True, + help='Use file mapping.config with mapping between input keys and ABOUT field names') + +@click.option('-q', '--quiet', is_flag=True, + help='Do not print error or warning messages.') + +@click.help_option('-h', '--help') + def gen(location, output, mapping, license_notice_text_location, fetch_license, quiet): """ -Given an inventory of ABOUT files at location, generate ABOUT files in base -directory. +Generate .ABOUT files in OUTPUT directory from a JSON or CSV inventory of .ABOUT files at LOCATION. LOCATION: Path to a JSON or CSV inventory file. OUTPUT: Path to a directory where ABOUT files are generated. """ - click.echo('Running attributecode version ' + __version__) + print_version() + if not location.endswith('.csv') and not location.endswith('.json'): - click.echo('ERROR: Input file. Only .csv and .json files are supported.') + click.echo('ERROR: Invalid input file format: must be .csv or .json.') + # FIXME: return error code? return - click.echo('Generating ABOUT files...') - errors, abouts = attributecode.gen.generate(location, output, mapping, license_notice_text_location, fetch_license) + click.echo('Generating .ABOUT files...') + + errors, abouts = attributecode.gen.generate( + location=location, base_dir=output, mapping=mapping, + license_notice_text_location=license_notice_text_location, + fetch_license=fetch_license) - number_of_about_file = len(abouts) - number_of_error = 0 + about_count = len(abouts) + error_count = 0 for e in errors: # Only count as warning/error if CRITICAL, ERROR and WARNING if e.severity > 20: - number_of_error = number_of_error + 1 - click.echo('Generated %(number_of_about_file)d ABOUT files with %(number_of_error)d errors and/or warning' % locals()) + error_count = error_count + 1 + click.echo( + 'Generated %(about_count)d .ABOUT files with %(error_count)d errors or warnings' % locals()) log_errors(errors, quiet, output) + # FIXME: return error code? + + +###################################################################### +# attrib subcommand +###################################################################### + +@cli.command(cls=AboutCommand, + short_help='Generate an attribution document from .ABOUT files.') + +@click.argument('location', nargs=1, required=True, + type=click.Path(exists=True, readable=True, resolve_path=True)) + +@click.argument('output', nargs=1, required=True, + type=click.Path(exists=False, writable=True, resolve_path=True)) + +@click.option('--inventory', required=False, + type=click.Path(exists=True, file_okay=True, resolve_path=True), + help='Path to an optional JSON or CSV inventory file listing the ' + 'subset of .ABOUT files path to consider when generating attribution ' + ) +@click.option('--mapping', is_flag=True, + help='Use the file "mapping.config" with mappings between the CSV ' + 'inventory columns names and .ABOUT field names') -@cli.command(cls=AboutCommand, short_help='LOCATION: directory, OUTPUT: output file') -@click.argument('location', nargs=1, required=True, type=click.Path(exists=True, readable=True, resolve_path=True)) -@click.argument('output', nargs=1, required=True, type=click.Path(exists=False, writable=True, resolve_path=True)) -@click.option('--inventory', required=False, type=click.Path(exists=True, file_okay=True, resolve_path=True), - help='Path to an inventory file') -@click.option('--mapping', is_flag=True, help='Use for mapping between the input keys and the ABOUT field names - mapping.config') @click.option('--template', type=click.Path(exists=True), nargs=1, - help='Path to a custom attribution template') -@click.option('-q', '--quiet', is_flag=True, help='Do not print any error/warning.') + help='Path to an optional custom attribution template used for generation.') + +@click.option('-q', '--quiet', is_flag=True, + help='Do not print error or warning messages.') + +@click.help_option('-h', '--help') + def attrib(location, output, template, mapping, inventory, quiet): """ -Generate an attribution OUTPUT document using the directory of ABOUT files at -LOCATION. You can provide a custom template file. You can also provide an inventory -file listing the subset of ABOUT files path to consider when generating -attribution and its column mapping file. +Generate an attribution document at OUTPUT using .ABOUT files at LOCATION. -LOCATION: Path to an ABOUT file or a directory containing ABOUT files. +LOCATION: Path to an .ABOUT file, a directory containing .ABOUT files or a .zip archive containing .ABOUT files. OUTPUT: Path to output file to write the attribution to. """ - click.echo('Running attributecode version ' + __version__) + print_version() click.echo('Generating attribution...') + # accept zipped ABOUT files as input if location.lower().endswith('.zip'): - # accept zipped ABOUT files as input location = extract_zip(location) - if mapping: - attributecode.util.have_mapping = True + inv_errors, abouts = model.collect_inventory(location) + no_match_errors = attributecode.attrib.generate_and_save( + abouts=abouts, output_location=output, + use_mapping=mapping, template_loc=template, + inventory_location=inventory) - err, abouts = model.collect_inventory(location) - no_match_errors = attributecode.attrib.generate_and_save(abouts, output, mapping, - template_loc=template, - inventory_location=inventory) - errors = [] - for e in err: - errors.append(e) for no_match_error in no_match_errors: - errors.append(no_match_error) - log_errors(errors, quiet, os.path.dirname(output)) + inv_errors.append(no_match_error) + + log_errors(inv_errors, quiet, os.path.dirname(output)) click.echo('Finished.') + # FIXME: return error code? + + +###################################################################### +# check subcommand +###################################################################### +@cli.command(cls=AboutCommand, short_help='Validate that the format of .ABOUT files is correct.') + +@click.argument('location', nargs=1, required=True, + type=click.Path(exists=True, readable=True, resolve_path=True)) + +@click.option('--show-all', is_flag=True, default=False, + help='Show all errors and warnings. ' + 'By default, running a check only reports these ' + 'error levels: CRITICAL, ERROR, and WARNING. ' + 'Use this option to report all errors and warning ' + 'for any level.' +) + +@click.help_option('-h', '--help') -@cli.command(cls=AboutCommand, short_help='LOCATION: directory') -@click.argument('location', nargs=1, required=True, type=click.Path(exists=True, readable=True, resolve_path=True)) -@click.option('--show-all', is_flag=True, help='Show all the errors and warning') def check(location, show_all): """ -Validating ABOUT files at LOCATION. [Default: it will only shows the following -level of errors: 'CRITICAL', 'ERROR', and 'WARNING'. -Use the `--show-all` option to show all kind of errors. +Check and validate .ABOUT file(s) at LOCATION for errors and +print error messages on the terminal. -LOCATION: Path to an ABOUT file or a directory containing ABOUT files. +LOCATION: Path to a .ABOUT file or a directory containing .ABOUT files. """ - click.echo('Running attributecode version ' + __version__) + click.echo('Running aboutcode-toolkit version ' + __version__) click.echo('Checking ABOUT files...') errors, abouts = attributecode.model.collect_inventory(location) @@ -233,10 +323,9 @@ def check(location, show_all): for severity, message in errors: sever = severities[severity] if show_all: - print_errors.append((msg_format % locals())) - else: - if sever in problematic_errors: - print_errors.append((msg_format % locals())) + print_errors.append(msg_format % locals()) + elif sever in problematic_errors: + print_errors.append(msg_format % locals()) number_of_errors = len(print_errors) @@ -244,15 +333,18 @@ def check(location, show_all): print(err) if print_errors: - click.echo('Found %(number_of_errors)d errors' % locals()) + click.echo('Found {} errors.'.format(number_of_errors)) + # FIXME: not sure this is the right way to exit with a retrun code sys.exit(1) else: - click.echo('No error is found.') + click.echo('No error found.') + # FIXME: return error code? + def log_errors(errors, quiet, base_dir=False): """ - Iterate of sequence of Error objects and print and log errors with a severity - superior or equal to level. + Iterate of sequence of Error objects and print and log errors with + a severity superior or equal to level. """ logger = logging.getLogger(__name__) handler = logging.StreamHandler() @@ -262,6 +354,8 @@ def log_errors(errors, quiet, base_dir=False): file_logger = logging.getLogger(__name__ + '_file') msg_format = '%(sever)s: %(message)s' + + # FIXME: do not create log file if there are NO errors # Create error.log if base_dir: bdir = to_posix(base_dir) @@ -272,6 +366,7 @@ def log_errors(errors, quiet, base_dir=False): file_handler = logging.FileHandler(log_path) file_logger.addHandler(file_handler) + for severity, message in errors: sever = severities[severity] if not quiet: diff --git a/src/attributecode/gen.py b/src/attributecode/gen.py index 7d49d382..b19e6a74 100644 --- a/src/attributecode/gen.py +++ b/src/attributecode/gen.py @@ -16,21 +16,27 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals import codecs from collections import OrderedDict import logging import posixpath -import unicodecsv +import sys +if sys.version_info[0] < 3: + # Python 2 + import backports.csv as csv +else: + # Python 3 + import csv from attributecode import ERROR from attributecode import CRITICAL from attributecode import Error from attributecode import model -from attributecode import util -from attributecode.model import verify_license_files_in_location from attributecode.model import check_file_field_exist +from attributecode import util from attributecode.util import add_unc from attributecode.util import to_posix @@ -47,12 +53,14 @@ def check_duplicated_columns(location): """ - Return a list of errors for duplicated column names in a CSV file at location. + Return a list of errors for duplicated column names in a CSV file + at location. """ location = add_unc(location) + # FIXME: why ignore errors? with codecs.open(location, 'rb', encoding='utf-8', errors='ignore') as csvfile: - reader = unicodecsv.UnicodeReader(csvfile) - columns = reader.next() + reader = csv.reader(csvfile) + columns = next(reader) columns = [col for col in columns] seen = set() @@ -97,10 +105,15 @@ def check_duplicated_about_file_path(inventory_dict): return errors -def load_inventory(mapping, location, base_dir, license_notice_text_location=None): +def load_inventory(location, base_dir, license_notice_text_location=None, + use_mapping=False): """ - Load the inventory file at location. Return a list of errors and a list of About - objects validated against the base_dir. + Load the inventory file at `location` for ABOUT and LICENSE files + stored in the `base_dir`. Return a list of errors and a list of + About objects validated against the base_dir. + Optionally use `license_notice_text_location` as the location of + license and notice texts. + Optionally use mappings for field names if `use_mapping` is True. """ errors = [] abouts = [] @@ -110,9 +123,9 @@ def load_inventory(mapping, location, base_dir, license_notice_text_location=Non if dup_cols_err: errors.extend(dup_cols_err) return errors, abouts - inventory = util.load_csv(mapping, location) + inventory = util.load_csv(location, use_mapping) else: - inventory = util.load_json(mapping, location) + inventory = util.load_json(location, use_mapping) try: dup_about_paths_err = check_duplicated_about_file_path(inventory) @@ -120,15 +133,15 @@ def load_inventory(mapping, location, base_dir, license_notice_text_location=Non errors.extend(dup_about_paths_err) return errors, abouts except: - msg = ("The essential field 'about_file_path' is not found.") + msg = "The essential field 'about_file_path' is not found." errors.append(Error(CRITICAL, msg)) return errors, abouts for i, fields in enumerate(inventory): # check does the input contains the required fields - requied_fileds = model.About.required_fields + required_fields = model.About.required_fields - for f in requied_fileds: + for f in required_fields: if f not in fields: msg = ( "Required column: %(f)r not found.\n" @@ -142,7 +155,7 @@ def load_inventory(mapping, location, base_dir, license_notice_text_location=Non afp = fields.get(model.About.about_file_path_attr) if not afp or not afp.strip(): - msg = 'Empty column: %(afp)r. Cannot generate ABOUT file.' % locals() + msg = 'Empty column: %(afp)r. Cannot generate .ABOUT file.' % locals() errors.append(Error(ERROR, msg)) continue else: @@ -164,10 +177,11 @@ def load_inventory(mapping, location, base_dir, license_notice_text_location=Non return errors, abouts -def generate(location, base_dir, mapping, license_notice_text_location, fetch_license, policy=None, conf_location=None, - with_empty=False, with_absent=False): +def generate(location, base_dir, license_notice_text_location=None, + fetch_license=False, policy=None, conf_location=None, + with_empty=False, with_absent=False, use_mapping=False): """ - Load ABOUT data from an inventory at csv_location. Write ABOUT files to + Load ABOUT data from a CSV inventory at `location`. Write ABOUT files to base_dir using policy flags and configuration file at conf_location. Policy defines which action to take for merging or overwriting fields and files. Return errors and about objects. @@ -178,12 +192,16 @@ def generate(location, base_dir, mapping, license_notice_text_location, fetch_li # Check if the fetch_license contains valid argument if fetch_license: # Strip the ' and " for api_url, and api_key from input - api_url = fetch_license[0].strip("'").strip("\"") - api_key = fetch_license[1].strip("'").strip("\"") + api_url = fetch_license[0].strip("'").strip('"') + api_key = fetch_license[1].strip("'").strip('"') gen_license = True bdir = to_posix(base_dir) - errors, abouts = load_inventory(mapping, location, bdir, license_notice_text_location) + errors, abouts = load_inventory( + location=location, + base_dir=bdir, + license_notice_text_location=license_notice_text_location, + use_mapping=use_mapping) if gen_license: license_dict, err = model.pre_process_and_fetch_license_dict(abouts, api_url, api_key) @@ -274,7 +292,7 @@ def generate(location, base_dir, mapping, license_notice_text_location, fetch_li except Exception as e: # only keep the first 100 char of the exception emsg = repr(e)[:100] - msg = (u'Failed to write ABOUT file at : ' + msg = (u'Failed to write .ABOUT file at : ' u'%(dump_loc)s ' u'with error: %(emsg)s' % locals()) errors.append(Error(ERROR, msg)) @@ -291,4 +309,4 @@ def deduplicate(sequence): for item in sequence: if item not in deduped: deduped.append(item) - return deduped \ No newline at end of file + return deduped diff --git a/src/attributecode/licenses.py b/src/attributecode/licenses.py index e24745b4..49ae9c9e 100644 --- a/src/attributecode/licenses.py +++ b/src/attributecode/licenses.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2013-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,6 +14,10 @@ # limitations under the License. # ============================================================================ +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + # Common license keys COMMON_LICENSES = ( 'aes-128-3.0', diff --git a/src/attributecode/model.py b/src/attributecode/model.py index 4de61401..d29395c4 100644 --- a/src/attributecode/model.py +++ b/src/attributecode/model.py @@ -14,26 +14,37 @@ # ============================================================================ """ -AboutCode is a tool to process ABOUT files. ABOUT files are small text files -that document the provenance (aka. the origin and license) of software -components as well as the essential obligation such as attribution/credits and -source code redistribution. See the ABOUT spec at http://dejacode.org. - -AbouCode reads and validates ABOUT files and collect software components -inventories. +AboutCode toolkit is a tool to process ABOUT files. ABOUT files are +small text files that document the provenance (aka. the origin and +license) of software components as well as the essential obligation +such as attribution/credits and source code redistribution. See the +ABOUT spec at http://dejacode.org. + +AboutCode toolkit reads and validates ABOUT files and collect software +components inventories. """ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals +from collections import OrderedDict import codecs import json import os import posixpath -import re -import unicodecsv -from collections import OrderedDict from posixpath import dirname +import re +import sys + +if sys.version_info[0] < 3: + # Python 2 + import backports.csv as csv +else: + # Python 3 + import csv + +from license_expression import Licensing try: import urllib2 # Python 2 @@ -52,14 +63,17 @@ from attributecode import CRITICAL from attributecode import ERROR -from attributecode import Error from attributecode import INFO from attributecode import WARNING from attributecode import api +from attributecode import Error from attributecode import saneyaml from attributecode import util -from attributecode.util import add_unc, UNC_PREFIX, UNC_PREFIX_POSIX, on_windows, copy_license_notice_files -from license_expression import Licensing +from attributecode.util import add_unc +from attributecode.util import copy_license_notice_files +from attributecode.util import on_windows +from attributecode.util import UNC_PREFIX +from attributecode.util import UNC_PREFIX_POSIX class Field(object): @@ -174,9 +188,10 @@ def serialize(self): value = u' '.join(value) else: value = u''.join(value) - serialized = u'%(name)s: %(value)s' % locals() - else: - serialized = u'%(name)s:' % locals() + + serialized = u'%(name)s:' % locals() + if value: + serialized += ' ' + '%(value)s' % locals() return serialized def serialized_value(self): @@ -384,10 +399,12 @@ def _validate(self, *args, **kwargs): name = self.name # FIXME: This is a temp fix for #286 - # The field in ignore_checking_list is validated in the check_file_field_exist function + # The field in ignore_checking_list is validated in the check_file_field_exist function ignore_checking_list = [u'license_file', u'notice_file', u'changelog_file'] + # mapping of normalized paths to a location or None paths = OrderedDict() + for path in self.value: path = path.strip() path = util.to_posix(path) @@ -404,42 +421,45 @@ def _validate(self, *args, **kwargs): # the license files, if need to be copied, are located under the path # set from the 'license-text-location' option, so the tool should check # at the 'license-text-location' instead of the 'base_dir' - if self.base_dir or self.license_notice_text_location: - if self.license_notice_text_location and name in ignore_checking_list: - location = posixpath.join(self.license_notice_text_location, path) - else: - # The 'about_resource_path' should be a joined path with - # the 'about_file_path' and the 'base_dir - if not self.running_inventory and self.about_file_path: - # Get the parent directory of the 'about_file_path' - afp_parent = posixpath.dirname(self.about_file_path) - - # Create a relative 'about_resource_path' by joining the - # parent of the 'about_file_path' with the value of the - # 'about_resource_path' - arp = posixpath.join(afp_parent, path) - normalized_arp = posixpath.normpath(arp).strip(posixpath.sep) - location = posixpath.join(self.base_dir, normalized_arp) - else: - location = posixpath.join(self.base_dir, path) - location = util.to_native(location) - location = os.path.abspath(os.path.normpath(location)) - location = util.to_posix(location) - location = add_unc(location) - - if not os.path.exists(location): - # We don't want to show the UNC_PREFIX in the error message - location = util.to_posix(location.strip(UNC_PREFIX)) - if not name in ignore_checking_list: - msg = (u'Field %(name)s: Path %(location)s not found' - % locals()) - errors.append(Error(CRITICAL, msg)) - location = None - else: + if not (self.base_dir or self.license_notice_text_location): msg = (u'Field %(name)s: Unable to verify path: %(path)s:' u' No base directory provided' % locals()) errors.append(Error(ERROR, msg)) location = None + paths[path] = location + continue + + if self.license_notice_text_location and name in ignore_checking_list: + location = posixpath.join(self.license_notice_text_location, path) + else: + # The 'about_resource_path' should be a joined path with + # the 'about_file_path' and the 'base_dir + if not self.running_inventory and self.about_file_path: + # Get the parent directory of the 'about_file_path' + afp_parent = posixpath.dirname(self.about_file_path) + + # Create a relative 'about_resource_path' by joining the + # parent of the 'about_file_path' with the value of the + # 'about_resource_path' + arp = posixpath.join(afp_parent, path) + normalized_arp = posixpath.normpath(arp).strip(posixpath.sep) + location = posixpath.join(self.base_dir, normalized_arp) + else: + location = posixpath.join(self.base_dir, path) + + location = util.to_native(location) + location = os.path.abspath(os.path.normpath(location)) + location = util.to_posix(location) + location = add_unc(location) + + if not os.path.exists(location): + # We don't want to show the UNC_PREFIX in the error message + location = util.to_posix(location.strip(UNC_PREFIX)) + if not name in ignore_checking_list: + msg = (u'Field %(name)s: Path %(location)s not found' + % locals()) + errors.append(Error(CRITICAL, msg)) + location = None paths[path] = location @@ -506,7 +526,8 @@ def _validate(self, *args, **kwargs): try: # TODO: we have lots the location by replacing it with a text location = add_unc(location) - text = codecs.open(location, encoding='utf-8', errors='ignore').read() + with codecs.open(location, encoding='utf-8', errors='ignore') as txt: + text = txt.read() self.value[path] = text except Exception as e: # only keep the first 100 char of the exception @@ -593,7 +614,7 @@ def has_content(self): def _serialized_value(self): # default normalized values for serialization - if self.value is True: + if self.value: return u'yes' elif self.value is False: return u'no' @@ -611,7 +632,8 @@ def __eq__(self, other): and self.value == other.value) -def validate_fields(fields, about_file_path, running_inventory, base_dir, license_notice_text_location=None): +def validate_fields(fields, about_file_path, running_inventory, base_dir, + license_notice_text_location=None): """ Validate a sequence of Field objects. Return a list of errors. Validation may update the Field objects as needed as a side effect. @@ -648,7 +670,7 @@ def create_fields(self): """ self.fields = OrderedDict([ ('about_resource', ListField(required=True)), - #('about_resource', AboutResourceField(required=True)), + # ('about_resource', AboutResourceField(required=True)), ('name', SingleLineField(required=True)), ('about_resource_path', AboutResourceField()), @@ -822,14 +844,14 @@ def as_dict(self, with_paths=False, with_absent=True, with_empty=True): # Return an empty 'about_resource_path' if the 'about_resource' # key is not found else: - as_dict[arpa] = '' + as_dict[arpa] = '' for field in self.all_fields(with_absent=with_absent, with_empty=with_empty): as_dict[field.name] = field.serialized_value() return as_dict - def hydrate(self, fields): + def hydrate(self, fields, use_mapping=False): """ Process an iterable of field (name, value) tuples. Update or create Fields attributes and the fields and custom fields dictionaries. @@ -837,10 +859,12 @@ def hydrate(self, fields): """ errors = [] seen_fields = OrderedDict() - if util.have_mapping: - mapping = util.get_mappings(None) + + mapping = {} + if use_mapping: + mapping = util.get_mapping() + for name, value in fields: - # normalize to lower case orig_name = name name = name.lower() previous_value = seen_fields.get(name) @@ -862,59 +886,65 @@ def hydrate(self, fields): standard_field.original_value = value standard_field.value = value standard_field.present = True - else: - if util.have_mapping: - if name in mapping.keys(): - # this is a special attribute - if name == self.about_file_path_attr: - setattr(self, self.about_file_path_attr, value) - continue - - # this is a special attribute, skip entirely - if name == self.about_resource_path_attr: - continue - - msg = (u'Field %(orig_name)s is a custom field') - errors.append(Error(INFO, msg % locals())) - custom_field = self.custom_fields.get(name) - if custom_field: - custom_field.original_value = value - custom_field.value = value - custom_field.present = True - else: - if name in dir(self): - msg = (u'Field %(orig_name)s has an ' - u'illegal reserved name') - errors.append(Error(ERROR, msg % locals())) - else: - # custom fields are always handled as StringFields - custom_field = StringField(name=name, - value=value, - present=True) - self.custom_fields[name] = custom_field - try: - setattr(self, name, custom_field) - except: - # The intended captured error message should display - # the line number of where the invalid line is, - # but I am not able to get the line number from - # the original code. By-passing the line number - # for now. - # msg = u'Invalid line: %(line)d: %(orig_name)r' - msg = u'Invalid line: %(orig_name)r: ' % locals() - msg += u'%s' % custom_field.value - errors.append(Error(CRITICAL, msg)) - else: - msg = (u'Field %(orig_name)s is not a supported field and is not ' + - u'defined in the mapping file. This field is ignored.') - errors.append(Error(INFO, msg % locals())) - else: - if not name == self.about_file_path_attr: - msg = (u'Field %(orig_name)s is not a supported field and is ignored.') - errors.append(Error(INFO, msg % locals())) + continue + + if not use_mapping: + if not name == self.about_file_path_attr: + msg = (u'Field %(orig_name)s is not a supported field and is ignored.') + errors.append(Error(INFO, msg % locals())) + continue + + if name not in mapping.keys(): + msg = (u'Field %(orig_name)s is not a supported field and is not ' + + u'defined in the mapping file. This field is ignored.') + errors.append(Error(INFO, msg % locals())) + continue + + # this is a special attribute + if name == self.about_file_path_attr: + setattr(self, self.about_file_path_attr, value) + continue + + # this is a special attribute, skip entirely + if name == self.about_resource_path_attr: + continue + + msg = (u'Field %(orig_name)s is a custom field') + errors.append(Error(INFO, msg % locals())) + custom_field = self.custom_fields.get(name) + if custom_field: + custom_field.original_value = value + custom_field.value = value + custom_field.present = True + continue + + if name in dir(self): + msg = (u'Field %(orig_name)s has an ' + u'illegal reserved name') + errors.append(Error(ERROR, msg % locals())) + continue + + # custom fields are always handled as StringFields + custom_field = StringField(name=name, + value=value, + present=True) + self.custom_fields[name] = custom_field + try: + setattr(self, name, custom_field) + except: + # The intended captured error message should display + # the line number of where the invalid line is, + # but I am not able to get the line number from + # the original code. By-passing the line number + # for now. + # msg = u'Invalid line: %(line)d: %(orig_name)r' + msg = u'Invalid line: %(orig_name)r: ' % locals() + msg += u'%s' % custom_field.value + errors.append(Error(CRITICAL, msg)) return errors - def process(self, fields, about_file_path, running_inventory=False, base_dir=None, license_notice_text_location=None): + def process(self, fields, about_file_path, running_inventory=False, + base_dir=None, license_notice_text_location=None, use_mapping=False): """ Hydrate and validate a sequence of field name/value tuples from an ABOUT file. Return a list of errors. @@ -923,20 +953,24 @@ def process(self, fields, about_file_path, running_inventory=False, base_dir=Non self.license_notice_text_location = license_notice_text_location afp = self.about_file_path errors = [] - hydratation_errors = self.hydrate(fields) + hydratation_errors = self.hydrate(fields, use_mapping=use_mapping) errors.extend(hydratation_errors) # We want to copy the license_files before the validation if license_notice_text_location: - copy_license_notice_files(fields, base_dir, license_notice_text_location, afp) + copy_license_notice_files( + fields, base_dir, license_notice_text_location, afp) # we validate all fields, not only these hydrated all_fields = self.all_fields() - validation_errors = validate_fields(all_fields, about_file_path, running_inventory, self.base_dir, self.license_notice_text_location) + validation_errors = validate_fields( + all_fields, about_file_path, running_inventory, + self.base_dir, self.license_notice_text_location) errors.extend(validation_errors) - # do not forget to resolve about resource paths - # The 'about_resource' field is now a ListField and those do not need to resolve + # do not forget to resolve about resource paths The + # 'about_resource' field is now a ListField and those do not + # need to resolve # self.about_resource.resolve(self.about_file_path) return errors @@ -951,7 +985,8 @@ def load(self, location): errors = [] try: loc = add_unc(loc) - input_text = codecs.open(loc, encoding='utf-8').read() + with codecs.open(loc, encoding='utf-8') as txt: + input_text = txt.read() """ The running_inventory defines if the current process is 'inventory' or not. This is used for the validation of the about_resource_path. @@ -992,7 +1027,8 @@ def load_lines(self, lines, base_dir): self.errors = errors return errors - def load_dict(self, fields_dict, base_dir, running_inventory=False, license_notice_text_location=None, with_empty=True): + def load_dict(self, fields_dict, base_dir, running_inventory=False, + license_notice_text_location=None, with_empty=True): """ Load the ABOUT file from a fields name/value mapping. If with_empty, create fields with no value for empty fields. @@ -1003,7 +1039,9 @@ def load_dict(self, fields_dict, base_dir, running_inventory=False, license_noti about_file_path = self.about_file_path if not with_empty: fields = [(n, v) for n, v in fields_dict.items() if v] - errors = self.process(fields, about_file_path, running_inventory, base_dir, license_notice_text_location) + errors = self.process( + fields, about_file_path, running_inventory, base_dir, + license_notice_text_location) self.errors = errors return errors @@ -1211,7 +1249,7 @@ def field_names(abouts, with_paths=True, with_absent=True, with_empty=True): fields = [] if with_paths: fields.append(About.about_file_path_attr) - #fields.append(About.about_resource_path_attr) + # fields.append(About.about_resource_path_attr) standard_fields = About().fields.keys() if with_absent: @@ -1279,7 +1317,7 @@ def write_output(abouts, location, format, with_absent=False, with_empty=True): with codecs.open(location, mode='wb', encoding='utf-8') as output_file: if format == 'csv': fieldnames = field_names(abouts) - writer = unicodecsv.DictWriter(output_file, fieldnames) + writer = csv.DictWriter(output_file, fieldnames) writer.writeheader() for row in about_dictionary_list: # See https://github.com/dejacode/about-code-tool/issues/167 @@ -1432,9 +1470,10 @@ def parse_license_expression(lic_expression): return special_char, lic_list def special_char_in_license_expresion(lic_expression): - not_support_char = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', - '+', '=', '{', '}', '|', '[', ']', '\\', - ':', ';', '<', '>', '?', ',', '/'] + not_support_char = [ + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '+', '=', '{', '}', '|', '[', ']', '\\', + ':', ';', '<', '>', '?', ',', '/'] special_character = [] for char in not_support_char: if char in lic_expression: diff --git a/src/attributecode/saneyaml.py b/src/attributecode/saneyaml.py index 10dbe482..e20b51f6 100644 --- a/src/attributecode/saneyaml.py +++ b/src/attributecode/saneyaml.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2015-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2015-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,14 +14,15 @@ # limitations under the License. # ============================================================================ - from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals from collections import OrderedDict from functools import partial import yaml + try: from yaml import CSafeLoader as SafeLoader from yaml import CSafeDumper as SafeDumper @@ -34,6 +35,11 @@ except NameError: unicode = str # Python 3 +try: + basestring # Python 2 +except NameError: + basestring = str # Python 3 + """ Wrapper around PyYAML to provide sane defaults ensuring that dump/load does diff --git a/src/attributecode/util.py b/src/attributecode/util.py index 62bfe130..2d8e7987 100644 --- a/src/attributecode/util.py +++ b/src/attributecode/util.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2013-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -15,29 +15,39 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals +from collections import OrderedDict import codecs import errno import json import ntpath import os +from os.path import abspath +from os.path import dirname +from os.path import join import posixpath import shutil import socket import string import sys -import unicodecsv -from collections import OrderedDict -from os.path import abspath -from os.path import dirname -from os.path import join + +if sys.version_info[0] < 3: + # Python 2 + import backports.csv as csv +else: + # Python 3 + import csv try: - import httplib # Python 2 + # Python 2 + import httplib except ImportError: - import http.client as httplib # Python 3 + # Python 3 + import http.client as httplib -from attributecode import CRITICAL, Error +from attributecode import CRITICAL +from attributecode import Error on_windows = 'win32' in sys.platform @@ -60,8 +70,6 @@ def to_posix(path): valid_file_chars = string.digits + string.ascii_letters + '_-.' -have_mapping = False - def invalid_chars(path): """ @@ -133,9 +141,6 @@ def get_locations(location): a file or a directory tree containing ABOUT files. File locations are normalized using posix path separators. """ - # See https://bugs.python.org/issue4071 - if on_windows: - location = unicode(location) location = add_unc(location) location = get_absolute(location) assert os.path.exists(location) @@ -197,7 +202,7 @@ def norm(p): relative = path[len(base) + 1:] # We don't want to keep the first segment of the root of the returned path. # See https://github.com/nexB/attributecode/issues/276 - #relative = posixpath.join(base_name, relative) + # relative = posixpath.join(base_name, relative) return relative @@ -230,30 +235,56 @@ def resource_name(path): return right.strip() -class OrderedDictReader(unicodecsv.DictReader): - """ - A DictReader that return OrderedDicts - """ - def next(self): - row_dict = unicodecsv.DictReader.next(self) - result = OrderedDict() - # reorder based on fieldnames order - for name in self.fieldnames: - result[name] = row_dict[name] - return result - - -def get_mappings(location=None): +# Python 3 +OrderedDictReader = csv.DictReader + +if sys.version_info[0] < 3: + # Python 2 + class OrderedDictReader(csv.DictReader): + """ + A DictReader that return OrderedDicts + Copied from csv.DictReader itself backported from Python 3 + license: python + """ + def __next__(self): + if self.line_num == 0: + # Used only for its side effect. + self.fieldnames + row = next(self.reader) + self.line_num = self.reader.line_num + + # unlike the basic reader, we prefer not to return blanks, + # because we will typically wind up with a dict full of None + # values + while row == []: + row = next(self.reader) + d = OrderedDict(zip(self.fieldnames, row)) + lf = len(self.fieldnames) + lr = len(row) + if lf < lr: + d[self.restkey] = row[lf:] + elif lf > lr: + for key in self.fieldnames[lr:]: + d[key] = self.restval + return d + + next = __next__ + + +def get_mapping(location=None): """ Return a mapping of user key names to About key names by reading the mapping.config file from location or the directory of this source file if location was not provided. """ if not location: - location = abspath(dirname(__file__)) - mappings = {} + location = join(abspath(dirname(__file__)), 'mapping.config') + if not os.path.exists(location): + return {} + + mapping = {} try: - with open(join(location, 'mapping.config'), 'rU') as mapping_file: + with open(location) as mapping_file: for line in mapping_file: if not line or not line.strip() or line.strip().startswith('#'): continue @@ -263,29 +294,38 @@ def get_mappings(location=None): key, sep, value = line.partition(':') about_key = key.strip().replace(' ', '_') user_key = value.strip() - mappings[about_key] = user_key + mapping[about_key] = user_key except Exception as e: print(repr(e)) print('Cannot open or process mapping.config file at %(location)r.' % locals()) - # this is rather brutal + # FIXME: this is rather brutal sys.exit(errno.EACCES) - return mappings + return mapping -def apply_mappings(abouts, mappings=None): +def apply_mapping(abouts, alternate_mapping=None): """ - Given a list of About data dictionaries and a dictionary of mappings, - return a new About data dictionaries list where the keys have been - replaced by the About mapped_abouts key if present. + Given a list of About data dictionaries and a dictionary of + mapping, return a new About data dictionaries list where the keys + have been replaced by the About mapped_abouts key if present. Load + the mapping from the default mnapping.config if an alternate + mapping dict is not provided. """ - mappings = mappings or get_mappings() + if alternate_mapping: + mapping = alternate_mapping + else: + mapping = get_mapping() + + if not mapping: + return abouts + mapped_abouts = [] for about in abouts: - mapped_about = {} + mapped_about = OrderedDict() for key in about: mapped = [] - for mapping_keys, input_keys in mappings.items(): + for mapping_keys, input_keys in mapping.items(): if key == input_keys: mapped.append(mapping_keys) if not mapped: @@ -296,54 +336,50 @@ def apply_mappings(abouts, mappings=None): return mapped_abouts -def get_about_file_path(mapping, location): +def get_about_file_path(location, use_mapping=False): """ Read file at location, return a list of about_file_path. """ afp_list = [] if location.endswith('.csv'): - about_data = load_csv(mapping, location) + about_data = load_csv(location, use_mapping=use_mapping) else: - about_data = load_json(mapping, location) + about_data = load_json(location, use_mapping=use_mapping) for about in about_data: afp_list.append(about['about_file_path']) return afp_list -def load_csv(mapping, location): +def load_csv(location, use_mapping=False): """ - Read CSV at location, return a list of ordered mappings, one for each row. + Read CSV at location, return a list of ordered dictionaries, one + for each row. """ - global have_mapping - have_mapping = mapping - results = [] - with codecs.open(location, mode='rb', encoding='utf-8', errors='ignore') as csvfile: + # FIXME: why ignore encoding errors here? + with codecs.open(location, mode='rb', encoding='utf-8', + errors='ignore') as csvfile: for row in OrderedDictReader(csvfile): - input_row = {} - # convert all the column keys to lower case as the same behavior as - # when user use the --mapping - for key in row.keys(): - input_row[key.lower()] = row[key] - results.append(input_row) - # user has the mapping option set - if mapping: - results = apply_mappings(results) + # convert all the column keys to lower case as the same + # behavior as when user use the --mapping + updated_row = OrderedDict( + [(key.lower(), value) for key, value in row.items()] + ) + results.append(updated_row) + if use_mapping: + results = apply_mapping(results) return results -def load_json(mapping, location): +def load_json(location, use_mapping=False): """ Read JSON at location, return a list of ordered mappings, one for each entry. """ - global have_mapping - have_mapping = mapping - with open(location) as json_file: results = json.load(json_file) - if mapping: - results = apply_mappings(results) + if use_mapping: + results = apply_mapping(results) return results diff --git a/tests/test_api.py b/tests/test_api.py index d94988b3..42f8936e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,14 +16,17 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals import unittest + from mock import patch import attributecode from attributecode import api from attributecode.api import LicenseInfo + class ApiTest(unittest.TestCase): def test_build_api_url(self): diff --git a/tests/test_attrib.py b/tests/test_attrib.py index a945c42e..154dccc0 100644 --- a/tests/test_attrib.py +++ b/tests/test_attrib.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,6 +16,7 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals import unittest @@ -31,27 +32,30 @@ def test_check_template(self): assert attrib.check_template('template_string') == None assert attrib.check_template('{{template_string') == (1, "unexpected end of template, expected 'end of print statement'.",) - template = open(get_test_loc('attrib_gen/test.template')).read() + with open(get_test_loc('attrib_gen/test.template')) as tmpl: + template = tmpl.read() assert attrib.check_template(template) == None def test_check_template_default_is_valid(self): - template = open(attrib.default_template).read() + with open(attrib.default_template) as tmpl: + template = tmpl.read() assert attrib.check_template(template) == None def test_generate(self): expected = (u'Apache HTTP Server: 2.4.3\n' u'resource: httpd-2.4.3.tar.gz\n') test_file = get_test_loc('attrib_gen/attrib.ABOUT') - template = open(get_test_loc('attrib_gen/test.template')).read() + with open(get_test_loc('attrib_gen/test.template')) as tmpl: + template = tmpl.read() _errors, abouts = model.collect_inventory(test_file) result = attrib.generate(abouts, template) self.assertEqual(expected, result) def test_generate_from_file_with_default_template(self): - self.maxDiff = None test_file = get_test_loc('attrib_gen/attrib.ABOUT') _errors, abouts = model.collect_inventory(test_file) result = attrib.generate_from_file(abouts) - expected = unicode(open(get_test_loc('attrib_gen/expected_default_attrib.html')).read()) + with open(get_test_loc('attrib_gen/expected_default_attrib.html')) as exp: + expected = exp.read() self.assertEqual([x.rstrip() for x in expected.splitlines()], [x.rstrip() for x in result.splitlines()]) diff --git a/tests/test_cmd.py b/tests/test_cmd.py index 46735212..d1e2fce1 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,36 +16,19 @@ from __future__ import absolute_import from __future__ import print_function - -import unittest +from __future__ import unicode_literals from attributecode import CRITICAL from attributecode import DEBUG from attributecode import ERROR -from attributecode import Error from attributecode import INFO from attributecode import NOTSET from attributecode import WARNING from attributecode import cmd -from attributecode import util - - - -class CmdTest(unittest.TestCase): - - def check_csv(self, expected, result): - """ - Compare two CSV files at locations as lists of ordered items. - """ - def as_items(csvfile): - mapping = None - return sorted([i.items() for i in util.load_csv(mapping, csvfile)]) +from attributecode import Error - expected = as_items(expected) - result = as_items(result) - assert expected == result -# NB: this test depends on py.test stdout/err capture capabilities +# NB: these tests depends on py.test stdout/err capture capabilities def test_log_errors(capsys): quiet = False errors = [Error(CRITICAL, 'msg1'), @@ -67,6 +50,7 @@ def test_log_errors(capsys): assert '' == err assert expected_out == out + def test_log_errors_with_quiet(capsys): quiet = True errors = [Error(CRITICAL, 'msg1'), diff --git a/tests/test_gen.py b/tests/test_gen.py index c2963494..97b6bb13 100644 --- a/tests/test_gen.py +++ b/tests/test_gen.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,19 +16,18 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals -import posixpath -import unittest from collections import OrderedDict +import unittest -from testing_utils import get_test_loc from testing_utils import get_temp_dir +from testing_utils import get_test_loc -from attributecode import Error from attributecode import ERROR from attributecode import INFO from attributecode import CRITICAL - +from attributecode import Error from attributecode import gen @@ -54,13 +53,9 @@ def test_check_duplicated_about_file_path(self): assert expected == result def test_load_inventory(self): - self.maxDiff = None - mapping = None location = get_test_loc('gen/inv.csv') base_dir = get_test_loc('inv') - errors, abouts = gen.load_inventory(mapping, location, base_dir) - - file_path = posixpath.normpath(posixpath.join(base_dir, '.')) + errors, abouts = gen.load_inventory(location, base_dir) expected_errors = [ Error(INFO, u'Field custom1 is not a supported field and is ignored.')] @@ -77,40 +72,28 @@ def test_load_inventory(self): assert expected == result def test_generation_dir_endswith_space(self): - mapping = None - license_text_location = None - extract_license = False location = get_test_loc('inventory/complex/about_file_path_dir_endswith_space.csv') - gen_dir = get_temp_dir() - - errors, _abouts = gen.generate(location, gen_dir, mapping, license_text_location, extract_license, with_empty=False, with_absent=False) - + base_dir = get_temp_dir() + errors, _abouts = gen.generate(location, base_dir) expected_errors_msg = 'contains directory name ends with spaces which is not allowed. Generation skipped.' - assert (len(errors) == 1, 'Should return 1 error.') + assert errors + assert len(errors) == 1 assert expected_errors_msg in errors[0].message def test_generation_with_no_about_resource(self): - mapping = None - license_text_location = None - extract_license = False location = get_test_loc('gen/inv2.csv') - gen_dir = get_temp_dir() - - errors, abouts = gen.generate(location, gen_dir, mapping, license_text_location, extract_license, with_empty=False, with_absent=False) + base_dir = get_temp_dir() + errors, abouts = gen.generate(location, base_dir) expected_dict = OrderedDict() expected_dict[u'.'] = None - assert abouts[0].about_resource.value == expected_dict assert len(errors) == 0 def test_generation_with_no_about_resource_reference(self): - mapping = None - license_text_location = None - extract_license = False location = get_test_loc('gen/inv3.csv') - gen_dir = get_temp_dir() + base_dir = get_temp_dir() - errors, abouts = gen.generate(location, gen_dir, mapping, license_text_location, extract_license, with_empty=False, with_absent=False) + errors, abouts = gen.generate(location, base_dir) expected_dict = OrderedDict() expected_dict[u'test.tar.gz'] = None @@ -120,13 +103,10 @@ def test_generation_with_no_about_resource_reference(self): assert msg in errors[0].message def test_generate(self): - mapping = '' - license_text_location = None - extract_license = False location = get_test_loc('gen/inv.csv') - gen_dir = get_temp_dir() + base_dir = get_temp_dir() - errors, abouts = gen.generate(location, gen_dir, mapping, license_text_location, extract_license, with_empty=False, with_absent=False) + errors, abouts = gen.generate(location, base_dir) expected_errors = [Error(INFO, u'Field custom1 is not a supported field and is ignored.')] assert expected_errors == errors @@ -145,4 +125,4 @@ def test_deduplicate(self): items = ['a', 'b', 'd', 'b', 'c', 'a'] expected = ['a', 'b', 'd', 'c'] results = gen.deduplicate(items) - assert expected == results \ No newline at end of file + assert expected == results diff --git a/tests/test_model.py b/tests/test_model.py index 520358e0..61561f0c 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,25 +16,52 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals from collections import OrderedDict +import json import posixpath +import sys import unittest - from unittest.case import expectedFailure + +from testing_utils import extract_test_loc from testing_utils import get_temp_file from testing_utils import get_test_loc from testing_utils import get_test_lines from testing_utils import get_unicode_content import attributecode +from attributecode import CRITICAL +from attributecode import ERROR +from attributecode import INFO +from attributecode import WARNING from attributecode import Error -from attributecode import CRITICAL, INFO, WARNING from attributecode import model from attributecode import util -from attributecode import ERROR -from attributecode.util import load_csv, add_unc -from testing_utils import extract_test_loc +from attributecode.util import add_unc +from attributecode.util import load_csv + + +def check_csv(expected, result): + """ + Assert that the contents of two CSV files locations `expected` and + `result` are equal. + """ + expected = sorted([sorted(d.items()) for d in load_csv(expected)]) + result = sorted([sorted(d.items()) for d in load_csv(result)]) + assert expected == result + + +def check_json(expected, result): + """ + Assert that the contents of two JSON files are equal. + """ + with open(expected) as e: + expected = json.load(e, object_pairs_hook=OrderedDict) + with open(result) as r: + result = json.load(r, object_pairs_hook=OrderedDict) + assert expected == result class FieldTest(unittest.TestCase): @@ -85,17 +112,16 @@ def test_PathField_check_missing_location(self): assert None == result def test_TextField_loads_file(self): - field = model.FileTextField(name='f', value='license.LICENSE', - present=True) + field = model.FileTextField( + name='f', value='license.LICENSE', present=True) base_dir = get_test_loc('fields') errors = field.validate(base_dir=base_dir) assert [] == errors - expected = [('license.LICENSE', u'some license text')] - result = field.value.items() - assert expected == result + expected = {'license.LICENSE': u'some license text'} + assert expected == field.value def test_UrlField_is_valid_url(self): assert model.UrlField.is_valid_url('http://www.google.com') @@ -258,11 +284,11 @@ def test_parse_error_for_invalid_field_name(self): assert expected == result expected_errors = [ - Error(CRITICAL, "Invalid line: 0: u'invalid space:value\\n'"), - Error(CRITICAL, "Invalid line: 1: u'other-field: value\\n'"), - Error(CRITICAL, "Invalid line: 4: u'_invalid_dash: value\\n'"), - Error(CRITICAL, "Invalid line: 5: u'3invalid_number: value\\n'"), - Error(CRITICAL, "Invalid line: 6: u'invalid.dot: value'") + Error(CRITICAL, "Invalid line: 0: 'invalid space:value\\n'"), + Error(CRITICAL, "Invalid line: 1: 'other-field: value\\n'"), + Error(CRITICAL, "Invalid line: 4: '_invalid_dash: value\\n'"), + Error(CRITICAL, "Invalid line: 5: '3invalid_number: value\\n'"), + Error(CRITICAL, "Invalid line: 6: 'invalid.dot: value'") ] assert expected_errors == errors @@ -285,11 +311,15 @@ def test_parse_rejects_non_ascii_names_and_accepts_unicode_values(self): errors, result = model.parse(test) expected = [(u'name', u'name'), (u'about_resource', u'.'), - (u'owner', u'Mat\xedas Aguirre')] + (u'owner', 'Matías Aguirre')] assert expected == result + expected_msg = "Invalid line: 3: 'Matías: unicode field name\\n'" + if sys.version_info[0] < 3: # Python 2 + expected_msg = "Invalid line: 3: 'Mat\\xedas: unicode field name\\n'" + expected_errors = [ - Error(CRITICAL, "Invalid line: 3: u'Mat\\xedas: unicode field name\\n'")] + Error(CRITICAL, expected_msg)] assert expected_errors == errors def test_parse_handles_blank_lines_and_spaces_in_field_names(self): @@ -379,7 +409,6 @@ def check_About_hydrate(self, about, fields, errors): assert expected == result def test_About_hydrate_normalize_field_names_to_lowercase(self): - self.maxDiff = None test_file = get_test_lines('parser_tests/upper_field_names.ABOUT') errors, fields = model.parse(test_file) assert [] == errors @@ -450,7 +479,7 @@ def test_About_has_errors_with_empty_notice_file_field(self): assert expected == result @expectedFailure - # This test need to be updated as the custom field will be ignore if no + # This test need to be updated as the custom field will be ignore if no # mapping is set def test_About_custom_fields_are_collected_correctly(self): test_file = get_test_loc('parse/custom_fields.about') @@ -463,7 +492,7 @@ def test_About_custom_fields_are_collected_correctly(self): assert sorted(expected) == sorted(result) @expectedFailure - # This test need to be updated as the custom field will be ignore if no + # This test need to be updated as the custom field will be ignore if no # mapping is set def test_About_custom_fields_are_collected_correctly_as_multiline_scalar(self): test_file = get_test_loc('parse/custom_fields.about') @@ -478,10 +507,8 @@ def test_About_custom_fields_are_collected_correctly_as_multiline_scalar(self): def test_About_has_errors_for_illegal_custom_field_name(self): test_file = get_test_loc('parse/illegal_custom_field.about') a = model.About(test_file) - result = a.custom_fields.items() - expected = [ - ] - assert expected == result + result = a.custom_fields + assert {} == result def test_About_file_fields_are_empty_if_present_and_path_missing(self): test_file = get_test_loc('parse/missing_notice_license_files.ABOUT') @@ -493,19 +520,12 @@ def test_About_file_fields_are_empty_if_present_and_path_missing(self): err_msg1 = u'Field license_file: Path %s not found' % file_path1 err_msg2 = u'Field notice_file: Path %s not found' % file_path2 - expected_errors = [ - err_msg1, err_msg2 - ] - + expected_errors = [err_msg1, err_msg2] errors = model.check_file_field_exist(a, test_file) assert expected_errors == errors - expected = [(u'test.LICENSE', None)] - result = a.license_file.value.items() - assert expected == result - expected = [(u'test.NOTICE', None)] - result = a.notice_file.value.items() - assert expected == result + assert {'test.LICENSE': None} == a.license_file.value + assert {'test.NOTICE': None} == a.notice_file.value def test_About_notice_and_license_text_are_loaded_from_file(self): test_file = get_test_loc('parse/license_file_notice_file.ABOUT') @@ -563,13 +583,6 @@ def FAILING_test_About_equals_with_small_text_differences(self): a = model.About(test_file, about_file_path='complete2/about.ABOUT') test_file2 = get_test_loc('equal/complete/about.ABOUT') b = model.About(test_file2, about_file_path='complete/about.ABOUT') - self.maxDiff = None - # print() - # print('a') - # print(a.dumps(True)) - # print() - # print('b') - # print(b.dumps(True)) assert a.dumps(True) == b.dumps(True) assert a == b @@ -593,7 +606,7 @@ def test_About_dumps_does_not_transform_strings_in_lists(self): notice_file: NOTICE notice_url: redistribute: -attribute: +attribute: track_change: modified: changelog_file: @@ -650,7 +663,7 @@ def test_field_names(self): # and that all fields are in the correct order expected = [ model.About.about_file_path_attr, - #model.About.about_resource_path_attr, + # model.About.about_resource_path_attr, 'about_resource', 'name', 'about_resource_path', @@ -719,7 +732,6 @@ def test_field_names_does_not_return_duplicates_custom_fields(self): class SerializationTest(unittest.TestCase): def test_About_dumps(self): - self.maxDiff = None test_file = get_test_loc('parse/complete/about.ABOUT') a = model.About(test_file) assert [] == a.errors @@ -849,6 +861,7 @@ def test_About_as_dict_with_empty(self): result = a.as_dict(with_paths=False, with_empty=True, with_absent=False) + # FIXME: why converting back to dict? assert expected == dict(result) def test_About_as_dict_with_present(self): @@ -896,6 +909,7 @@ def test_About_as_dict_with_present(self): result = a.as_dict(with_paths=False, with_empty=False, with_absent=True) + # FIXME: why converting back to dict? assert expected == dict(result) def test_About_as_dict_with_nothing(self): @@ -916,6 +930,7 @@ def test_About_as_dict_with_nothing(self): result = a.as_dict(with_paths=False, with_empty=False, with_absent=False) + # FIXME: why converting back to dict? assert expected == dict(result) def test_loads_dumps_is_idempotent(self): @@ -1004,12 +1019,11 @@ def test_as_dict_load_dict_is_idempotent(self): a = model.About() base_dir = 'some_dir' a.load_dict(test, base_dir) - as_dict = a.as_dict(with_paths=False, with_absent=False, - with_empty=True) + as_dict = a.as_dict(with_paths=False, with_absent=False, with_empty=True) + # FIXME: why converting back to dict? assert expected == dict(as_dict) def test_load_dict_handles_field_validation_correctly(self): - self.maxDiff = None test = {u'about_resource': u'.', u'about_resource_path': u'.', u'attribute': u'yes', @@ -1028,44 +1042,32 @@ def test_load_dict_handles_field_validation_correctly(self): a = model.About() base_dir = 'some_dir' a.load_dict(test, base_dir) - as_dict = a.as_dict(with_paths=False, with_absent=False, - with_empty=True) + as_dict = a.as_dict(with_paths=False, with_absent=False, with_empty=True) + # FIXME: why converting back to dict? assert test == dict(as_dict) - def check_csvs(self, expected, result): - """ - Assert that the content of two CSV file locations are equal. - """ - mapping = None - expected = [d.items() for d in load_csv(mapping, expected)] - result = [d.items() for d in load_csv(mapping, result)] - for ie, expect in enumerate(expected): - res = result[ie] - for ii, exp in enumerate(expect): - r = res[ii] - assert exp == r - def test_write_output_csv(self): path = 'load/this.ABOUT' test_file = get_test_loc(path) - a = model.About(location=test_file, about_file_path=path) + abouts = model.About(location=test_file, about_file_path=path) - tmp_file = get_temp_file() - model.write_output([a], tmp_file, format = 'csv') + result = get_temp_file() + model.write_output([abouts], result, format='csv') expected = get_test_loc('load/expected.csv') - self.check_csvs(expected, tmp_file) + check_csv(expected, result) def test_write_output_json(self): path = 'load/this.ABOUT' test_file = get_test_loc(path) - a = model.About(location=test_file, about_file_path=path) + abouts = model.About(location=test_file, about_file_path=path) - tmp_file = get_temp_file() - model.write_output([a], tmp_file, format = 'json') + result = get_temp_file() + model.write_output([abouts], result, format='json') expected = get_test_loc('load/expected.json') - self.check_csvs(expected, tmp_file) + check_json(expected, result) + class CollectorTest(unittest.TestCase): @@ -1190,72 +1192,63 @@ def test_collect_inventory_works_with_relative_paths(self): assert expected == result1 assert expected == result2 - def check_csv(self, expected, result): - """ - Compare two CSV files at locations as lists of ordered items. - """ - def as_items(csvfile): - mapping= None - return sorted([i.items() for i in util.load_csv(mapping, csvfile)]) - - expected = as_items(expected) - result = as_items(result) - assert expected == result - def test_collect_inventory_basic_from_directory(self): location = get_test_loc('inventory/basic') result = get_temp_file() errors, abouts = model.collect_inventory(location) - model.write_output(abouts, result, format = 'csv') + model.write_output(abouts, result, format='csv') expected_errors = [] assert expected_errors == errors expected = get_test_loc('inventory/basic/expected.csv') - self.check_csv(expected, result) + check_csv(expected, result) def test_collect_inventory_with_about_resource_path_from_directory(self): location = get_test_loc('inventory/basic_with_about_resource_path') result = get_temp_file() errors, abouts = model.collect_inventory(location) - model.write_output(abouts, result, format = 'csv') + model.write_output(abouts, result, format='csv') expected_errors = [] assert expected_errors == errors expected = get_test_loc('inventory/basic_with_about_resource_path/expected.csv') - self.check_csv(expected, result) + check_csv(expected, result) def test_collect_inventory_with_no_about_resource_from_directory(self): location = get_test_loc('inventory/no_about_resource_key') result = get_temp_file() errors, abouts = model.collect_inventory(location) - model.write_output(abouts, result, format = 'csv') + model.write_output(abouts, result, format='csv') expected_errors = [Error(CRITICAL, u'about/about.ABOUT: Field about_resource is required')] assert expected_errors == errors expected = get_test_loc('inventory/no_about_resource_key/expected.csv') - self.check_csv(expected, result) + check_csv(expected, result) - # FIXME: The self.check_csv is failing because there are many keys in the ABOUT files that are - # not supported. Instead of removing all the non-supported keys in the output - # and do the comparison, it may be best to apply the mapping to include theses keys @expectedFailure def test_collect_inventory_complex_from_directory(self): + # FIXME: check_csv is failing because there are many keys in + # the ABOUT files that are not supported. Instead of removing + # all the non-supported keys in the output and do the + # comparison, it may be best to apply the mapping to include + # theses keys location = get_test_loc('inventory/complex') result = get_temp_file() errors, abouts = model.collect_inventory(location) - model.write_output(abouts, result, format = 'csv') + model.write_output(abouts, result, format='csv') assert all(e.severity == INFO for e in errors) expected = get_test_loc('inventory/complex/expected.csv') - self.check_csv(expected, result) + check_csv(expected, result) + class GroupingsTest(unittest.TestCase): diff --git a/tests/test_util.py b/tests/test_util.py index 100dd8cc..4731ae71 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014-2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,11 +16,14 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals from collections import OrderedDict import string import unittest +from unittest.case import expectedFailure +from testing_utils import extract_test_loc from testing_utils import get_test_loc from testing_utils import on_posix from testing_utils import on_windows @@ -28,7 +31,6 @@ from attributecode import CRITICAL from attributecode import Error from attributecode import util -from testing_utils import extract_test_loc class UtilsTest(unittest.TestCase): @@ -211,13 +213,17 @@ def test_check_file_names_with_no_invalid_char_return_no_error(self): assert expected == result def test_check_file_names_with_invalid_chars_return_errors(self): - paths = ['locations/file', - 'locations/file with space', - 'locations/dir1/dir2/file1', - 'locations/dir2/file1'] + paths = [ + 'locations/file', + 'locations/file with space', + 'locations/dir1/dir2/file1', + 'locations/dir2/file1' + ] expected = [Error(CRITICAL, "Invalid characters ' ' in file name at: 'locations/file with space'")] result = util.check_file_names(paths) + + assert expected[0].message == result[0].message assert expected == result def test_get_about_locations(self): @@ -258,8 +264,7 @@ def test_get_relative_path_with_same_path_twice(self): result = util.get_relative_path(loc, loc) assert expected == result - def test_load_csv(self): - mapping = None + def test_load_csv_without_mapping(self): test_file = get_test_loc('util/about.csv') expected = [OrderedDict( [('about_file', 'about.ABOUT'), @@ -267,11 +272,10 @@ def test_load_csv(self): ('name', 'ABOUT tool'), ('version', '0.8.1')]) ] - result = util.load_csv(mapping, test_file) + result = util.load_csv(test_file) assert expected == result - def test_load_json(self): - mapping = None + def test_load_json_without_mapping(self): test_file = get_test_loc('load/expected.json') expected = [OrderedDict( [('about_file_path', '/load/this.ABOUT'), @@ -280,27 +284,25 @@ def test_load_json(self): ('name', 'AboutCode'), ('version', '0.11.0')]) ] - result = util.load_json(mapping, test_file) + result = util.load_json(test_file) assert expected == result - def test_get_about_file_path_from_csv(self): - mapping = True + def test_get_about_file_path_from_csv_using_mapping(self): test_file = get_test_loc('util/about.csv') expected = ['about.ABOUT'] - result = util.get_about_file_path(mapping, test_file) + result = util.get_about_file_path(test_file, use_mapping=True) assert expected == result - def test_get_about_file_path_from_json(self): - mapping = True + def test_get_about_file_path_from_json_using_mapping(self): test_file = get_test_loc('load/expected.json') expected = ['/load/this.ABOUT'] - result = util.get_about_file_path(mapping, test_file) + result = util.get_about_file_path(test_file, use_mapping=True) assert expected == result # The column names should be converted to lowercase as the same behavior as # when user use the mapping.config - """def test_load_csv_does_not_convert_column_names_to_lowercase(self): - mapping = None + @expectedFailure + def test_load_csv_does_not_convert_column_names_to_lowercase(self): test_file = get_test_loc('util/about_key_with_upper_case.csv') expected = [OrderedDict( [('about_file', 'about.ABOUT'), @@ -308,8 +310,8 @@ def test_get_about_file_path_from_json(self): ('nAme', 'ABOUT tool'), ('Version', '0.8.1')]) ] - result = util.load_csv(mapping, test_file) - assert expected == result""" + result = util.load_csv(test_file) + assert expected == result def test_get_locations_with_very_long_path(self): longpath = ( diff --git a/tests/testing_utils.py b/tests/testing_utils.py index 036a48ac..6c77651d 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2016 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2017 nexB Inc. http://www.nexb.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,6 +16,7 @@ from __future__ import absolute_import from __future__ import print_function +from __future__ import unicode_literals import codecs import logging @@ -27,7 +28,9 @@ import tempfile import zipfile -from attributecode.util import to_posix, add_unc +from attributecode.util import add_unc +from attributecode.util import to_posix + logger = logging.getLogger(__name__) handler = logging.StreamHandler() @@ -35,8 +38,7 @@ logger.addHandler(handler) -TESTDATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), - 'testdata') +TESTDATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'testdata') on_windows = 'win32' in sys.platform on_posix = not on_windows diff --git a/thirdparty/base/apache-2.0.LICENSE b/thirdparty/base/apache-2.0.LICENSE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/thirdparty/base/apache-2.0.LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/thirdparty/base/appdirs-1.4.3-py2.py3-none-any.whl b/thirdparty/base/appdirs-1.4.3-py2.py3-none-any.whl new file mode 100644 index 00000000..fda65956 Binary files /dev/null and b/thirdparty/base/appdirs-1.4.3-py2.py3-none-any.whl differ diff --git a/thirdparty/base/appdirs.ABOUT b/thirdparty/base/appdirs.ABOUT new file mode 100644 index 00000000..1d772ec8 --- /dev/null +++ b/thirdparty/base/appdirs.ABOUT @@ -0,0 +1,18 @@ +about_resource: appdirs-1.4.3-py2.py3-none-any.whl +name: appdirs +version: 1.4.3 + +download_url: https://pypi.python.org/packages/56/eb/810e700ed1349edde4cbdc1b2a21e28cdf115f9faf263f6bbf8447c1abf3/appdirs-1.4.3-py2.py3-none-any.whl#md5=9ed4b51c9611775c3078b3831072e153 + +home_url: https://pypi.python.org/pypi/appdirs +owner: ActiveState + +vcs_repository: https://github.com/ActiveState/appdirs.git + +copyright: Copyright (c) 2010 ActiveState Software Inc. + +dje_license: mit +license_text_file: + - appdirs.LICENSE + + diff --git a/thirdparty/base/appdirs.LICENSE b/thirdparty/base/appdirs.LICENSE new file mode 100644 index 00000000..d15d784d --- /dev/null +++ b/thirdparty/base/appdirs.LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2010 ActiveState Software Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/thirdparty/base/certifi-14.05.14-py2.py3-none-any.whl b/thirdparty/base/certifi-14.05.14-py2.py3-none-any.whl deleted file mode 100644 index d8daba62..00000000 Binary files a/thirdparty/base/certifi-14.05.14-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/certifi-2015.04.28-py2.py3-none-any.whl b/thirdparty/base/certifi-2015.04.28-py2.py3-none-any.whl deleted file mode 100644 index 2a521b88..00000000 Binary files a/thirdparty/base/certifi-2015.04.28-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/certifi-2017.4.17-py2.py3-none-any.whl b/thirdparty/base/certifi-2017.4.17-py2.py3-none-any.whl new file mode 100644 index 00000000..2350c983 Binary files /dev/null and b/thirdparty/base/certifi-2017.4.17-py2.py3-none-any.whl differ diff --git a/thirdparty/base/certifi.ABOUT b/thirdparty/base/certifi.ABOUT index a51966f7..e92b4cff 100644 --- a/thirdparty/base/certifi.ABOUT +++ b/thirdparty/base/certifi.ABOUT @@ -1,8 +1,8 @@ -about_resource: certifi-2015.04.28-py2.py3-none-any.whl -version: 2015.04.28 +about_resource: certifi-2017.4.17-py2.py3-none-any.whl +version: 2017.4.17 description: Python package for providing Mozilla's CA Bundle. -download_url: https://pypi.python.org/packages/2.7/c/certifi/certifi-2015.04.28-py2.py3-none-any.whl#md5=4b0d6599c8297becffeb369c0b3ef47b +download_url: https://pypi.python.org/packages/eb/01/c1f58987b777d6c4ec535b4e004a4a07bfc9db06f0c7533367ca6da8f2a6/certifi-2017.4.17-py2.py3-none-any.whl owner: Kenneth Reitz contact: me@kennethreitz.com diff --git a/thirdparty/base/chardet-3.0.3-py2.py3-none-any.whl b/thirdparty/base/chardet-3.0.3-py2.py3-none-any.whl new file mode 100644 index 00000000..47eb51a5 Binary files /dev/null and b/thirdparty/base/chardet-3.0.3-py2.py3-none-any.whl differ diff --git a/thirdparty/base/chardet.ABOUT b/thirdparty/base/chardet.ABOUT new file mode 100644 index 00000000..b41f66f3 --- /dev/null +++ b/thirdparty/base/chardet.ABOUT @@ -0,0 +1,10 @@ +about_resource: chardet-3.0.3-py2.py3-none-any.whl +name: chardet +version: 3.0.3 +home_url: https://github.com/chardet/chardet +download_url: https://pypi.python.org/packages/8c/27/99f781a11e4daa5acadf97add6e5883ec5f8f9abbf279e790fd0ff371db7/chardet-3.0.3-py2.py3-none-any.whl +dje_license: lgpl-2.1 +license_text_url: https://raw.github.com/erikrose/chardet/70af46cb8e146326081fd76360d1c19675ee627c/COPYING +license_text_file: lgpl-2.1.LICENSE +vcs_tool: git +vcs_repository: https://github.com/chardet/chardet.git diff --git a/thirdparty/base/idna-2.5-py2.py3-none-any.whl b/thirdparty/base/idna-2.5-py2.py3-none-any.whl new file mode 100644 index 00000000..1bd6c351 Binary files /dev/null and b/thirdparty/base/idna-2.5-py2.py3-none-any.whl differ diff --git a/thirdparty/base/idna.ABOUT b/thirdparty/base/idna.ABOUT new file mode 100644 index 00000000..ec480b73 --- /dev/null +++ b/thirdparty/base/idna.ABOUT @@ -0,0 +1,21 @@ +about_resource: idna-2.5-py2.py3-none-any.whl +version: 2.5 + +download_url: https://pypi.python.org/packages/11/7d/9bbbd7bb35f34b0169542487d2a8859e44306bb2e6a4455d491800a5621f/idna-2.5-py2.py3-none-any.whl + +owner: Kim Davies +home_url: https://github.com/kjd/idna +name: idna + +copyright: + - Copyright (c) 2013-2017, Kim Davies + - Copyright (c) 2001-2014 Python Software Foundation + - Copyright (c) 1991-2014 Unicode, Inc. + +dje_license: bsd-new and python and unicode-data-software + +license_text_file: + - idna.LICENSE + - PSF.LICENSE + - unicode-data-software.LICENSE +notice_file: idna.NOTICE \ No newline at end of file diff --git a/thirdparty/base/idna.LICENSE b/thirdparty/base/idna.LICENSE new file mode 100644 index 00000000..81a951e4 --- /dev/null +++ b/thirdparty/base/idna.LICENSE @@ -0,0 +1,32 @@ +License +------- + +Copyright (c) 2013-2017, Kim Davies. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +#. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +#. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with + the distribution. + +#. Neither the name of the copyright holder nor the names of the + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +#. THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. diff --git a/thirdparty/base/idna.NOTICE b/thirdparty/base/idna.NOTICE new file mode 100644 index 00000000..9d38815e --- /dev/null +++ b/thirdparty/base/idna.NOTICE @@ -0,0 +1,80 @@ +License +------- + +Copyright (c) 2013-2017, Kim Davies. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +#. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +#. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with + the distribution. + +#. Neither the name of the copyright holder nor the names of the + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +#. THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +Portions of the codec implementation and unit tests are derived from the +Python standard library, which carries the `Python Software Foundation +License `_: + + Copyright (c) 2001-2014 Python Software Foundation; All Rights Reserved + +Portions of the unit tests are derived from the Unicode standard, which +is subject to the Unicode, Inc. License Agreement: + + Copyright (c) 1991-2014 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in + . + + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Unicode data files and any associated documentation + (the "Data Files") or Unicode software and any associated documentation + (the "Software") to deal in the Data Files or Software + without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, and/or sell copies of + the Data Files or Software, and to permit persons to whom the Data Files + or Software are furnished to do so, provided that + + (a) this copyright and permission notice appear with all copies + of the Data Files or Software, + + (b) this copyright and permission notice appear in associated + documentation, and + + (c) there is clear notice in each modified Data File or in the Software + as well as in the documentation associated with the Data File(s) or + Software that the data or software has been modified. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THE DATA FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in these Data Files or Software without prior + written authorization of the copyright holder. diff --git a/thirdparty/base/lgpl-2.1.LICENSE b/thirdparty/base/lgpl-2.1.LICENSE new file mode 100644 index 00000000..d8c9cefe --- /dev/null +++ b/thirdparty/base/lgpl-2.1.LICENSE @@ -0,0 +1,513 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/thirdparty/base/packaging-16.8-py2.py3-none-any.whl b/thirdparty/base/packaging-16.8-py2.py3-none-any.whl new file mode 100644 index 00000000..5c9cc7af Binary files /dev/null and b/thirdparty/base/packaging-16.8-py2.py3-none-any.whl differ diff --git a/thirdparty/base/packaging.ABOUT b/thirdparty/base/packaging.ABOUT new file mode 100644 index 00000000..cd30f3d6 --- /dev/null +++ b/thirdparty/base/packaging.ABOUT @@ -0,0 +1,18 @@ +about_resource: packaging-16.8-py2.py3-none-any.whl +name: packaging +version: 16.8 + +download_url: https://pypi.python.org/packages/87/1b/c39b7c65b5612812b83d6cab7ef2885eac9f6beb0b7b8a7071a186aea3b1/packaging-16.8-py2.py3-none-any.whl#md5=c7326351bf015fa53c74b0075923ab02 + +home_url: https://pypi.python.org/pypi/packaging +owner: Python Packaging Authority + +copyright: Copyright (c) Donald Stufft and individual contributors. + +dje_license: bsd-simplified or apache-2.0 +license_text_file: + - apache-2.0.LICENSE + - packaging.LICENSE + +notice_text_file: + - packaging.NOTICE diff --git a/thirdparty/base/packaging.LICENSE b/thirdparty/base/packaging.LICENSE new file mode 100644 index 00000000..42ce7b75 --- /dev/null +++ b/thirdparty/base/packaging.LICENSE @@ -0,0 +1,23 @@ +Copyright (c) Donald Stufft and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/thirdparty/base/packaging.NOTICE b/thirdparty/base/packaging.NOTICE new file mode 100644 index 00000000..769ae59c --- /dev/null +++ b/thirdparty/base/packaging.NOTICE @@ -0,0 +1,3 @@ +This software is made available under the terms of *either* of the licenses +found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made +under the terms of *both* these licenses. \ No newline at end of file diff --git a/thirdparty/base/pip-1.5.6-py2.py3-none-any.whl b/thirdparty/base/pip-1.5.6-py2.py3-none-any.whl deleted file mode 100644 index 097ab434..00000000 Binary files a/thirdparty/base/pip-1.5.6-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/pip-6.1.1-py2.py3-none-any.whl b/thirdparty/base/pip-6.1.1-py2.py3-none-any.whl deleted file mode 100644 index e59694a0..00000000 Binary files a/thirdparty/base/pip-6.1.1-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/pip-9.0.1-py2.py3-none-any.whl b/thirdparty/base/pip-9.0.1-py2.py3-none-any.whl new file mode 100644 index 00000000..4b8ecc69 Binary files /dev/null and b/thirdparty/base/pip-9.0.1-py2.py3-none-any.whl differ diff --git a/thirdparty/base/pip.ABOUT b/thirdparty/base/pip.ABOUT index 82811bb7..af015886 100644 --- a/thirdparty/base/pip.ABOUT +++ b/thirdparty/base/pip.ABOUT @@ -1,6 +1,6 @@ -about_resource: pip-6.1.1-py2.py3-none-any.whl -version: 6.1.1 -download_url: https://pypi.python.org/packages/py2.py3/p/pip/pip-6.1.1-py2.py3-none-any.whl +about_resource: pip-9.0.1-py2.py3-none-any.whl (1.3MB) +download_url: https://pypi.python.org/packages/b6/ac/7015eb97dc749283ffdec1c3a88ddb8ae03b8fad0f0e611408f196358da3/pip-9.0.1-py2.py3-none-any.whl#md5=297dbd16ef53bcef0447d245815f5144 +version: 9.0.1 name: pip owner: The pip developers diff --git a/thirdparty/base/pip.AUTHORS b/thirdparty/base/pip.AUTHORS index 321c6a59..f18ad3cd 100644 --- a/thirdparty/base/pip.AUTHORS +++ b/thirdparty/base/pip.AUTHORS @@ -101,7 +101,7 @@ Paul van der Linden Peter Waller Phil Freo Phil Whelan -Piet Delport +Pi Delport Preston Holmes Przemek Wrzos Qiangning Hong @@ -131,4 +131,4 @@ Wil Tan Yoval P Yu Jian Zearin -Zhiping Deng \ No newline at end of file +Zhiping Deng diff --git a/thirdparty/base/pyparsing-2.2.0-py2.py3-none-any.whl b/thirdparty/base/pyparsing-2.2.0-py2.py3-none-any.whl new file mode 100644 index 00000000..0465e176 Binary files /dev/null and b/thirdparty/base/pyparsing-2.2.0-py2.py3-none-any.whl differ diff --git a/thirdparty/base/pyparsing.ABOUT b/thirdparty/base/pyparsing.ABOUT new file mode 100644 index 00000000..f89693d4 --- /dev/null +++ b/thirdparty/base/pyparsing.ABOUT @@ -0,0 +1,13 @@ +about_resource: pyparsing-2.2.0-py2.py3-none-any.whl +name: pyparsing +version: 2.2.0 +home_url: http://pyparsing.wikispaces.com/ +download_url: download_url: https://pypi.python.org/packages/6a/8a/718fd7d3458f9fab8e67186b00abdd345b639976bc7fb3ae722e1b026a50/pyparsing-2.2.0-py2.py3-none-any.whl#md5=7247e7896688eff4bc8c7fc5d0cdd2b0 +owner: Paul McGuire +copyright: Copyright (c) 2003-2016 Paul T. McGuire + +vcs_tool: svn +vcs_repository: http://svn.code.sf.net/p/pyparsing/code/tags/pyparsing_2.1.9/ + +dje_license: mit +license_text_file: pyparsing.LICENSE diff --git a/thirdparty/base/pyparsing.LICENSE b/thirdparty/base/pyparsing.LICENSE new file mode 100644 index 00000000..1bf98523 --- /dev/null +++ b/thirdparty/base/pyparsing.LICENSE @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/thirdparty/base/requests-2.17.3-py2.py3-none-any.whl b/thirdparty/base/requests-2.17.3-py2.py3-none-any.whl new file mode 100644 index 00000000..0558438c Binary files /dev/null and b/thirdparty/base/requests-2.17.3-py2.py3-none-any.whl differ diff --git a/thirdparty/base/requests.ABOUT b/thirdparty/base/requests.ABOUT new file mode 100644 index 00000000..e1cfc07b --- /dev/null +++ b/thirdparty/base/requests.ABOUT @@ -0,0 +1,15 @@ +about_resource: requests-2.17.3-py2.py3-none-any.whl +version: 2.17.3 +download_url: https://pypi.python.org/packages/29/b9/d26a6ab2ee178415ab8c0c591d2a1eb782a50c42a417ae390055f86a63c1/requests-2.17.3-py2.py3-none-any.whl + +name: requests +home_url: http://python-requests.org +owner: Kenneth Reitz +dje_license: apache-2.0 +notice_file: requests.NOTICE +license_text_file: apache-2.0.LICENSE + +vcs_tool: git +vcs_repository: https://github.com/kennethreitz/requests.git + +copyright: Copyright (c) 2017 Kenneth Reitz diff --git a/thirdparty/base/requests.NOTICE b/thirdparty/base/requests.NOTICE new file mode 100644 index 00000000..db78ea69 --- /dev/null +++ b/thirdparty/base/requests.NOTICE @@ -0,0 +1,13 @@ +Copyright 2017 Kenneth Reitz + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/thirdparty/base/setuptools-17.0-py2.py3-none-any.whl b/thirdparty/base/setuptools-17.0-py2.py3-none-any.whl deleted file mode 100644 index a1d3561b..00000000 Binary files a/thirdparty/base/setuptools-17.0-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/setuptools-36.6.0-py2.py3-none-any.whl b/thirdparty/base/setuptools-36.6.0-py2.py3-none-any.whl new file mode 100644 index 00000000..4dc4b9ae Binary files /dev/null and b/thirdparty/base/setuptools-36.6.0-py2.py3-none-any.whl differ diff --git a/thirdparty/base/setuptools-7.0-py2.py3-none-any.whl b/thirdparty/base/setuptools-7.0-py2.py3-none-any.whl deleted file mode 100644 index fa1d1054..00000000 Binary files a/thirdparty/base/setuptools-7.0-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/setuptools.ABOUT b/thirdparty/base/setuptools.ABOUT index 658155b4..f9ed216d 100644 --- a/thirdparty/base/setuptools.ABOUT +++ b/thirdparty/base/setuptools.ABOUT @@ -1,8 +1,8 @@ -about_resource: setuptools-17.0-py2.py3-none-any.whl -name: setuptools -version: 17.0 +about_resource: setuptools-36.6.0-py2.py3-none-any.whl +version: 36.6.0 +download_url: https://pypi.python.org/packages/bd/4c/b06ab3abfc8bc93b87b70f4cab22352c3c72deba7b71390d14bfffa97c85/setuptools-36.6.0-py2.py3-none-any.whl#md5=df531523e300bc3e6b9ce4451681912c -download_url: https://pypi.python.org/packages/3.4/s/setuptools/setuptools-17.0-py2.py3-none-any.whl +name: setuptools home_url: https://pypi.python.org/pypi/setuptools owner: Python Packaging Authority diff --git a/thirdparty/base/setuptools.LICENSE b/thirdparty/base/setuptools.LICENSE new file mode 100644 index 00000000..6e0693b4 --- /dev/null +++ b/thirdparty/base/setuptools.LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2016 Jason R Coombs + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/thirdparty/base/six-1.10.0-py2.py3-none-any.whl b/thirdparty/base/six-1.10.0-py2.py3-none-any.whl new file mode 100644 index 00000000..08872619 Binary files /dev/null and b/thirdparty/base/six-1.10.0-py2.py3-none-any.whl differ diff --git a/thirdparty/base/six-1.9.0-py2.py3-none-any.whl b/thirdparty/base/six-1.9.0-py2.py3-none-any.whl deleted file mode 100644 index 743ee125..00000000 Binary files a/thirdparty/base/six-1.9.0-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/six.ABOUT b/thirdparty/base/six.ABOUT index d556e285..3cb7559f 100644 --- a/thirdparty/base/six.ABOUT +++ b/thirdparty/base/six.ABOUT @@ -1,6 +1,6 @@ -about_resource: six-1.9.0-py2.py3-none-any.whl -version: 1.9.0 -download_url: https://pypi.python.org/packages/3.3/s/six/six-1.9.0-py2.py3-none-any.whl#md5=9ac7e129a80f72d6fc1f0216f6e9627b +about_resource: six-1.10.0-py2.py3-none-any.whl +version: 1.10.0 +download_url: https://pypi.python.org/packages/3.3/s/six/six-1.10.0-py2.py3-none-any.whl name: six description: Python 2 and 3 compatibility utilities diff --git a/thirdparty/base/unicode-data-software.LICENSE b/thirdparty/base/unicode-data-software.LICENSE new file mode 100644 index 00000000..82d29855 --- /dev/null +++ b/thirdparty/base/unicode-data-software.LICENSE @@ -0,0 +1,33 @@ +Distributed under the Terms of Use in http://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +the Unicode data files and any associated documentation (the "Data Files") or +Unicode software and any associated documentation (the "Software") to deal in +the Data Files or Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files or +Software are furnished to do so, provided that (a) the above copyright notice(s) +and this permission notice appear with all copies of the Data Files or Software, +(b) both the above copyright notice(s) and this permission notice appear in +associated documentation, and (c) there is clear notice in each modified Data +File or in the Software as well as in the documentation associated with the Data +File(s) or Software that the data or software has been modified. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD +PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +these Data Files or Software without prior written authorization of the +copyright holder. + +Unicode and the Unicode logo are trademarks of Unicode, Inc. in the United +States and other countries. All third party trademarks referenced herein are the +property of their respective owners. diff --git a/thirdparty/base/urllib3-1.21.1-py2.py3-none-any.whl b/thirdparty/base/urllib3-1.21.1-py2.py3-none-any.whl new file mode 100644 index 00000000..9061cfdf Binary files /dev/null and b/thirdparty/base/urllib3-1.21.1-py2.py3-none-any.whl differ diff --git a/thirdparty/base/urllib3.ABOUT b/thirdparty/base/urllib3.ABOUT new file mode 100644 index 00000000..63f3c0ab --- /dev/null +++ b/thirdparty/base/urllib3.ABOUT @@ -0,0 +1,14 @@ +about_resource: urllib3-1.21.1-py2.py3-none-any.whl +version: 1.21.1 +download_url: "https://pypi.python.org/packages/24/53/f397db567de0aa0e81b211d81c13c41a779f14893e42189cf5bdb97611b2/urllib3-1.21.1-py2.py3-none-any.whl + +name: urllib3 +home_url: https://github.com/shazow/urllib3 +dje_license: mit +license_text_file: urllib3.LICENSE + +owner: Andrey Petrov +copyright: Copyright 2008-2016 Andrey Petrov and contributors + +vcs_tool: git +vcs_repository: https://github.com/shazow/urllib3.git diff --git a/thirdparty/base/urllib3.LICENSE b/thirdparty/base/urllib3.LICENSE new file mode 100644 index 00000000..1c3283ee --- /dev/null +++ b/thirdparty/base/urllib3.LICENSE @@ -0,0 +1,19 @@ +This is the MIT license: http://www.opensource.org/licenses/mit-license.php + +Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/thirdparty/base/virtualenv-1.11.6-py2.py3-none-any.whl b/thirdparty/base/virtualenv-1.11.6-py2.py3-none-any.whl deleted file mode 100644 index 92fc33dc..00000000 Binary files a/thirdparty/base/virtualenv-1.11.6-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/virtualenv.ABOUT b/thirdparty/base/virtualenv.ABOUT deleted file mode 100644 index 9945d52b..00000000 --- a/thirdparty/base/virtualenv.ABOUT +++ /dev/null @@ -1,17 +0,0 @@ -about_resource: virtualenv-1.11.6-py2.py3-none-any.whl -version: 1.11.6 -download_url: https://raw.githubusercontent.com/pypa/virtualenv/1.11.6/virtualenv.py - -vcs_tool: git -vcs_repository: https://github.com/pypa/virtualenv.git - -name: virtualenv -homepage: http://virtualenv.org/ -owner: The virtualenv developers - -license_url: https://raw.github.com/pypa/virtualenv/develop/LICENSE.txt -license_file: virtualenv.LICENSE -license: mit -copyright: Copyright (c) 2007 Ian Bicking and Contributors - Copyright (c) 2009 Ian Bicking, The Open Planning Project - Copyright (c) 2011-2014 The virtualenv developers diff --git a/thirdparty/base/virtualenv.LICENSE b/thirdparty/base/virtualenv.LICENSE index 7e00d5d5..ab145001 100644 --- a/thirdparty/base/virtualenv.LICENSE +++ b/thirdparty/base/virtualenv.LICENSE @@ -1,6 +1,6 @@ Copyright (c) 2007 Ian Bicking and Contributors Copyright (c) 2009 Ian Bicking, The Open Planning Project -Copyright (c) 2011-2014 The virtualenv developers +Copyright (c) 2011-2016 The virtualenv developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/thirdparty/base/virtualenv.py b/thirdparty/base/virtualenv.py index 68a5d875..42cd1f4b 100644 --- a/thirdparty/base/virtualenv.py +++ b/thirdparty/base/virtualenv.py @@ -36,7 +36,7 @@ except ImportError: import configparser as ConfigParser -__version__ = "15.0.0" +__version__ = "15.1.0" virtualenv_version = __version__ # legacy if sys.version_info < (2, 6): @@ -155,12 +155,19 @@ def get_installed_pythons(): '_collections_abc', '_bootlocale', ]) + if minver >= 6: + REQUIRED_MODULES.extend(['enum']) if is_pypy: # these are needed to correctly display the exceptions that may happen # during the bootstrap REQUIRED_MODULES.extend(['traceback', 'linecache']) + if majver == 3: + # _functools is needed to import locale during stdio initialization and + # needs to be copied on PyPy because it's not built in + REQUIRED_MODULES.append('_functools') + class Logger(object): @@ -297,7 +304,7 @@ def level_matches(self, level, consumer_level): else: return level >= consumer_level - #@classmethod + @classmethod def level_for_integer(cls, level): levels = cls.LEVELS if level < 0: @@ -306,8 +313,6 @@ def level_for_integer(cls, level): return levels[-1] return levels[level] - level_for_integer = classmethod(level_for_integer) - # create a silent logger just to prevent this from being undefined # will be overridden with requested verbosity main() is called. logger = Logger([(Logger.LEVELS[-1], sys.stdout)]) @@ -677,6 +682,11 @@ def main(): home_dir = args[0] + if os.path.exists(home_dir) and os.path.isfile(home_dir): + logger.fatal('ERROR: File already exists and is not a directory.') + logger.fatal('Please provide a different path or delete the file.') + sys.exit(3) + if os.environ.get('WORKING_ENV'): logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') logger.fatal('Please deactivate your workingenv, then re-run this script') @@ -881,7 +891,6 @@ def space_path2url(p): "PIP_FIND_LINKS": findlinks, "PIP_USE_WHEEL": "1", "PIP_ONLY_BINARY": ":all:", - "PIP_PRE": "1", "PIP_USER": "0", } @@ -1057,6 +1066,16 @@ def copy_required_modules(dst_prefix, symlink): if os.path.exists(pyfile): copyfile(pyfile, dst_filename[:-1], symlink) +def copy_tcltk(src, dest, symlink): + """ copy tcl/tk libraries on Windows (issue #93) """ + for libversion in '8.5', '8.6': + for libname in 'tcl', 'tk': + srcdir = join(src, 'tcl', libname + libversion) + destdir = join(dest, 'tcl', libname + libversion) + # Only copy the dirs from the above combinations that exist + if os.path.exists(srcdir) and not os.path.exists(destdir): + copyfileordir(srcdir, destdir, symlink) + def subst_path(prefix_path, prefix, home_dir): prefix_path = os.path.normpath(prefix_path) @@ -1113,6 +1132,9 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy copy_required_modules(home_dir, symlink) finally: logger.indent -= 2 + # ...copy tcl/tk + if is_win: + copy_tcltk(prefix, home_dir, symlink) mkdir(join(lib_dir, 'site-packages')) import site site_filename = site.__file__ @@ -1349,12 +1371,6 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy else: copyfile(py_executable, full_pth, symlink) - if is_win and ' ' in py_executable: - # There's a bug with subprocess on Windows when using a first - # argument that has a space in it. Instead we have to quote - # the value: - py_executable = '"%s"' % py_executable - # NOTE: keep this check as one line, cmd.exe doesn't cope with line breaks cmd = [py_executable, '-c', 'import sys;out=sys.stdout;' 'getattr(out, "buffer", out).write(sys.prefix.encode("utf-8"))'] logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) @@ -1532,6 +1548,7 @@ def resolve_interpreter(exe): """ # If the "executable" is a version number, get the installed executable for # that version + orig_exe = exe python_versions = get_installed_pythons() if exe in python_versions: exe = python_versions[exe] @@ -1543,16 +1560,16 @@ def resolve_interpreter(exe): exe = join(path, exe) break if not os.path.exists(exe): - logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe)) + logger.fatal('The path %s (from --python=%s) does not exist' % (exe, orig_exe)) raise SystemExit(3) if not is_executable(exe): - logger.fatal('The executable %s (from --python=%s) is not executable' % (exe, exe)) + logger.fatal('The path %s (from --python=%s) is not an executable file' % (exe, orig_exe)) raise SystemExit(3) return exe def is_executable(exe): """Checks a file is executable""" - return os.access(exe, os.X_OK) + return os.path.isfile(exe) and os.access(exe, os.X_OK) ############################################################ ## Relocating the environment: @@ -1960,21 +1977,21 @@ def convert(s): ##file activate.fish ACTIVATE_FISH = convert(""" -eJyFVVFv0zAQfs+vONJO3RDNxCsSQoMVrdK2Vl03CSHkesllMXLsYDvZivjx2GmTOG0YfWhV+7u7 -73z33Y1gnTENKeMIeakNPCKUGhP7xcQTbCJ4ZOKcxoZV1GCUMp1t4O0zMxkTQEGVQjicO4dTyIwp -Ppyfu386Q86jWOZwBhq1ZlK8jYIRXEoQ0jhDYAYSpjA2fBsFQVoKG0UKSLAJB9MEJrMXi6uYMiXl -KCrIZYJARQIKTakEGAkmQ+tU5ZSDRTAlRY7CRJMA7GdkgRoNSJ74t1BRxegjR12jWAoGbfpTAeGY -LK4vycN8tb6/uCbLi/VVWGPcx3maPr2AO4VjYB+HMAxAkQT/i/ptfbW4vVrczAZit3eHDNqL13n0 -Ya+w+Tq/uyLL1eJmuSaLh9lqNb/0+IzgznqnAjAvzBa4jG0BNmNXfdJUkxTU2I6xRaKcy+e6VApz -WVmoTGFTgwslrYdN03ONrbbMN1E/FQ7H7gOP0UxRjV67TPRBjF3naCMV1mSkYk9MUN7F8cODZzsE -iIHYviIe6n8WeGQxWKuhl+9Xa49uijq7fehXMRxT9VR9f/8jhDcfYSKkSOyxKp22cNIrIk+nzd2b -Yc7FNpHx8FUn15ZfzXEE98JxZEohx4r6kosCT+R9ZkHQtLmXGYSEeH8JCTvYkcRgXAutp9Rw7Jmf -E/J5fktuL25m1tMe3vLdjDt9bNxr2sMo2P3C9BccqGeYhqfQITz6XurXaqdf99LF1mT2YJrvzqCu -5w7dKvV3PzNyOb+7+Hw923dOuB+AX2SxrZs9Lm0xbCH6kmhjUyuWw+7cC7DX8367H3VzDz6oBtty -tMIeobE21JT6HaRS+TbaoqhbE7rgdGs3xtE4cOF3xo0TfxwsdyRlhUoxuzes18r+Jp88zDx1G+kd -/HTrr1BY2CeuyfnbQtAcu9j+pOw6cy9X0k3IuoyKCZPC5ESf6MkgHE5tLiSW3Oa+W2NnrQfkGv/h -7tR5PNFnMBlw4B9NJTxnzKA9fLTT0aXSb5vw7FUKzcTZPddqYHi2T9/axJmEEN3qHncVCuEPaFmq -uEtpcBj2Z1wjrqGReJBHrY6/go21NA== +eJyFVVFv2zYQftevuMoOnBS1gr0WGIZ08RADSRw4boBhGGhGOsUcKFIjKbUu9uN7lC2JsrXWDzZM +fnf38e6+uwlsdsJCLiRCUVkHrwiVxYy+hHqDbQKvQl3z1ImaO0xyYXdbeP9FuJ1QwMFUSnmcP4dL +2DlXfry+9v/sDqVMUl3AFVi0Vmj1PokmcKtBaecNQTjIhMHUyX0SRXmlKIpWkGEbDuYZzBZfCVcL +4youUdVQ6AyBqwwMusoocBrcDsmpKbgEQgijVYHKJbMI6DMhoEUHWmbhLdTcCP4q0TYokYNDev5c +QTxlq/tb9rJcbz7f3LOnm81d3GD8x3uav30FfwrnwCEOYRyAKot+FvXPzd3q8W71sBiJ3d2dMugu +fsxjCPsBmz+Wz3fsab16eNqw1ctivV7eBnwm8EzeuQIsSrcHqVMqwHbqq8/aarKSO+oYKhKXUn9p +SmWw0DVBdQ7bBlwaTR62bc+1tpaYb5PhUyScu48CRgvDLQbtMrMnMQ6dY5022JDRRrwJxWUfJwwP +ge0YIAVGfcUC1M8s8MxitFZjmR9W64hui7p4fBlWMZ5y81b/9cvfMbz7FWZKq4yOTeW1hbNBEWU+ +b+/ejXMu95lOx696uXb8Go4T+Kw8R2EMSqx5KLkkCkQ+ZBZFbZsHL4OYseAvY3EPO5MYTBuhDZQa +TwPza8Y+LR/Z483Dgjwd4R3f7bTXx9Znkw6T6PAL83/hRD3jNAKFjuEx9NJkq5t+fabLvdvRwbw4 +nEFTzwO6U+q34cvY7fL55tP94tg58XEA/q7LfdPsaUXFoEIMJdHF5iSW0+48CnDQ82G7n3XzAD6q +Bmo5XuOA0NQ67ir7AXJtQhtLKO7XhC0l39PGOBsHPvzBuHUSjoOnA0ldozGC9gZ5rek3+y3ALHO/ +kT7AP379lQZLSnFDLtwWihfYxw4nZd+ZR7myfkI2ZTRCuRxmF/bCzkbhcElvYamW9PbDGrvqPKC0 ++D/uLi/sFcxGjOHylYagZzzsjjhw206RQwrWIwOxS2dnk+40xOjX8bTPegz/gdWVSXuaowNuOLda +wYyNuRPSTcd/B48Ppeg= """) ##file activate.csh diff --git a/thirdparty/base/virtualenv.py.ABOUT b/thirdparty/base/virtualenv.py.ABOUT index bd645afa..e2f23b7b 100644 --- a/thirdparty/base/virtualenv.py.ABOUT +++ b/thirdparty/base/virtualenv.py.ABOUT @@ -1,6 +1,6 @@ about_resource: virtualenv.py -version: 15.0.0 -download_url: https://github.com/pypa/virtualenv/raw/15.0.0/virtualenv.py +version: 15.1.0 +download_url: https://raw.githubusercontent.com/pypa/virtualenv/15.1.0/virtualenv.py vcs_tool: git vcs_repository: https://github.com/pypa/virtualenv.git @@ -14,4 +14,4 @@ license_text_file: virtualenv.LICENSE dje_license: mit copyright: Copyright (c) 2007 Ian Bicking and Contributors Copyright (c) 2009 Ian Bicking, The Open Planning Project - Copyright (c) 2011-2015 The virtualenv developers + Copyright (c) 2011-2016 The virtualenv developers diff --git a/thirdparty/base/wheel-0.24.0-py2.py3-none-any.whl b/thirdparty/base/wheel-0.24.0-py2.py3-none-any.whl deleted file mode 100644 index 3355a171..00000000 Binary files a/thirdparty/base/wheel-0.24.0-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/base/wheel-0.29.0-py2.py3-none-any.whl b/thirdparty/base/wheel-0.29.0-py2.py3-none-any.whl new file mode 100644 index 00000000..506d5e52 Binary files /dev/null and b/thirdparty/base/wheel-0.29.0-py2.py3-none-any.whl differ diff --git a/thirdparty/base/wheel.ABOUT b/thirdparty/base/wheel.ABOUT index 2fffd2ea..cd47c698 100644 --- a/thirdparty/base/wheel.ABOUT +++ b/thirdparty/base/wheel.ABOUT @@ -1,6 +1,6 @@ -about_resource: wheel-0.24.0-py2.py3-none-any.whl -version: 0.24.0 -download_url: https://pypi.python.org/packages/py2.py3/w/wheel/wheel-0.24.0-py2.py3-none-any.whl#md5=4c24453cda2177fd42c5d62d6434679a +about_resource: wheel-0.29.0-py2.py3-none-any.whl +version: 0.29.0 +download_url: https://pypi.python.org/packages/py2.py3/w/wheel/wheel-0.29.0-py2.py3-none-any.whl name: wheel home_url: https://bitbucket.org/pypa/wheel diff --git a/thirdparty/dev/apache-2.0.LICENSE b/thirdparty/dev/apache-2.0.LICENSE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/thirdparty/dev/apache-2.0.LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/thirdparty/dev/apipkg-1.4-py2.py3-none-any.whl b/thirdparty/dev/apipkg-1.4-py2.py3-none-any.whl new file mode 100644 index 00000000..724449d9 Binary files /dev/null and b/thirdparty/dev/apipkg-1.4-py2.py3-none-any.whl differ diff --git a/thirdparty/dev/apipkg.ABOUT b/thirdparty/dev/apipkg.ABOUT new file mode 100644 index 00000000..af140f97 --- /dev/null +++ b/thirdparty/dev/apipkg.ABOUT @@ -0,0 +1,10 @@ +about_resource: apipkg-1.4-py2.py3-none-any.whl +download_url: https://pypi.python.org/packages/94/72/fd4f2e46ce7b0d388191c819ef691c8195fab09602bbf1a2f92aa5351444/apipkg-1.4-py2.py3-none-any.whl#md5=5644eb6aff3f19e13430251a820e987f +version: 1.4.1 + +name: apipkg +home_url: https://bitbucket.org/hpk42/apipkg +owner: Holger Krekel +dje_license: mit +license_text_file: apipkg.LICENSE +copyright: Copyright (c) 2009 holger krekel diff --git a/thirdparty/dev/apipkg.LICENSE b/thirdparty/dev/apipkg.LICENSE new file mode 100644 index 00000000..31ecdfb1 --- /dev/null +++ b/thirdparty/dev/apipkg.LICENSE @@ -0,0 +1,19 @@ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + diff --git a/thirdparty/dev/py-1.4.31-py2.py3-none-any.whl b/thirdparty/dev/py-1.4.31-py2.py3-none-any.whl deleted file mode 100644 index 69eef310..00000000 Binary files a/thirdparty/dev/py-1.4.31-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/dev/py-1.4.33-py2.py3-none-any.whl b/thirdparty/dev/py-1.4.33-py2.py3-none-any.whl new file mode 100644 index 00000000..b5cd8d45 Binary files /dev/null and b/thirdparty/dev/py-1.4.33-py2.py3-none-any.whl differ diff --git a/thirdparty/dev/py.ABOUT b/thirdparty/dev/py.ABOUT index 82d46b08..ddf13db3 100644 --- a/thirdparty/dev/py.ABOUT +++ b/thirdparty/dev/py.ABOUT @@ -1,15 +1,14 @@ -about_resource: py-1.4.31-py2.py3-none-any.whl -version: 1.4.31 -download_url: https://pypi.python.org/packages/source/p/py/py-1.4.31.tar.gz +about_resource: py-1.4.33-py2.py3-none-any.whl +version: 1.4.33 +download_url: https://pypi.python.org/packages/92/8b/ac214296ed28a05efd36e8b55a7820eda62d7028ecf10e5a98afb1982e93/py-1.4.33-py2.py3-none-any.whl name: py description: library with cross-python path, ini-parsing, io, code, log facilities -homepage: http://pylib.readthedocs.org/ +home_url: http://pylib.readthedocs.org/ owner: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others -contact: pytest-dev@python.org -license: mit -license_file: py.LICENSE -copyright: Copyright (c) Holger Krekel and others - - - +contatct: pytest-dev@python.org +dje_license: mit +license_text_file: py.LICENSE +copyright: copyright (c) 2004-2014 Holger Krekel and others +vcs_tool: git +vcs_repo: https://github.com/pytest-dev/py.git \ No newline at end of file diff --git a/thirdparty/dev/pytest-2.9.0-py2.py3-none-any.whl b/thirdparty/dev/pytest-2.9.0-py2.py3-none-any.whl deleted file mode 100644 index 69fdebb0..00000000 Binary files a/thirdparty/dev/pytest-2.9.0-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/dev/pytest-3.1.0-py2.py3-none-any.whl b/thirdparty/dev/pytest-3.1.0-py2.py3-none-any.whl new file mode 100644 index 00000000..dfaf980a Binary files /dev/null and b/thirdparty/dev/pytest-3.1.0-py2.py3-none-any.whl differ diff --git a/thirdparty/dev/pytest.ABOUT b/thirdparty/dev/pytest.ABOUT index 99505365..4d96e94e 100644 --- a/thirdparty/dev/pytest.ABOUT +++ b/thirdparty/dev/pytest.ABOUT @@ -1,12 +1,14 @@ -download_url: https://pypi.python.org/packages/source/p/pytest/pytest-2.9.0.tar.gz -about_resource: pytest-2.9.0-py2.py3-none-any.whl -version: 2.9.0 +about_resource: pytest-3.1.0-py2.py3-none-any.whl +download_url: https://pypi.python.org/packages/55/9c/5529093be0f518fe710d5b925680429c24810dadd6519c0ca86435656e85/pytest-3.1.0-py2.py3-none-any.whl +version: 3.1.0 name: pytest -description: pytest:simple powerful testing with Python -homepage: http://pytest.org +description: pytest: simple powerful testing with Python +home_url: http://pytest.org owner: Holger Krekel, Benjamin Peterson, Ronny Pfannschmidt, Floris Bruynooghe and others contact: holger at merlinux.eu -license: mit -license_file: pytest.LICENSE -copyright: Copyright (c) 2004-2016 Holger Krekel and others +dje_license: mit +license_text_file: pytest.LICENSE +copyright: Copyright Holger Krekel and others, 2004-2014 +vcs_tool: git +vcs_repo: https://github.com/pytest-dev/pytest.git \ No newline at end of file diff --git a/thirdparty/prod/Jinja2-2.7.3-py2-none-any.whl b/thirdparty/prod/Jinja2-2.7.3-py2-none-any.whl deleted file mode 100644 index 83a82bea..00000000 Binary files a/thirdparty/prod/Jinja2-2.7.3-py2-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/Jinja2-2.9.6-py2.py3-none-any.whl b/thirdparty/prod/Jinja2-2.9.6-py2.py3-none-any.whl new file mode 100644 index 00000000..9fb201e6 Binary files /dev/null and b/thirdparty/prod/Jinja2-2.9.6-py2.py3-none-any.whl differ diff --git a/thirdparty/prod/Jinja2.ABOUT b/thirdparty/prod/Jinja2.ABOUT index 64040866..e30b2dfd 100644 --- a/thirdparty/prod/Jinja2.ABOUT +++ b/thirdparty/prod/Jinja2.ABOUT @@ -1,15 +1,9 @@ -about_resource: Jinja2-2.7.3-py2-none-any.whl -version: 2.7.3 -download_url: https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.7.3.tar.gz#md5=b9dffd2f3b43d673802fe857c8445b1a +about_resource: Jinja2-2.9.6-py2.py3-none-any.whl +version: 2.9.6 +download_url: https://pypi.python.org/packages/5e/73/10c45b82a88ed6b7751bd40da31eeefd7b362e07b56a99aa6e56655a0794/Jinja2-2.9.6-py2.py3-none-any.whl#md5=61a215bcdb0f7939c70582bc00b293f1 name: Jinja2 -homepage: http://jinja.pocoo.org/ - -license: bsd-new -license_file: Jinja2.LICENSE - -vcs_tool: git -vcs_repository: https://github.com/mitsuhiko/jinja2.git - -owner: Armin Ronacher +dje_license: bsd-new copyright: Copyright (c) 2009 by the Jinja Team +license_text_file: Jinja2.LICENSE +home_url: http://jinja.pocoo.org/ diff --git a/thirdparty/prod/Jinja2.LICENSE b/thirdparty/prod/Jinja2.LICENSE index 31bf900e..5a0acde8 100644 --- a/thirdparty/prod/Jinja2.LICENSE +++ b/thirdparty/prod/Jinja2.LICENSE @@ -28,4 +28,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/thirdparty/prod/MarkupSafe-0.23-py2-none-any.whl b/thirdparty/prod/MarkupSafe-0.23-py2-none-any.whl deleted file mode 100644 index 6de5f499..00000000 Binary files a/thirdparty/prod/MarkupSafe-0.23-py2-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/MarkupSafe-1.0.tar.gz b/thirdparty/prod/MarkupSafe-1.0.tar.gz new file mode 100644 index 00000000..606021ae Binary files /dev/null and b/thirdparty/prod/MarkupSafe-1.0.tar.gz differ diff --git a/thirdparty/prod/MarkupSafe.ABOUT b/thirdparty/prod/MarkupSafe.ABOUT index 927598c0..2ef53beb 100644 --- a/thirdparty/prod/MarkupSafe.ABOUT +++ b/thirdparty/prod/MarkupSafe.ABOUT @@ -1,15 +1,9 @@ -about_resource: MarkupSafe-0.23-py2-none-any.whl -version: 0.23 -download_url: https://pypi.python.org/packages/source/m/MarkupSafe/MarkupSafe-0.23.tar.gz +about_resource: MarkupSafe-1.0.tar.gz +version: 1.0 +download_url: https://pypi.python.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz#md5=2fcedc9284d50e577b5192e8e3578355 name: MarkupSafe -homepage: https://github.com/mitsuhiko/markupsafe - -license: bsd-new - -vcs_tool: git -vcs_repository: https://github.com/mitsuhiko/markupsafe -license_file: MarkupSafe.LICENSE - -copyright: Copyright (c) 2010 by Armin Ronacher and contributors. -owner: Armin Ronacher +dje_license: bsd-new +copyright: Copyright (c) 2010 by Armin Ronacher and contributors +license_text_file: MarkupSafe.LICENSE +home_url: https://github.com/pallets/markupsafe diff --git a/thirdparty/prod/MarkupSafe.LICENSE b/thirdparty/prod/MarkupSafe.LICENSE index 5d269389..0a486d61 100644 --- a/thirdparty/prod/MarkupSafe.LICENSE +++ b/thirdparty/prod/MarkupSafe.LICENSE @@ -30,4 +30,4 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. +DAMAGE. \ No newline at end of file diff --git a/thirdparty/prod/PSF.LICENSE b/thirdparty/prod/PSF.LICENSE new file mode 100644 index 00000000..b6bddd8f --- /dev/null +++ b/thirdparty/prod/PSF.LICENSE @@ -0,0 +1,48 @@ +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights +Reserved" are retained in Python alone or in any derivative version prepared by +Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. diff --git a/thirdparty/prod/PyYAML-3.11-py2.py3-none-any.whl b/thirdparty/prod/PyYAML-3.11-py2.py3-none-any.whl deleted file mode 100644 index 5dedfc0a..00000000 Binary files a/thirdparty/prod/PyYAML-3.11-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/PyYAML-3.11.tar.gz b/thirdparty/prod/PyYAML-3.11.tar.gz deleted file mode 100644 index 2a5d4310..00000000 Binary files a/thirdparty/prod/PyYAML-3.11.tar.gz and /dev/null differ diff --git a/thirdparty/prod/PyYAML-3.12-py2-none-any.whl b/thirdparty/prod/PyYAML-3.12-py2-none-any.whl new file mode 100644 index 00000000..c301d137 Binary files /dev/null and b/thirdparty/prod/PyYAML-3.12-py2-none-any.whl differ diff --git a/thirdparty/prod/PyYAML-3.12-py3-none-any.whl b/thirdparty/prod/PyYAML-3.12-py3-none-any.whl new file mode 100644 index 00000000..4c971df0 Binary files /dev/null and b/thirdparty/prod/PyYAML-3.12-py3-none-any.whl differ diff --git a/thirdparty/prod/PyYAML-3.12.tar.gz b/thirdparty/prod/PyYAML-3.12.tar.gz new file mode 100644 index 00000000..aabee39f Binary files /dev/null and b/thirdparty/prod/PyYAML-3.12.tar.gz differ diff --git a/thirdparty/prod/backports.csv-1.0.5-py2.py3-none-any.whl b/thirdparty/prod/backports.csv-1.0.5-py2.py3-none-any.whl new file mode 100644 index 00000000..7babb3c2 Binary files /dev/null and b/thirdparty/prod/backports.csv-1.0.5-py2.py3-none-any.whl differ diff --git a/thirdparty/prod/backports.csv.ABOUT b/thirdparty/prod/backports.csv.ABOUT new file mode 100644 index 00000000..64b53bd7 --- /dev/null +++ b/thirdparty/prod/backports.csv.ABOUT @@ -0,0 +1,13 @@ +about_resource: backports.csv-1.0.5-py2.py3-none-any.whl +version: 1.0.5 +download_url: https://pypi.python.org/packages/23/01/0b1fce3fd8199fe32338dc66747baad52c7183b7f587128bc77cefde0620/backports.csv-1.0.5-py2.py3-none-any.whl#md5=2b3dc8b5ca0a6f50ed50595a074ed870 + +name: backports.csv +homepage: https://github.com/ryanhiebert/backports.csv +owner: Ryan Hiebert + +license: python +license_file: PSF.LICENSE + +vcs_tool: git +vcs_repository: https://github.com/ryanhiebert/backports.csv.git diff --git a/thirdparty/prod/backports.csv.NOTICE b/thirdparty/prod/backports.csv.NOTICE new file mode 100644 index 00000000..3d3b2c3a --- /dev/null +++ b/thirdparty/prod/backports.csv.NOTICE @@ -0,0 +1,2 @@ +backports.csv is a backport of the csv module from Python 3. +Because of this fact, it is released under the same license as Python. diff --git a/thirdparty/prod/boolean.py-3.0.dev5-py2.py3-none-any.whl b/thirdparty/prod/boolean.py-3.0.dev5-py2.py3-none-any.whl deleted file mode 100644 index 135053ee..00000000 Binary files a/thirdparty/prod/boolean.py-3.0.dev5-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/boolean.py-3.5-py2.py3-none-any.whl b/thirdparty/prod/boolean.py-3.5-py2.py3-none-any.whl new file mode 100644 index 00000000..5fe68e51 Binary files /dev/null and b/thirdparty/prod/boolean.py-3.5-py2.py3-none-any.whl differ diff --git a/thirdparty/prod/boolean.py.ABOUT b/thirdparty/prod/boolean.py.ABOUT index dce96c3e..220bf74e 100644 --- a/thirdparty/prod/boolean.py.ABOUT +++ b/thirdparty/prod/boolean.py.ABOUT @@ -1,6 +1,6 @@ -about_resource: boolean.py-3.0.dev5-py2.py3-none-any.whl -version: 3.0.dev5 -download_url: https://pypi.python.org/packages/dc/07/6c3ed91d7c02ba9a8584fbac997378b329a69a9b06dc90fa18242b8ef020/boolean.py-3.0.dev5-py2.py3-none-any.whl +about_resource: boolean.py-3.5-py2.py3-none-any.whl +version: 3.5 +download_url: https://pypi.python.org/packages/80/f3/0508ae7ba76b02f7fd666b705766edc1863fc8ef29d0519b4c95d60ab1bb/boolean.py-3.5-py2.py3-none-any.whl#md5=cf90b0c0530663bbf71a53fb58f6fa72 name: boolean.py diff --git a/thirdparty/prod/click-3.3-py2.py3-none-any.whl b/thirdparty/prod/click-3.3-py2.py3-none-any.whl deleted file mode 100644 index e2749112..00000000 Binary files a/thirdparty/prod/click-3.3-py2.py3-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/click-6.7-py2.py3-none-any.whl b/thirdparty/prod/click-6.7-py2.py3-none-any.whl new file mode 100644 index 00000000..56c7ff34 Binary files /dev/null and b/thirdparty/prod/click-6.7-py2.py3-none-any.whl differ diff --git a/thirdparty/prod/click.ABOUT b/thirdparty/prod/click.ABOUT index 091be73f..26e0e85b 100644 --- a/thirdparty/prod/click.ABOUT +++ b/thirdparty/prod/click.ABOUT @@ -1,16 +1,17 @@ -about_resource: click-3.3-py2.py3-none-any.whl -version: 3.3 -download_url: https://pypi.python.org/packages/2.7/c/click/click-3.3-py2.py3-none-any.whl +about_resource: click-6.7-py2.py3-none-any.whl +version: 6.7 +download_url: https://pypi.python.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl#md5=5e7a4e296b3212da2ff11017675d7a4d name: click + owner: Armin Ronacher contact: armin.ronacher@active-4.com -homepage: http://click.pocoo.org/ +homepage:http://click.pocoo.org/ vcs_tool: git -vcs_repository: https://github.com/mitsuhiko/click.git -description: A simple wrapper around optparse for +vcs_repository: https://github.com/pallets/click.git +description: A simple wrapper around optparse for powerful command line utilities. license: bsd-new license_file: click.LICENSE -notes: Click uses parts of optparse written by Gregory P. Ward and maintained +notes: Click uses parts of optparse written by Gregory P. Ward and maintained by the Python software foundation. This is limited to code in the parser.py module and is under the same license as clikc itself. \ No newline at end of file diff --git a/thirdparty/prod/click.LICENSE b/thirdparty/prod/click.LICENSE index 1704daa2..012b628f 100644 --- a/thirdparty/prod/click.LICENSE +++ b/thirdparty/prod/click.LICENSE @@ -35,4 +35,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/thirdparty/prod/colorama-0.3.1-py2-none-any.whl b/thirdparty/prod/colorama-0.3.1-py2-none-any.whl deleted file mode 100644 index 801381a7..00000000 Binary files a/thirdparty/prod/colorama-0.3.1-py2-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/colorama-0.3.9-py2.py3-none-any.whl b/thirdparty/prod/colorama-0.3.9-py2.py3-none-any.whl new file mode 100644 index 00000000..29b83f06 Binary files /dev/null and b/thirdparty/prod/colorama-0.3.9-py2.py3-none-any.whl differ diff --git a/thirdparty/prod/colorama.ABOUT b/thirdparty/prod/colorama.ABOUT index f790c5de..54f1fb7e 100644 --- a/thirdparty/prod/colorama.ABOUT +++ b/thirdparty/prod/colorama.ABOUT @@ -1,10 +1,12 @@ -about_resource: colorama-0.3.1-py2-none-any.whl +about_resource: colorama-0.3.9-py2.py3-none-any.whl +download_url: https://pypi.python.org/packages/db/c8/7dcf9dbcb22429512708fe3a547f8b6101c0d02137acbd892505aee57adf/colorama-0.3.9-py2.py3-none-any.whl#md5=cc0c01c7b3b34d0354d813e9ab26aca3 +version: 0.3.9 + name: colorama -version: 0.3.1 -description: Cross-platform colored terminal text. -homepage: https://pypi.python.org/pypi/colorama +description: Cross-platform colored terminal text +home_url: https://pypi.python.org/pypi/colorama owner: Jonathan Hartley -contact: tartley@tartley.com -license: bds-new -license_file: colorama.LICENSE -download_url: https://pypi.python.org/packages/source/c/colorama/colorama-0.3.1.tar.gz#md5=95ce8bf32f5c25adea14b809db3509cb \ No newline at end of file +dje_license: bds-new +keywords: color colour terminal text ansi windows crossplatform xplatform +license_text_file: colorama.LICENSE +copyright: Copyright (c) 2010 Jonathan Hartley \ No newline at end of file diff --git a/thirdparty/prod/license-expression.NOTICE b/thirdparty/prod/license-expression.NOTICE new file mode 100644 index 00000000..46142d0a --- /dev/null +++ b/thirdparty/prod/license-expression.NOTICE @@ -0,0 +1,17 @@ +Software license +================ + +license-expression is a free software tool from nexB Inc. and others. +Visit https://github.com/nexB/license-expression for support and download. + +Copyright (c) 2017 nexB Inc. and others. All rights reserved. +http://nexb.com and http://aboutcode.org + +This software is licensed under the Apache License version 2.0. + +You may not use this software except in compliance with the License. +You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/thirdparty/prod/license_expression-0.4-py2-none-any.whl b/thirdparty/prod/license_expression-0.4-py2-none-any.whl deleted file mode 100644 index 20acfd7b..00000000 Binary files a/thirdparty/prod/license_expression-0.4-py2-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/license_expression-0.94-py2.py3-none-any.whl b/thirdparty/prod/license_expression-0.94-py2.py3-none-any.whl new file mode 100644 index 00000000..c6c8a266 Binary files /dev/null and b/thirdparty/prod/license_expression-0.94-py2.py3-none-any.whl differ diff --git a/thirdparty/prod/license_expression.ABOUT b/thirdparty/prod/license_expression.ABOUT index 52d37413..14f7b977 100644 --- a/thirdparty/prod/license_expression.ABOUT +++ b/thirdparty/prod/license_expression.ABOUT @@ -1,11 +1,12 @@ -about_resource: license_expression-0.4-py2-none-any.whl +about_resource: license_expression-0.94py2.py3-none-any.whl name: license-expression -version: 0.4 -download_url: https://pypi.python.org/packages/72/70/aed8505711db9c3c295658914e83f114161451017c20c34a2280d2d228f2/license_expression-0.4-py2-none-any.whl#md5=8c5ca89b7826d564f140032be5800fc3 +version: 0.94 +download_url: https://pypi.python.org/packages/d8/a5/24528298829a430d4ace4de39d7ae1cd94482c55aa5d6dceb98c1ae163a6/license_expression-0.94-py2.py3-none-any.whl#md5=19404419f6fe0db20a09f1416207138f -copyright: Copyright (c) 2016 nexB Inc. and others. +copyright: Copyright (c) 2017 nexB Inc. and others. +owner: nexB Inc. dje_license: apache-2.0 license_text_file: apache-2.0.LICENSE - -home_url: https://github.com/nexB/license-expression \ No newline at end of file +notice_file: license-expression.NOTICE +home_url: https://github.com/nexB/license-expression diff --git a/thirdparty/prod/pyyaml.ABOUT b/thirdparty/prod/pyyaml.ABOUT deleted file mode 100644 index 2594ce9d..00000000 --- a/thirdparty/prod/pyyaml.ABOUT +++ /dev/null @@ -1,17 +0,0 @@ -about_resource: - - PyYAML-3.11-py2.py3-none-any.whl - - PyYAML-3.11.tar.gz -download_url: https://pypi.python.org/packages/source/P/PyYAML/PyYAML-3.11.tar.gz#md5=f50e08ef0fe55178479d3a618efe21db -version: 3.11 - -name: PyYAML - -homepage: http://pyyaml.org/wiki/PyYAML -copyright: Copyright (c) 2006 Kirill Simonov -owner: Kirill Simonov -contact: xi@resolvent.net - -license: mit -license_file: pyyaml.LICENSE - -description: YAML parser and emitter for Python diff --git a/thirdparty/prod/pyyaml.py2.ABOUT b/thirdparty/prod/pyyaml.py2.ABOUT new file mode 100644 index 00000000..49ffdb11 --- /dev/null +++ b/thirdparty/prod/pyyaml.py2.ABOUT @@ -0,0 +1,15 @@ +about_resource: PyYAML-3.12-py2-none-any.whl +download_url: https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950 +version: 3.12 + +name: PyYAML + +home_url: http://pyyaml.org/wiki/PyYAML +copyright: Copyright (c) 2006 Kirill Simonov +owner: Kirill Simonov +contact: xi@resolvent.net + +dje_license: mit +license_text_file: pyyaml.LICENSE + +description: YAML parser and emitter for Python diff --git a/thirdparty/prod/pyyaml.py3.ABOUT b/thirdparty/prod/pyyaml.py3.ABOUT new file mode 100644 index 00000000..7f6373d4 --- /dev/null +++ b/thirdparty/prod/pyyaml.py3.ABOUT @@ -0,0 +1,15 @@ +about_resource: PyYAML-3.12-py3-none-any.whl +download_url: https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950 +version: 3.12 + +name: PyYAML + +home_url: http://pyyaml.org/wiki/PyYAML +copyright: Copyright (c) 2006 Kirill Simonov +owner: Kirill Simonov +contact: xi@resolvent.net + +dje_license: mit +license_text_file: pyyaml.LICENSE + +description: YAML parser and emitter for Python diff --git a/thirdparty/prod/pyyaml.tar.ABOUT b/thirdparty/prod/pyyaml.tar.ABOUT new file mode 100644 index 00000000..b91e4699 --- /dev/null +++ b/thirdparty/prod/pyyaml.tar.ABOUT @@ -0,0 +1,15 @@ +about_resource: PyYAML-3.12.tar.gz +download_url: https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950 +version: 3.12 + +name: PyYAML + +home_url: http://pyyaml.org/wiki/PyYAML +copyright: Copyright (c) 2006 Kirill Simonov +owner: Kirill Simonov +contact: xi@resolvent.net + +dje_license: mit +license_text_file: pyyaml.LICENSE + +description: YAML parser and emitter for Python diff --git a/thirdparty/prod/unicodecsv-0.9.4-py2-none-any.whl b/thirdparty/prod/unicodecsv-0.9.4-py2-none-any.whl deleted file mode 100644 index 22b971c7..00000000 Binary files a/thirdparty/prod/unicodecsv-0.9.4-py2-none-any.whl and /dev/null differ diff --git a/thirdparty/prod/unicodecsv.ABOUT b/thirdparty/prod/unicodecsv.ABOUT deleted file mode 100644 index 41775764..00000000 --- a/thirdparty/prod/unicodecsv.ABOUT +++ /dev/null @@ -1,13 +0,0 @@ -about_resource: unicodecsv-0.9.4-py2-none-any.whl -version: 0.9.4 -download_url: https://pypi.python.org/packages/source/u/unicodecsv/unicodecsv-0.9.4.tar.gz#md5=344fa55f299ba198cb73db48546002fd - -name: unicodecsv -homepage: https://github.com/jdunck/python-unicodecsv -owner: Jeremy Dunck - -license: bsd-new -license_file: unicodecsv.LICENSE - -vcs_tool: git -vcs_repository: https://github.com/jdunck/python-unicodecsv.git diff --git a/thirdparty/prod/unicodecsv.LICENSE b/thirdparty/prod/unicodecsv.LICENSE deleted file mode 100644 index 6d004c77..00000000 --- a/thirdparty/prod/unicodecsv.LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2010 Jeremy Dunck. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this list of - conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, this list - of conditions and the following disclaimer in the documentation and/or other materials - provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY JEREMY DUNCK ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JEREMY DUNCK OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those of the -authors and should not be interpreted as representing official policies, either expressed -or implied, of Jeremy Dunck.