diff --git a/.gitignore b/.gitignore index 09aa2e97..50c831c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.py[cod] +.Python /build /bin @@ -9,6 +10,7 @@ lib64 /Lib /Scripts /include +/local # Installer logs pip-log.txt @@ -29,4 +31,6 @@ nosetests.xml # PyCharm project .idea/ -/about_code_tool.egg_info \ No newline at end of file + +/*.egg-info/ +/.cache/ diff --git a/.travis.yml b/.travis.yml index 61f978c0..d5196b43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: python python: - - "2.6" - "2.7" install: - source configure etc/conf diff --git a/README.rst b/README.rst index a6439f24..8534180f 100644 --- a/README.rst +++ b/README.rst @@ -1,14 +1,14 @@ -ABOUT tool -========== +AboutCode tool +============== -.. image:: https://api.travis-ci.org/dejacode/about-code-tool.png?branch=develop - :target: https://travis-ci.org/dejacode/about-code-tool +.. image:: https://travis-ci.org/dejacode/about-code-tool.svg?branch=master + :target: https://travis-ci.org/dejacode/about-code-tool -.. image:: https://coveralls.io/repos/dejacode/about-code-tool/badge.png?branch=develop - :target: https://coveralls.io/r/dejacode/about-code-tool?branch=develop +.. image:: https://coveralls.io/repos/dejacode/about-code-tool/badge.svg?branch=master + :target: https://coveralls.io/r/dejacode/about-code-tool?branch=master -The ABOUT tool and ABOUT files provide a simple way to document the +The AboutCode tool and ABOUT files provide a simple way to document the (origin and license) and other important or interesting information about third-party software components that you use in your project. @@ -19,66 +19,108 @@ For more information on the ABOUT file format, visit http://www.dejacode.org There are many examples of ABOUT files (valid or invalid) in the testdata/ directory of the whole repository. -The current version of the ABOUT tool can read these ABOUT files so that you +The current version of AboutCode can read these ABOUT files so that you can collect and validate the inventory of third-party components that you use. -In future versions, this tool will be able to generate attribution notices and -collect redistributable source code used in your project to help you comply -with open source licenses requirements. +This version of AboutCode follows the ABOUT specification version 1.0.0 at: +https://github.com/dejacode/about-code-tool/blob/master/SPEC -This version of the ABOUT tool follows the ABOUT specification version 0.8.1 at: -http://www.dejacode.org/about_spec_v0.8.1.html +License +------- +AboutCode is released under the Apache 2.0 license. +See (of course) the about.ABOUT file for details. -REQUIREMENTS + +Requirements ------------ -The ABOUT tool is tested with Python 2.6 or 2.7 on Linux, Mac and Windows. -You will need to install a Python interpreter if you do not have one already -installed. +The AboutCode tool requires an installation Python 2.7 on Linux, Mac and Windows. +You need to install Python if you do not have one already installed. 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.6 --version python2.7 --version -On Windows or Mac, you can download the latest Python 2.7.x here: - https://www.python.org/downloads/ +On Linux, Python2.7 may be available from your distro package manager. + +On Windows and Mac if version 2.7 is not installed, you can download the latest +Python 2.7.x here https://www.python.org/downloads/ : -Download the .msi installer for Windows or the .dmg archive for Mac. -Open and run the installer using all the default options. +* Download the .msi installer for Windows or the .dmg archive for Mac. +* Open and run the installer using all the default options. +* On Windows, make sure you install Python in the default c:\\Python27 and not + on another drive. -INSTALLATION +Installation ------------ -Checkout or download and extract the AboutCode tool from: - https://github.com/dejacode/about-code-tool/ +Download the AboutCode tool from a released version at: + https://github.com/dejacode/about-code-tool/releases + +Extract the archive to a directory and open a command prompt or shell in this +directory. Then on Linux or Mac run:: + + source configure + +And on Windows:: -To install all the needed dependencies in a virtualenv, run (on posix):: - source configure -or on windows:: configure -TESTS ------ -To verify that everything works fine you can run the test suite with:: - python setup.py test +For instance on Linux the whole installation would be like this:: + + $ wget https://github.com/dejacode/about-code-tool/archive/v2.3.2.zip + $ unzip v2.3.2.zip + $ cd attributecode-2.3.2/ + $ source configure + +On Windows, the whole installation would be like this: + * Download and extract https://github.com/dejacode/about-code-tool/archive/v2.3.2.zip + * open a command prompt and cd to the directory where the zip extraction directory + * run configure -USAGE + +Later on, if opening a new shell or command prompt on an already installed +AboutCode you need to **activate** this installation. + +On Linux or Mac, run this:: + + source bin/activate + +On Windows, run this:: + + bin\\activate + + +Usage ----- -The ABOUT tool command syntax is: +Once installed, the AboutCode tool is used from the command line. +There are three scripts: about.py, genabout.py and genattrib.py. +Once you have installed or activated AboutCode, the scripts are invoked from a +shell or command prompt in this way:: + + $ python about_code_tool/about.py + + +See docs/UsingAboutCodetoDocumentYourSoftwareAssets.pdf for a detailed +documentation and tutorial or read on the quick instructions below. + + +**Using the about.py script** -**about.py** +The about.py script is used to collect existing ABOUT files, validate that +they are correct and collect inventories of the documented components in a CSV +file. :: Usage: about.py [options] input_path output_path - Input can be a file or directory. - Output must be a file with a .csv extension. + input_path can be a file or directory containing .ABOUT files. + output_path is a file with a .csv extension. Options: -h, --help Display help @@ -92,20 +134,26 @@ The ABOUT tool command syntax is: Example:: - $ python about.py ./thirdparty_code/ thirdparty_about.csv + $ python about_code_tool/about.py ./thirdparty/ thirdparty_about.csv -In this example, the .ABOUT files in the directory /thirdparty_code/ will + +In this example, the .ABOUT files in the directory thirdparty/ will be parsed and validated to collect the data they contain. The collected information will be saved to the CSV file named "thirdparty_about.csv". -**genabout.py** + + +**Using the genabout.py script** + +The genabout.py script is used to generate new ABOUT files by using a CSV file +as an input. :: Usage: genabout.py [options] input_path output_path - Input must be a CSV file - Output must be a directory location where the ABOUT files should be generated + input_path is a CSV file using the same format as the CSV created with about.py + output_path is a directory where the new .ABOUT files are generated Options: @@ -131,39 +179,44 @@ information will be saved to the CSV file named "thirdparty_about.csv". Copy the 'license_text_file' from the directory to the generated location License path - License text files path - --mapping Configure the mapping key from the MAPPING.CONFIG + --mapping Use the mapping between columns names in your CSV and the ABOUT field + names as defined in the MAPPING.CONFIG mapping configuration file. - --extract_license=EXTRACT_LICENSE + --extract_license Extract License text and create .LICENSE side-by-side - with the .ABOUT from DJE License Library. - api_url - URL to the DJE License Library - api_username - The regular DJE username - api_key - Hash attached to your username which is used to authenticate - yourself in the API. Contact us to get the hash key. - + with the generated .ABOUT file using data fetched from a DejaCode License Library. + The following additional options are required: + --api_url - URL to the DejaCode License Library API endpoint + --api_key - DejaCode API key + Example syntax: - genabout.py --extract_license --api_url='api_url' --api_username='api_username' --api_key='api_key' + python about_code_tool/genabout.py --extract_license --api_url='api_url' --api_key='api_key' Example:: - $ python genabout.py thirdparty_code.csv /tmp/thirdparty_about/ + $ mkdir tmp + $ python about_code_tool/genabout.py thirdparty_code.csv tmp/thirdparty_about + +In this example, the tool will use the list in the "thirdparty_code.csv" file +and generate .ABOUT files in a directory tmp/thirdparty_about/ -In this example, the tool will look at the "thirdparty_code.csv" and generate -the .ABOUT files in the directory /tmp/thirdparty_about/. +**Using the genattrib.py script** -**genattrib.py** +The genattrib.py script is used to generate a credit and license attribution +documentation in HTML from a directory containing .ABOUT files. :: Usage: genattrib.py [options] input_path output_path component_list - - Input can be a file or directory. - Output of rendered template must be a file (e.g. .html). - Component List must be a .csv file which has at least an "about_file" column. - - + + input can be a file or directory. + output of rendered template must be a file (e.g. .html). + component_list is an optional .csv file with an "about_file" column. + It is used to limit the attribution generation to the subset of + ABOUT files listed here. + Options: -h, --help Display help -v, --version Display current version, license notice, and copyright notice @@ -181,7 +234,7 @@ the .ABOUT files in the directory /tmp/thirdparty_about/. Example:: - $ python genattrib.py /tmp/thirdparty_about/ /tmp/thirdparty_attribution/attribution.html thirdparty_code.csv + $ python about_code_tool/genattrib.py tmp/thirdparty_about/ tmp/attribution.html thirdparty_code.csv In this example, the tool will look at the .ABOUT files listed in the "thirdparty_code.csv" from the /tmp/thirdparty_about/ and then generate the attribution output to @@ -190,7 +243,9 @@ from the /tmp/thirdparty_about/ and then generate the attribution output to (See USAGE for a details explaining of each scripts and options.) -HELP and SUPPORT + + +Help and Support ---------------- If you have a question or find a bug, enter a ticket at: @@ -201,19 +256,24 @@ For issues, you can use: https://github.com/dejacode/about-code-tool/issues -SOURCE CODE ------------ -AboutCode is available through GitHub. For the latest version visit: +Hacking, tests and source code +------------------------------ +For the latest stable version visit:: + https://github.com/dejacode/about-code-tool +The development takes places in the develop branch. We use the git flow +branching model. -HACKING -------- -We accept pull requests provided under the same license as this tool. -You agree to the http://developercertificate.org/ +**Tests** +You can run the test suite with:: -LICENSE -------- -AboutCode is released under the Apache 2.0 license. -See (of course) the about.ABOUT file for details. + python setup.py test + + +**Contributing** + +We accept bugs, patches and pull requests for code and documentation provided +under the same license (Apache-2.0) as this tool. +When contributing, you are agreeing to the http://developercertificate.org/ diff --git a/USAGE.rst b/USAGE.rst index bff4de32..bd17f28b 100644 --- a/USAGE.rst +++ b/USAGE.rst @@ -83,12 +83,11 @@ genabout.py Extract License text and create .LICENSE side-by-side with the .ABOUT from DJE License Library. api_url - URL to the DJE License Library - api_username - The regular DJE username - api_key - Hash attached to your username which is used to authenticate - yourself in the API. Contact us to get the hash key. + api_key - Hash which is used to authenticate yourself in the API. + Contact us to get the hash key. Example syntax: - genabout.py --extract_license --api_url='api_url' --api_username='api_username' --api_key='api_key' + genabout.py --extract_license --api_url='api_url' --api_key='api_key' Purpose ------- @@ -177,12 +176,11 @@ Options This option requires 3 parameters: api_url - URL to the DJE License Library - api_username - The regular DJE username - api_key - Hash attached to your username which is used to authenticate - yourself in the API. + api_key - Hash which is used to authenticate yourself in the API. + Contact us to get the hash key. (Please contact us to get the api_* value to use this feature) - $ python genabout.py --extract_license --api_url='api_url' --api_username='api_username' --api_key='api_key' + $ python genabout.py --extract_license --api_url='api_url' --api_key='api_key' genattrib.py diff --git a/about.ABOUT b/about.ABOUT index 81be1884..fff7f2e1 100644 --- a/about.ABOUT +++ b/about.ABOUT @@ -1,7 +1,7 @@ about_resource: . name: AboutCode -version: 2.0.0 +version: 2.3.3 owner: nexB Inc. @@ -21,6 +21,6 @@ description: AboutCode is a tool to process ABOUT files. An ABOUT file dje_license: apache-2.0 license_text_file: apache-2.0.LICENSE license_spdx: Apache-2.0 -copyright: Copyright (c) 2013-2015 nexB Inc. +copyright: Copyright (c) 2013-2016 nexB Inc. notice_file: NOTICE \ No newline at end of file diff --git a/about_code_tool/about.py b/about_code_tool/about.py index 28e86619..7336439c 100644 --- a/about_code_tool/about.py +++ b/about_code_tool/about.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2016 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 @@ -32,41 +32,34 @@ import csv from datetime import datetime from email.parser import HeaderParser -from os.path import basename, dirname, join, normpath, realpath import errno import httplib import logging import optparse import os -import posixpath +from os.path import basename +from os.path import dirname +from os.path import join +from os.path import normpath +from os.path import realpath import socket import string import sys import urlparse -import ntpath +from help import VERBOSITY_HELP +from help import __full_info__ +from help import __version_info__ +from licenses import COMMON_LICENSES +from licenses import SPDX_LICENSE_IDS +from util import ImprovedFormatter +from util import canonical_path +from util import is_about_file +from util import on_windows +from util import path_exists +from util import posix_path +from util import remove_unc -__version__ = '2.0.0' - -# See http://dejacode.org -__about_spec_version__ = '1.0' - - -__copyright__ = """ -Copyright (c) 2013-2014 nexB Inc. 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 - - 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. -""" logger = logging.getLogger(__name__) handler = logging.StreamHandler() @@ -135,6 +128,7 @@ def repr_problem(obj): 'notes_file', ) + OWNERSHIP_FIELDS = ( 'contact', 'owner', @@ -216,320 +210,7 @@ def repr_problem(obj): ) -HEADER_ROW_FIELDS = (('about_file',) - + MANDATORY_FIELDS - + OPTIONAL_FIELDS) - - -# SPDX License Identifiers from http://spdx.org/licenses/ -# based on SPDX License List version 1.18 released on 2013-04-10 -SPDX_LICENSES = ( - 'AFL-1.1', - 'AFL-1.2', - 'AFL-2.0', - 'AFL-2.1', - 'AFL-3.0', - 'APL-1.0', - 'Aladdin', - 'ANTLR-PD', - 'Apache-1.0', - 'Apache-1.1', - 'Apache-2.0', - 'APSL-1.0', - 'APSL-1.1', - 'APSL-1.2', - 'APSL-2.0', - 'Artistic-1.0', - 'Artistic-2.0', - 'AAL', - 'BitTorrent-1.0', - 'BitTorrent-1.1', - 'BSL-1.0', - 'BSD-2-Clause', - 'BSD-2-Clause-FreeBSD', - 'BSD-2-Clause-NetBSD', - 'BSD-3-Clause', - 'BSD-3-Clause-Clear', - 'BSD-4-Clause', - 'BSD-4-Clause-UC', - 'CECILL-1.0', - 'CECILL-1.1', - 'CECILL-2.0', - 'CECILL-B', - 'CECILL-C', - 'ClArtistic', - 'CNRI-Python', - 'CNRI-Python-GPL-Compatible', - 'CPOL-1.02', - 'CDDL-1.0', - 'CDDL-1.1', - 'CPAL-1.0', - 'CPL-1.0', - 'CATOSL-1.1', - 'Condor-1.1', - 'CC-BY-1.0', - 'CC-BY-2.0', - 'CC-BY-2.5', - 'CC-BY-3.0', - 'CC-BY-ND-1.0', - 'CC-BY-ND-2.0', - 'CC-BY-ND-2.5', - 'CC-BY-ND-3.0', - 'CC-BY-NC-1.0', - 'CC-BY-NC-2.0', - 'CC-BY-NC-2.5', - 'CC-BY-NC-3.0', - 'CC-BY-NC-ND-1.0', - 'CC-BY-NC-ND-2.0', - 'CC-BY-NC-ND-2.5', - 'CC-BY-NC-ND-3.0', - 'CC-BY-NC-SA-1.0', - 'CC-BY-NC-SA-2.0', - 'CC-BY-NC-SA-2.5', - 'CC-BY-NC-SA-3.0', - 'CC-BY-SA-1.0', - 'CC-BY-SA-2.0', - 'CC-BY-SA-2.5', - 'CC-BY-SA-3.0', - 'CC0-1.0', - 'CUA-OPL-1.0', - 'D-FSL-1.0', - 'WTFPL', - 'EPL-1.0', - 'eCos-2.0', - 'ECL-1.0', - 'ECL-2.0', - 'EFL-1.0', - 'EFL-2.0', - 'Entessa', - 'ErlPL-1.1', - 'EUDatagrid', - 'EUPL-1.0', - 'EUPL-1.1', - 'Fair', - 'Frameworx-1.0', - 'FTL', - 'AGPL-1.0', - 'AGPL-3.0', - 'GFDL-1.1', - 'GFDL-1.2', - 'GFDL-1.3', - 'GPL-1.0', - 'GPL-1.0+', - 'GPL-2.0', - 'GPL-2.0+', - 'GPL-2.0-with-autoconf-exception', - 'GPL-2.0-with-bison-exception', - 'GPL-2.0-with-classpath-exception', - 'GPL-2.0-with-font-exception', - 'GPL-2.0-with-GCC-exception', - 'GPL-3.0', - 'GPL-3.0+', - 'GPL-3.0-with-autoconf-exception', - 'GPL-3.0-with-GCC-exception', - 'LGPL-2.1', - 'LGPL-2.1+', - 'LGPL-3.0', - 'LGPL-3.0+', - 'LGPL-2.0', - 'LGPL-2.0+', - 'gSOAP-1.3b', - 'HPND', - 'IPL-1.0', - 'Imlib2', - 'IJG', - 'Intel', - 'IPA', - 'ISC', - 'JSON', - 'LPPL-1.3a', - 'LPPL-1.0', - 'LPPL-1.1', - 'LPPL-1.2', - 'LPPL-1.3c', - 'Libpng', - 'LPL-1.02', - 'LPL-1.0', - 'MS-PL', - 'MS-RL', - 'MirOS', - 'MIT', - 'Motosoto', - 'MPL-1.0', - 'MPL-1.1', - 'MPL-2.0', - 'MPL-2.0-no-copyleft-exception', - 'Multics', - 'NASA-1.3', - 'Naumen', - 'NBPL-1.0', - 'NGPL', - 'NOSL', - 'NPL-1.0', - 'NPL-1.1', - 'Nokia', - 'NPOSL-3.0', - 'NTP', - 'OCLC-2.0', - 'ODbL-1.0', - 'PDDL-1.0', - 'OGTSL', - 'OLDAP-2.2.2', - 'OLDAP-1.1', - 'OLDAP-1.2', - 'OLDAP-1.3', - 'OLDAP-1.4', - 'OLDAP-2.0', - 'OLDAP-2.0.1', - 'OLDAP-2.1', - 'OLDAP-2.2', - 'OLDAP-2.2.1', - 'OLDAP-2.3', - 'OLDAP-2.4', - 'OLDAP-2.5', - 'OLDAP-2.6', - 'OLDAP-2.7', - 'OPL-1.0', - 'OSL-1.0', - 'OSL-2.0', - 'OSL-2.1', - 'OSL-3.0', - 'OLDAP-2.8', - 'OpenSSL', - 'PHP-3.0', - 'PHP-3.01', - 'PostgreSQL', - 'Python-2.0', - 'QPL-1.0', - 'RPSL-1.0', - 'RPL-1.1', - 'RPL-1.5', - 'RHeCos-1.1', - 'RSCPL', - 'Ruby', - 'SAX-PD', - 'SGI-B-1.0', - 'SGI-B-1.1', - 'SGI-B-2.0', - 'OFL-1.0', - 'OFL-1.1', - 'SimPL-2.0', - 'Sleepycat', - 'SMLNJ', - 'SugarCRM-1.1.3', - 'SISSL', - 'SPL-1.0', - 'Watcom-1.0', - 'NCSA', - 'VSL-1.0', - 'W3C', - 'WXwindows', - 'Xnet', - 'X11', - 'XFree86-1.1', - 'YPL-1.0', - 'YPL-1.1', - 'Zimbra-1.3', - 'Zlib', - 'ZPL-1.1', - 'ZPL-2.0', - 'ZPL-2.1', -) - - -# Maps lowercase id to standard ids with official case -SPDX_LICENSE_IDS = dict((name.lower(), name) for name in SPDX_LICENSES) - - -# Use DJE License Name -COMMON_LICENSES = ( - 'AES-128 v3.0 License', - 'Apache License 1.1', - 'Apache License 2.0', - 'Apple Attribution License 1997', - 'Apple Example Code License', - 'Apple Public Source License 2.0', - 'Arphic Public License', - 'Artistic License (Perl) 1.0', - 'Artistic License 2.0', - 'Bitstream Vera Font License', - 'Boost Software License 1.0', - 'Broadcom CFE License', - 'BSD-Modified', - 'BSD-Original', - 'BSD-Original-UC', - 'BSD-Simplified', - 'CMU Computing Services License', - 'Common Development and Distribution License 1.0', - 'Common Development and Distribution License 1.1', - 'Common Public License 1.0', - 'Creative Commons Attribution License 2.5', - 'Creative Commons Attribution Share Alike License 3.0', - 'Curl License', - 'FreeType Project License', - 'GNU General Public License 2.0', - 'GNU General Public License 2.0 with Bison exception', - 'GNU General Public License 2.0 with GLIBC exception', - 'GNU General Public License 3.0', - 'GNU Lesser General Public License 2.1', - 'GNU Library General Public License 2.0', - 'GPL 2.0 or later with Linking exception', - 'GPL 2.0 with Broadcom Linking exception', - 'Independent JPEG Group License', - 'ISC License (ISCL)', - 'Larabie Fonts EULA', - 'Libpng License', - 'Microsoft Limited Public License', - 'Microsoft Public License', - 'Microsoft Reciprocal License', - 'Microsoft TrueType Fonts EULA', - 'MIT License', - 'Mozilla Public License 1.1', - 'Net SNMP License', - 'Netscape Public License 1.1', - 'NTP License', - 'OpenSSL/SSLeay License', - 'Original SSLeay License with Windows exception', - 'RSA Data Security MD4', - 'RSA Data Security MD5', - 'SFL License Agreement', - 'SGI Free Software License B v2.0', - 'Sun RPC License', - 'TCL/TK License', - 'Tidy License', - 'University of Illinois/NCSA Open Source License', - 'X11 License', - 'ZLIB License', -) - -def posix_path(path): - """ - Return a path using the posixpath separator given a path that may - contain posix or windows separators, converting \ to /. - """ - return path.replace(ntpath.sep, posixpath.sep) - - -def is_about_file(path): - """ - Return True if the path represents a valid ABOUT file name. - """ - return path.lower().endswith('.about') - - -def resource_name(resource_path): - """ - Return a resource name based on a posix path (either the filename or - directory name). Recurse to handle paths that ends with a path separator - """ - left, right = posixpath.split(resource_path) - if right: - return right.strip() - elif left and left != '/': - # recurse for directories that end up with a / - return resource_name(left) - else: - return '' +HEADER_ROW_FIELDS = ('about_file',) + MANDATORY_FIELDS + OPTIONAL_FIELDS def check_network_connection(): @@ -554,7 +235,14 @@ class AboutFile(object): """ def __init__(self, location=None): self.about_resource = None - self.location = location + # The os.path.abspath(None) will cause error in linux system. + # See https://bugs.python.org/issue22587 + # Note that the os.path.abspath is needed for windows when there + # is long path/filename. + if on_windows: + self.location = os.path.abspath(location) + else: + self.location = location self.parsed = None self.parsed_fields = None @@ -740,9 +428,14 @@ def validate_field_values_are_not_empty(self): continue if field_name in MANDATORY_FIELDS: - err = Error(VALUE, field_name, None, - 'This mandatory field has no value.') - self.errors.append(err) + if field_name == 'version': + err = Warn(VALUE, field_name, None, + 'This mandatory field has no value.') + self.warnings.append(err) + else: + err = Error(VALUE, field_name, None, + 'This mandatory field has no value.') + self.errors.append(err) elif field_name in OPTIONAL_FIELDS: err = Warn(VALUE, field_name, None, 'This optional field has no value.') @@ -829,8 +522,12 @@ def validate_mandatory_fields_are_present(self): """ for field_name in MANDATORY_FIELDS: if field_name not in self.validated_fields: - self.errors.append(Error(VALUE, field_name, None, + if field_name == 'version' : + self.warnings.append(Error(VALUE, field_name, None, 'Mandatory field missing')) + else: + self.errors.append(Error(VALUE, field_name, None, + 'Mandatory field missing')) def validate_known_optional_fields(self, field_name): """ @@ -979,8 +676,7 @@ def get_row_data(self, updated_path, custom_keys): for field in MANDATORY_FIELDS + OPTIONAL_FIELDS: if field in self.validated_fields: row += [self.validated_fields[field]] - # The following code is to catch is the input contians any - # multiple licenses + # The following code is to catch if the input contains any multiple licenses if field in no_multi_license_fields: for lic_field in no_multi_license_fields: try: @@ -1082,7 +778,10 @@ def get_dje_license_name(self): """ Return the about object's dje_license_name. """ - return self.parsed.get('dje_license_name', '') + try: + return self.parsed.get('dje_license_name', '') + except: + return '' def check_invalid_chars(field_name, line): """ @@ -1105,6 +804,7 @@ def check_invalid_chars(field_name, line): return invalid_chars, warnings + class Collector(object): """ Collect ABOUT files. @@ -1142,19 +842,20 @@ def collect(location): ABOUT file or a directory tree containing ABOUT files. Locations are normalized using posix path separators. """ - # FIXME: we should not accept both a file and dir location as input paths = [] - if location: - if os.path.isfile(location) and is_about_file(location): - paths.append(location) - else: - for root, _, files in os.walk(location): - for name in files: - if is_about_file(name): - paths.append(os.path.join(root, name)) - # normalize the paths to use posix path separators - paths = [posix_path(p) for p in paths] - return paths + + location = canonical_path(location) + assert os.path.exists(location) + + if is_about_file(location): + paths.append(location) + else: + for root, _, files in os.walk(location): + for name in files: + if is_about_file(name): + paths.append(os.path.join(root, name)) + # always return posix paths + return [posix_path(p) for p in paths] @property def errors(self): @@ -1197,6 +898,10 @@ def get_relative_path(self, location): """ user_loc = normpath(self.location) if os.path.isdir(self.normalized_location): + # Making sure both are in posix path format before + # doing any string partition. + location = posix_path(location) + user_loc = posix_path(user_loc) parent_name = basename(user_loc) subpath = '/' + parent_name + location.partition(user_loc)[2] if user_loc[-1] == '/': @@ -1238,28 +943,23 @@ def write_to_csv(self, output_path): def get_about_context(self, about_object): about_content = about_object.validated_fields - if '\n' in about_object.get_dje_license_name(): - msg = ('Multiple licenses is not supported. ' - 'Skipping License generation.') - err = Error(GENATTRIB, 'dje_license', - about_object.location, msg) + has_multiple_licenses = '\n' in about_object.get_dje_license_name() + if has_multiple_licenses: + msg = 'Multiple licenses is not supported. Skipping License generation.' + about_object.location = remove_unc(about_object.location) + err = Error(GENATTRIB, 'dje_license', about_object.location, msg) self.genattrib_errors.append(err) - lic_text = unicode(about_object.license_text(), - errors='replace') - notice_text = unicode(about_object.notice_text(), - errors='replace') + lic_text = unicode(about_object.license_text(), errors='replace') + notice_text = unicode(about_object.notice_text(), errors='replace') about_content['license_text'] = lic_text about_content['notice_text'] = notice_text # report error if no license_text is found - if not about_content.get('license_text')\ - and not about_content.get('notice_text')\ - and not '\n' in about_object.get_dje_license_name(): - msg = ('No license_text found. ' - 'Skipping License generation.') - err = Error(GENATTRIB, 'license_text_file', - about_object.location, msg) + if not lic_text and not notice_text and not has_multiple_licenses: + msg = 'No license_text found. Skipping License generation.' + about_object.location = remove_unc(about_object.location) + err = Error(GENATTRIB, 'license_text_file', about_object.location, msg) self.genattrib_errors.append(err) return about_content @@ -1278,8 +978,7 @@ def generate_attribution(self, template_path=None, limit_to=None, verification=N return if not template_path: - template_path = join(dirname(realpath(__file__)), - "templates/default.html") + template_path = join(dirname(realpath(__file__)), 'templates/default.html') # FIXME: the template dir should be outside the code tree template_dir = dirname(template_path) @@ -1302,11 +1001,10 @@ def generate_attribution(self, template_path=None, limit_to=None, verification=N for component in not_process_components: for about_object in self: # The about_object.location is the absolute path of the ABOUT - # file. The purpose of the following string partition is to + # file. The purpose of the following string partition is to # match the about_file's location with the input list. - about_relative_path = about_object.location.partition( - normpath(self.location))[2] - if component == about_relative_path: + about_relative_path = about_object.location.partition(normpath(self.location))[2] + if component == posix_path(about_relative_path): component_exist = True about_content = self.get_about_context(about_object) license_dict[about_object.get_dje_license_name()] = about_content['license_text'] @@ -1314,9 +1012,9 @@ def generate_attribution(self, template_path=None, limit_to=None, verification=N break if not component_exist: + self.location = remove_unc(self.location) loc = self.location + component - msg = ('The requested ABOUT file: %r does not exist. ' - 'No attribution generated for this file.' % loc) + msg = 'The requested ABOUT file: %r does not exist. No attribution generated for this file.' % loc err = Error(GENATTRIB, 'about_file', loc, msg) self.genattrib_errors.append(err) else: @@ -1364,8 +1062,8 @@ def check_paths(self, paths): for path in paths: path = posix_path(path) afp = join(self.location, path) - msg = ('The requested ABOUT file: %(afp)r does not exist. ' - 'No attribution generated for this file.' % locals()) + afp = remove_unc(afp) + msg = ('The requested ABOUT file: %(afp)r does not exist. No attribution generated for this file.' % locals()) err = Error(GENATTRIB, 'about_file', path, msg) self.genattrib_errors.append(err) @@ -1375,30 +1073,24 @@ def get_genattrib_errors(self): USAGE_SYNTAX = ( """ - Input can be a file or directory. - Output must be a file with a .csv extension. -""" -) - - -VERBOSITY_HELP = ( -""" -Print more or fewer verbose messages while processing ABOUT files: -0 - Do not print any warning or error messages, just a total count (default) -1 - Print error messages -2 - Print error and warning messages + can be a file or directory containing .ABOUT files. + must be a file with a .csv extension to save the inventory collected from .ABOUT files. """ ) ERROR = 0 OK = 1 + def main(parser, options, args): + """ + Main commnand line entry point. + """ overwrite = options.overwrite verbosity = options.verbosity if options.version: - print('ABOUT tool {0}\n{1}'.format(__version__, __copyright__)) + print(__full_info__) return ERROR if verbosity == 1: @@ -1407,7 +1099,7 @@ def main(parser, options, args): handler.setLevel(logging.WARNING) if not len(args) == 2: - print('Input and Output paths are required.') + print('ERROR: and are required.') print() parser.print_help() return errno.EEXIST @@ -1415,35 +1107,35 @@ def main(parser, options, args): input_path, output_path = args output_path = os.path.abspath(output_path) - if not os.path.exists(input_path): - print('Input path does not exist.') + if not path_exists(input_path): + print('ERROR: does not exist.') print() parser.print_help() return errno.EEXIST if os.path.isdir(output_path): - print('Output must be a file, not a directory.') + print('ERROR: must be a file, not a directory.') print() parser.print_help() return errno.EISDIR if not output_path.endswith('.csv'): - print('Output file name must end with ".csv".') + print('ERROR: must be a CSV file ending with ".csv".') print() parser.print_help() return errno.EINVAL - if os.path.exists(output_path) and not overwrite: - print('Output file already exists. Select a different file name ' - 'or use the --overwrite option.') + if path_exists(output_path) and not overwrite: + print('ERROR: file already exists. Select a different file name or use the --overwrite option.') print() parser.print_help() return errno.EEXIST - if (not os.path.exists(output_path) - or (os.path.exists(output_path) and overwrite)): + if (not path_exists(output_path) + or (path_exists(output_path) and overwrite)): collector = Collector(input_path) collector.write_to_csv(output_path) + print('Completed.') if collector.errors: print('%d errors detected.' % len(collector.errors)) if collector.warnings: @@ -1451,62 +1143,28 @@ def main(parser, options, args): return OK else: # we should never reach this - assert False, 'Unsupported option(s).' + assert False, 'ERROR: Unsupported option(s).' def get_parser(): - class MyFormatter(optparse.IndentedHelpFormatter): - def _format_text(self, text): - """ - Overridden to allow description to be printed without - modification. - """ - return text - - def format_option(self, option): - """ - Overridden to allow options help text to be printed without - modification. - """ - result = [] - opts = self.option_strings[option] - opt_width = self.help_position - self.current_indent - 2 - if len(opts) > opt_width: - opts = '%*s%s\n' % (self.current_indent, '', opts) - indent_first = self.help_position - else: # start help on same line as opts - opts = '%*s%-*s ' % (self.current_indent, '', - opt_width, opts) - indent_first = 0 - result.append(opts) - if option.help: - help_text = self.expand_default(option) - help_lines = help_text.split('\n') - # help_lines = textwrap.wrap(help_text, self.help_width) - result.append('%*s%s\n' % (indent_first, '', help_lines[0])) - result.extend(['%*s%s\n' % (self.help_position, '', line) - for line in help_lines[1:]]) - elif opts[-1] != '\n': - result.append('\n') - return ''.join(result) - + """ + Return a command line options parser. + """ parser = optparse.OptionParser( usage='%prog [options] input_path output_path', description=USAGE_SYNTAX, add_help_option=False, - formatter=MyFormatter(), + formatter=ImprovedFormatter(), ) - parser.add_option('-h', '--help', action='help', help='Display help') - parser.add_option( - '--version', action='store_true', - help='Display current version, license notice, and copyright notice') - parser.add_option('--overwrite', action='store_true', - help='Overwrite the output file if it exists') + parser.add_option('-h', '--help', action='help', help='Print this help message and exit.') + parser.add_option('--version', action='store_true', help='Print the current version and copyright notice and exit.') + parser.add_option('--overwrite', action='store_true', help='Overwrite the file at if it exists.') parser.add_option('--verbosity', type=int, help=VERBOSITY_HELP) return parser if __name__ == '__main__': + print(__version_info__) parser = get_parser() options, args = parser.parse_args() sys.exit(main(parser, options, args)) diff --git a/about_code_tool/genabout.py b/about_code_tool/genabout.py index 404f8c10..7e30edd8 100644 --- a/about_code_tool/genabout.py +++ b/about_code_tool/genabout.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2016 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,13 +15,38 @@ # ============================================================================ """ -This is a tool to generate ABOUT files based on the input file. -The input file should be a csv format which contains information about the -file location, origin and license of the software components etc. +Generate ABOUT files based on CSV file. The input file contains data such as the +ABOUT file location, the origin and license of the software components etc. """ from __future__ import print_function +from about import AboutFile +from about import ERROR_WARN_FIELDS +from about import MANDATORY_FIELDS +from about import OPTIONAL_FIELDS +from about import check_network_connection +from collections import namedtuple +from help import MAPPING_HELP +from help import VERBOSITY_HELP +from help import __full_info__ +from help import __version_info__ +from os import makedirs +from os.path import abspath +from os.path import basename +from os.path import dirname +from os.path import exists +from os.path import expanduser +from os.path import isdir +from os.path import join +from os.path import normpath +from urlparse import urljoin, urlparse +from util import ImprovedFormatter +from util import add_unc +from util import apply_mappings +from util import get_mappings +from util import path_exists + import copy import csv import errno @@ -34,31 +59,6 @@ import urllib import urllib2 -from collections import namedtuple -from urlparse import urljoin, urlparse -from os import makedirs -from os.path import exists, dirname, join, abspath, isdir, normpath, basename, expanduser - -import about - -__version__ = '2.0.0' - -__copyright__ = """ -Copyright (c) 2013-2014 nexB Inc. 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 - - 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. -""" - LOG_FILENAME = 'error.log' @@ -69,9 +69,10 @@ logger.addHandler(handler) file_logger = logging.getLogger(__name__ + '_file') + ESSENTIAL_FIELDS = ('about_file',) -SUPPORTED_FIELDS = about.OPTIONAL_FIELDS + about.MANDATORY_FIELDS + ('about_file',) +SUPPORTED_FIELDS = OPTIONAL_FIELDS + MANDATORY_FIELDS + ESSENTIAL_FIELDS def repr_problem(obj): @@ -106,6 +107,7 @@ def repr_problem(obj): GENATTRIB = 'Attribution generation problem' NETWORK = 'Network problem' + # Handle different behaviors if ABOUT file already exists ACTION_DO_NOTHING_IF_ABOUT_FILE_EXIST = 0 ACTION_OVERWRITES_THE_CURRENT_ABOUT_FIELD_VALUE_IF_EXIST = 1 @@ -113,153 +115,123 @@ def repr_problem(obj): ACTION_REPLACE_THE_ABOUT_FILE_WITH_THE_CURRENT_GENERATED_FILE = 3 +def load_data_from_csv(location): + """ + Load data from CSV at location and return a list of About data dictionaries. + Keys are converted to lowercase. + """ + abouts = [] + with open(location, 'rU') as inp: + csvfile = csv.DictReader(inp) + for row in csvfile: + row_dict = {} + for key, value in row.items(): + row_dict[key.lower()] = value.strip() + abouts.append(row_dict) + return abouts + + +def get_unknown_fields(abouts, user_keys): + """ + Return a list of the non-supported fields given a list of About data + dictionaries and a list of user-defined keys in MAPPING.CONFIG. + """ + first = abouts[0] + return [field for field in first + if not field in SUPPORTED_FIELDS and not field in user_keys] + + +def has_duplicate_about_file_paths(abouts): + """ + Given a list of About data dictionaries, check if there are any + duplicated about_file paths. Return True if this is the case. + """ + seen = set() + for about in abouts: + about_file_path = about['about_file'] + if about_file_path in seen: + return True + seen.add(about_file_path) + + class GenAbout(object): def __init__(self): self.warnings = [] self.errors = [] - self.extract_dje_license_error = False + self.extract_license_api_error = False @staticmethod - # FIXME: why use a static and not a regular function? def get_duplicated_keys(input_file): + # FIXME: why use a static and not a regular function? csv_context = csv.reader(open(input_file, 'rU')) keys_row = csv_context.next() lower_case_keys_row = [k.lower() for k in keys_row] return ([key for key in keys_row if lower_case_keys_row.count(key.lower()) > 1]) - @staticmethod - def get_input_list(input_file): - # FIXME: why use a static and not a regular function? - csvfile = csv.DictReader(open(input_file, 'rU')) - input_list = [] - for row in csvfile: - row_dict = {} - for key in row: - row_dict[key.lower()] = row[key] - input_list.append(row_dict) - return input_list - - @staticmethod - def get_non_empty_rows_list(input_list): - # FIXME: why use a static and not a regular function? - copied_list = copy.deepcopy(input_list) - new_list = [] - for line in copied_list: - for key in line.keys(): - if line[key]: - new_list.append(line) - break - return new_list - - @staticmethod - def get_mapping_list(): - """ - Read the MAPPING.CONFIG - """ - # FIXME: why use a static and not a regular function? - self_path = abspath(dirname(__file__)) - mapping_list = {} - try: - with open(join(self_path, 'MAPPING.CONFIG'), 'rU') as file_in: - for line in file_in.readlines(): - if not line.startswith('#') and ':' in line: - about_spec_key = line.partition(':')[0] - user_spec_key = line.partition(':')[2].strip() - # Handle cases which keys contain spaces - if about_spec_key.endswith(' '): - about_spec_key = about_spec_key.strip() - about_spec_key = about_spec_key.replace(' ', '_') - mapping_list[about_spec_key.lower()] = user_spec_key.lower() - except Exception as e: - print(repr(e)) - print('The "MAPPING.CONFIG" file cannot be opened.') - sys.exit(errno.EACCES) - return mapping_list - - @staticmethod - def convert_input_list(input_list, mapping_list): - """ - Perform the key mapping - """ - # FIXME: why use a static and not a regular function? - copied_list = copy.deepcopy(input_list) - for copied_dict in copied_list: - for about_spec_key in mapping_list: - if mapping_list[about_spec_key] in copied_dict.keys(): - copied_dict[about_spec_key] = copied_dict.pop(mapping_list[about_spec_key]) - return copied_list - def validate(self, input_list): if not self.validate_mandatory_fields(input_list): - required_keys = about.MANDATORY_FIELDS + ('about_file',) - print("Required keys not found.") + required_keys = MANDATORY_FIELDS + ('about_file',) + print('ERROR: Required column/keys not found in the CSV.') print(required_keys) print("Use the '--mapping' option to map the input keys and verify the mapping information are correct.") - print("OR correct the header keys from the input CSV.") + print("OR correct the column names in the CSV.") sys.exit(errno.EINVAL) - if not self.validate_value_in_essential_fields(input_list): - print("Some of the essential fields value are missing.") + + elif not self.validate_value_in_essential_fields(input_list): + print("ERROR: Some of the essential column/fields value are missing in the CSV.") print(ESSENTIAL_FIELDS) - print("Please check the input CSV.") - print("No ABOUT file is created.") + print("Please check the the CSV.") + print("No ABOUT file was generated.") sys.exit(errno.EINVAL) - if self.validate_duplication(input_list): - print("The input has duplicated 'about_file'.") - print("Duplication is not supported. Please correct the input and rerun the tool.") - print("No ABOUT file is created.") + + elif has_duplicate_about_file_paths(input_list): + print("ERROR: The CSV has duplicated 'about_file' values.") + print("Duplication is not supported. Please correct the the CSV and rerun the tool.") + print("No ABOUT file was generated.") sys.exit(errno.EINVAL) @staticmethod - def validate_mandatory_fields(input_list): + def validate_mandatory_fields(abouts): + """ + Given a list of About data dictionaries, validate the presence of + mandatory fields. Return True if they are present. + """ # FIXME: why use a static and not a regular function? - for line in input_list: - for key in about.MANDATORY_FIELDS + ('about_file',): - if not key in line.keys(): + + for about in abouts: + for key in MANDATORY_FIELDS + ESSENTIAL_FIELDS: + if not key in about: return False return True @staticmethod - def validate_value_in_essential_fields(input_list): + def validate_value_in_essential_fields(abouts): + """ + Given a list of About data dictionaries, validate the presence of + essential fields. Return True if they are present. + """ # FIXME: why use a static and not a regular function? - for line in input_list: + for about in abouts: for key in ESSENTIAL_FIELDS: - if not line[key]: + if not about.get(key): return False return True - @staticmethod - def validate_duplication(input_list): - # FIXME: why use a static and not a regular function? - check_duplication = [] - for line in input_list: - component = line['about_file'] - if component in check_duplication: - return True - check_duplication.append(component) - return False - - def get_only_supported_fields(self, input_list, ignored_keys_list): + def get_only_supported_fields(self, input_list, ignored_keys): copied_list = copy.deepcopy(input_list) for copied_dict in copied_list: for key in copied_dict.keys(): - if key in ignored_keys_list: + if key in ignored_keys: copied_dict.pop(key, None) - msg = 'The field(s) "%s" is/are not supported and will be ignored.' % ignored_keys_list - self.warnings.append(Warn(IGNORED, ignored_keys_list, '', msg)) + msg = 'Field(s) %r not supported and will be ignored.' % ignored_keys + self.warnings.append(Warn(IGNORED, ignored_keys, '', msg)) return copied_list - @staticmethod - def get_non_supported_fields(input_list, mapping_keys): - """ - Returns a list of the non-supported fields in a given line. - """ - # FIXME: why use a static and not a regular function? - first_line = input_list[0] - return [field for field in first_line.keys() if not field in SUPPORTED_FIELDS and not field in mapping_keys] def verify_files_existence(self, input_list, project_dir, file_in_project): """ - Verify the existence of the 'license text file' + Verify the existence of a file pointed to by ' _file' suffixed fields + such as 'license_text_file'. """ files_list = [] # Get all the dictionary keys @@ -274,92 +246,84 @@ def verify_files_existence(self, input_list, project_dir, file_in_project): # FIXME: this loop is too complex for line in input_list: for file_key in file_keys: - if line[file_key]: - file_path_list = [] - file_value = [] - file_location = line['about_file'] - if file_location.startswith('/'): - file_location = file_location.partition('/')[2] - about_parent_dir = dirname(file_location) - if file_in_project: - if '\n' in line[file_key]: - file_value = line[file_key].split('\n') - else: - file_value.append(line[file_key]) - for value in file_value: - if file_location.endswith('/'): - about_parent_dir = normpath(dirname(join(file_location, value))) - file_path_list.append(join(project_dir, dirname(file_location), value)) + if not line[file_key]: + continue + + file_path_list = [] + file_value = [] + file_location = line['about_file'] + if file_location.startswith('/'): + file_location = file_location.partition('/')[2] + about_parent_dir = dirname(file_location) + if file_in_project: + if '\n' in line[file_key]: + file_value = line[file_key].split('\n') else: - if '\n' in line[file_key]: - file_value = line[file_key].split('\n') - else: - file_value.append(line[file_key]) - for value in file_value: - file_path_list.append(join(project_dir, value)) + file_value.append(line[file_key]) + for value in file_value: + if file_location.endswith('/'): + about_parent_dir = normpath(dirname(join(file_location, value))) + file_path_list.append(join(project_dir, dirname(file_location), value)) + else: + if '\n' in line[file_key]: + file_value = line[file_key].split('\n') + else: + file_value.append(line[file_key]) + for value in file_value: + file_path_list.append(join(project_dir, value)) - for path in file_path_list: - if _exists(path): - files_list.append((path, about_parent_dir)) - else: - self.warnings.append(Warn(FILE, file_key, path, "File does not exist.")) + for path in file_path_list: + if path_exists(path): + files_list.append((path, about_parent_dir)) + else: + self.warnings.append(Warn(FILE, file_key, path, 'File does not exist.')) return files_list - def request_license_data(self, url, username, api_key, license_key): + def request_license_data(self, url, api_key, license_key): """ + Return a dictionary of license data. Send a request to a given API URL to gather license data for - license_key, authenticating through an api_key and username. Return a - python dictionary of results returned by the API. + license_key, authenticating through an api_key. """ payload = { - 'username': username, 'api_key': api_key, + 'key': license_key, 'format': 'json' } url = url.rstrip('/') encoded_payload = urllib.urlencode(payload) - full_url = '%(url)s/%(license_key)s/?%(encoded_payload)s' % locals() + full_url = '%(url)s/?%(encoded_payload)s' % locals() # handle special characters in URL such as space etc. full_url = urllib.quote(full_url, safe="%/:=&?~#+!$,;'@()*[]") + headers = {'Authorization': 'Token %s' % api_key} license_data = {} try: - request = urllib2.Request(full_url) - response = urllib2.urlopen(request) - response_content = response.read() - license_data = json.loads(response_content) - except urllib2.HTTPError as http_e: + # The 'self.extract_license_api_error' is True if any of the + # api_url/api_key/network status have problem. + if not self.extract_license_api_error: + request = urllib2.Request(full_url, headers=headers) + response = urllib2.urlopen(request) + response_content = response.read() + license_data = json.loads(response_content) + except urllib2.HTTPError, http_e: # some auth problem if http_e.code == 401: - error_msg = ("Authorization denied. Invalid '--api_username' or '--api_key'." - " License data collection skipped.") - print() - print(error_msg) - print() - self.extract_dje_license_error = True - self.errors.append(Error(VALUE, 'username/api_key', - username + '/' + api_key, error_msg)) - else: - # FIXME: would this be only with a 404? - self.errors.append(Error(VALUE, 'dje_license_key', license_key, - "Invalid 'dje_license_key'")) - except urllib2.URLError: - if about.check_network_connection(): - error_msg = ("URL not reachable. Invalid '--api_url'." - " LICENSE generation is skipped.") - print("\n" + error_msg + "\n") - self.extract_dje_license_error = True - self.errors.append(Error(VALUE, '--api_url', url, error_msg)) + error_msg = ("Authorization denied. Invalid '--api_key'. License generation is skipped.") + print('\n%(error_msg)s\n' % locals()) + self.extract_license_api_error = True + self.errors.append(Error(VALUE, 'api_key', api_key, error_msg)) else: - error_msg = "Network problem. Please check the Internet connection. LICENSE generation is skipped." - print("\n" + error_msg + "\n") - self.extract_dje_license_error = True - self.errors.append(Error(NETWORK, 'Network', '', error_msg)) - except ValueError: + # Since no api_url/api_key/network status have + # problem detected, it yields 'dje_license_key' is the cause of + # this exception. + self.errors.append(Error(VALUE, 'dje_license_key', license_key, "Invalid 'dje_license_key'")) + except ValueError as e: # FIXME: when does this happen? pass finally: - return license_data + license_data = license_data.get('results')[0] if license_data.get('count') == 1 else {} + return license_data @staticmethod def copy_files(gen_location, files_list): @@ -369,14 +333,14 @@ def copy_files(gen_location, files_list): # FIXME : why use a static and not a regular function? for file_path, component_path in files_list: output_file_path = join(gen_location, component_path) - if not _exists(output_file_path): + if not path_exists(output_file_path): makedirs(output_file_path) shutil.copy2(file_path, output_file_path) def write_licenses(self, license_context_list): for gen_license_path, license_context in license_context_list: try: - if not _exists(dirname(gen_license_path)): + if not path_exists(dirname(gen_license_path)): makedirs(dirname(gen_license_path)) with open(gen_license_path, 'wb') as output: output.write(license_context) @@ -385,17 +349,16 @@ def write_licenses(self, license_context_list): 'Something is wrong.') self.errors.append(err) - def get_license_details_from_api(self, url, username, api_key, license_key): + def get_license_details_from_api(self, url, api_key, license_key): """ Returns the license_text of a given license_key using an API request. Returns an empty string if the text is not available. """ - license_data = self.request_license_data(url, username, - api_key, license_key) + license_data = self.request_license_data(url, api_key, license_key) license_name = license_data.get('name', '') license_text = license_data.get('full_text', '') license_key = license_data.get('key', '') - return [license_name, license_key, license_text] + return license_name, license_key, license_text def get_dje_license_list(self, gen_location, input_list, gen_license, dje_license_dict): # FIXME : this is too complex @@ -410,10 +373,10 @@ def get_dje_license_list(self, gen_location, input_list, gen_license, dje_licens about_parent_dir = dirname(file_location) license_text_file = line['license_text_file'] license_file = normpath(gen_location.rpartition('/')[0] + join(about_parent_dir, license_text_file)) - if not _exists(license_file): + if not path_exists(license_file): self.errors.append(Error(FILE, 'license_text_file', license_file, "The 'license_text_file' does not exist.")) else: - if gen_license: + if gen_license and not self.extract_license_api_error: if line['dje_license_key']: license_output_list.append(self.gen_license_list(line)) lic_name = line['dje_license_name'] @@ -436,42 +399,69 @@ def get_dje_license_list(self, gen_location, input_list, gen_license, dje_licens "Missing 'dje_license_key' for " + line['about_file'])) return license_output_list - def pre_process_and_dje_license_dict(self, input_list, api_url, api_username, api_key): + def pre_process_and_dje_license_dict(self, input_list, api_url, api_key): + """ + Modify a list of About data dictionaries by adding license information + fetched from the DejaCode API. + """ dje_uri = urlparse(api_url) domain = '{uri.scheme}://{uri.netloc}/'.format(uri=dje_uri) - dje_lic_urn = urljoin(domain, "urn/?urn=urn:dje:license:") + dje_lic_urn = urljoin(domain, 'urn/?urn=urn:dje:license:') key_text_dict = {} license_dict = {} + if check_network_connection(): + if not self.valid_api_url(api_url): + error_msg = "URL not reachable. Invalid '--api_url'. License generation is skipped." + print('\n%(error_msg)s\n' % locals()) + self.extract_license_api_error = True + self.errors.append(Error(VALUE, '--api_url', api_url, error_msg)) + else: + error_msg = "Network problem. Please check your Internet connection. License generation is skipped." + print('\n%(error_msg)s\n' % locals()) + self.extract_license_api_error = True + self.errors.append(Error(NETWORK, 'Network', '', error_msg)) for line in input_list: try: if line['dje_license_key']: if '\n' in line['dje_license_key']: line['dje_license_name'] = "" - self.errors.append(Error(VALUE, 'dje_license_key', - line['dje_license_key'], - "No multiple licenses or newline character are accepted.")) + self.errors.append(Error(VALUE, 'dje_license_key', line['dje_license_key'], "No multiple licenses or newline character are accepted.")) continue lic = line['dje_license_key'] - if not lic in license_dict: + if lic not in license_dict: detail_list = [] - detail = self.get_license_details_from_api(api_url, api_username, api_key, lic) - license_dict[lic] = detail[0] - line['dje_license_name'] = detail[0] - dje_key = detail[1] - license_context = detail [2] - line['dje_license_url'] = dje_lic_urn + lic - detail_list.append(dje_key) - detail_list.append(license_context) - key_text_dict[detail[0]] = detail_list + license_name, license_key, license_text = self.get_license_details_from_api(api_url, api_key, lic) + line['dje_license_key'] = license_key + license_dict[license_key] = license_name + line['dje_license_name'] = license_name + line['dje_license_url'] = dje_lic_urn + license_key + detail_list.append(license_key) + detail_list.append(license_text) + key_text_dict[license_name] = detail_list else: line['dje_license_name'] = license_dict[lic] line['dje_license_url'] = dje_lic_urn + lic - except Exception: - err = Warn(VALUE, 'dje_license_key', '', - 'Missing "dje_license_key" for ' + line['about_file']) + except Exception as e: + err = Warn(VALUE, 'dje_license_key', '', 'Missing "dje_license_key" for ' + line['about_file']) self.warnings.append(err) return key_text_dict + def valid_api_url(self, api_url): + try: + request = urllib2.Request(api_url) + # This will always goes to exception as no key are provided. + # The purpose of this code is to validate the provided api_url is correct + response = urllib2.urlopen(request) + except urllib2.HTTPError, http_e: + # The 403 error code is refer to "Authentication credentials were not provided.". + # This is correct as no key are provided. + if http_e.code == 403: + return True + except: + # All other exceptions yield to invalid api_url + pass + return False + def process_dje_licenses(self, dje_license_list, dje_license_dict, output_path): license_list_context = [] for gen_path, license_name in dje_license_list: @@ -481,7 +471,7 @@ def process_dje_licenses(self, dje_license_list, dje_license_dict, output_path): if lic: license_key = dje_license_dict[lic][0] gen_license_path = join(output_path, gen_path, license_key) + '.LICENSE' - if not _exists(gen_license_path) and not self.extract_dje_license_error: + if not path_exists(gen_license_path) and not self.extract_license_api_error: context = dje_license_dict[lic][1] if context: gen_path_context = [] @@ -492,7 +482,7 @@ def process_dje_licenses(self, dje_license_list, dje_license_dict, output_path): def pre_generation(self, gen_location, input_list, action_num): """ - Perfom some pre-generation. + Perform some pre-generation. TODO: document me """ output_list = [] @@ -511,12 +501,31 @@ def pre_generation(self, gen_location, input_list, action_num): file_location = dirname(file_location) file_location = join(file_location, basename(file_location)) file_location += '.ABOUT' + # The following code is to check if there is any directory ends with spaces + split_path = file_location.split('/') + dir_endswith_space = False + for segment in split_path: + if segment.endswith(' '): + msg = 'File path contains directory name ends with spaces which is not allowed. Generation skipped.' + self.errors.append(Error(VALUE, 'about_file_path', + file_location, msg)) + dir_endswith_space = True + break + if dir_endswith_space: + continue about_file_location = join(gen_location, file_location) about_file_dir = dirname(about_file_location) if not os.path.exists(about_file_dir): - makedirs(about_file_dir) - about_file_exist = _exists(about_file_location) + # Check for invalid file path + try: + makedirs(about_file_dir) + except: + msg = 'Invalid ABOUT file path.' + self.errors.append(Error(VALUE, 'about_file_path', + about_file_dir, msg)) + continue + about_file_exist = path_exists(about_file_location) if about_file_exist: if action_num == ACTION_DO_NOTHING_IF_ABOUT_FILE_EXIST: msg = 'ABOUT file already existed. Generation is skipped.' @@ -525,7 +534,7 @@ def pre_generation(self, gen_location, input_list, action_num): continue # Overwrites the current ABOUT field value if it existed elif action_num == ACTION_OVERWRITES_THE_CURRENT_ABOUT_FIELD_VALUE_IF_EXIST: - about_object = about.AboutFile(about_file_location) + about_object = AboutFile(about_file_location) for field_name, value in about_object.parsed.items(): field_name = field_name.lower() if not field_name in line.keys() or not line[field_name]: @@ -533,7 +542,7 @@ def pre_generation(self, gen_location, input_list, action_num): # Keep the current field value and only add the "new" field # and field value elif action_num == ACTION_KEEP_CURRENT_FIELDS_UNCHANGED_AND_ONLY_ADD_NEW_FIELDS: - about_object = about.AboutFile(about_file_location) + about_object = AboutFile(about_file_location) for field_name, value in about_object.parsed.items(): field_name = field_name.lower() line[field_name] = value @@ -598,12 +607,16 @@ def format_output(input_list): for item in sorted(about_dict_list.iterkeys()): if item == 'about_file': continue - if not item in about.MANDATORY_FIELDS: + if not item in MANDATORY_FIELDS: # The purpose of the replace('\n', '\n ') is used to # format the continuation strings value = about_dict_list[item].replace('\n', '\n ') - if (value or item in about.MANDATORY_FIELDS) and not item\ - in about.ERROR_WARN_FIELDS and not item == 'about_resource': + if (value or item in MANDATORY_FIELDS) and not item in ERROR_WARN_FIELDS and not item == 'about_resource': + # It will cause error if value has different coding + try: + value = unicode(value, errors='ignore') + except: + pass context += item + ': ' + value + '\n' component.append(about_file_location) @@ -614,7 +627,8 @@ def format_output(input_list): @staticmethod def write_output(output): for about_file_location, context in output: - if _exists(about_file_location): + about_file_location = add_unc(about_file_location) + if path_exists(about_file_location): os.remove(about_file_location) with open(about_file_location, 'wb') as output_file: output_file.write(context) @@ -631,59 +645,56 @@ def warnings_errors_summary(self): file_logger.warning(warning_msg) -def _exists(location): - # FIXME: duplicated code with about.py - return location and exists(abspath(location)) +def filter_dicts_of_empty_values(abouts): + """ + Return a list of About data dictionaries filtering dictionaries composed + entirely of empty values. + """ + filtered = [] + for about in abouts: + if any(v and v.strip() for v in about.values()): + filtered.append(dict(about)) + return filtered -USAGE_SYNTAX = """\ - Input must be a CSV file - Output must be a directory location where the ABOUT files should be generated -""" -VERBOSITY_HELP = """\ -Print more or fewer verbose messages while processing ABOUT files -0 - Do not print any warning or error messages, just a total count (default) -1 - Print error messages -2 - Print error and warning messages +USAGE_SYNTAX = """\ + must be a file with a .csv extension containing an inventory of ABOUT data. + must be a directory where ABOUT files should be generated. """ ACTION_HELP = """\ -Handle different behaviors if ABOUT files already existed -0 - Do nothing if ABOUT file existed (default) -1 - Overwrites the current ABOUT field value if existed -2 - Keep the current field value and only add the "new" field and field value -3 - Replace the ABOUT file with the current generation +Handle different behaviors if ABOUT files already exist: +0 - Do nothing if an ABOUT file exists (default). +1 - Merge and overwrite existing ABOUT files field values with new generated field/value. +2 - Merge and keep existing ABOUT files field value. Add new generated field/value. +3 - Overwrite existing ABOUT files with generated files. """ COPY_FILES_HELP = """\ -Copy the '*_file' from the project to the generated location -Project path - Project path +Copy the '*_file' from the COPY_FILES directory to the generated location. """ LICENSE_TEXT_LOCATION_HELP = """\ -Copy the 'license_text_file' from the directory to the generated location -License path - License text files path -""" - -MAPPING_HELP = """\ -Configure the mapping key from the MAPPING.CONFIG +Copy the 'license_text_file' from the LICENSE_TEXT_LOCATION directory to the generated location. """ EXTRACT_LICENSE_HELP = """\ -Extract License text and create .LICENSE side-by-side - with the .ABOUT from DJE License Library. -api_url - URL to the DJE License Library -api_username - The regular DJE username -api_key - Hash attached to your username which is used to authenticate - yourself in the API. Contact us to get the hash key. +Fetch and save license texts in .LICENSE files side-by-side with the +.ABOUT files using the DejaCode License Library API. +api_url - URL to the DejaCode License Library. +api_key - Key used to authenticate yourself in the API. + Contact us to get an API key. Example syntax: -genabout.py --extract_license --api_url='api_url' --api_username='api_username' --api_key='api_key' +genabout.py --extract_license --api_url='api_url' --api_key='api_key' """ def main(parser, options, args): + """ + Main commnand line entry point. + """ verbosity = options.verbosity action = options.action copy_files_path = options.copy_files @@ -693,14 +704,12 @@ def main(parser, options, args): action_num = 0 api_url = '' - api_username = '' api_key = '' gen_license = False dje_license_dict = {} - mapping_keys = [] if options.version: - print('ABOUT tool {0}\n{1}'.format(__version__, __copyright__)) + print(__full_info__) sys.exit(0) if verbosity == 1: @@ -713,35 +722,35 @@ def main(parser, options, args): if action in valid_actions: action_num = action else: - print('Invalid action: should be 0, 1, 2 or 3') + print('ERROR: Invalid action: must be one of: 0, 1, 2 or 3') sys.exit(errno.EINVAL) if copy_files_path: # code to handle tilde character copy_files_path = os.path.abspath(expanduser(copy_files_path)) - if not _exists(copy_files_path): - print("The project path does not exist.") + if not path_exists(copy_files_path): + print("ERROR: The COPY_FILES path does not exist.") sys.exit(errno.EINVAL) if license_text_path: # code to handle tilde character license_text_path = os.path.abspath(expanduser(license_text_path)) - if not _exists(license_text_path): - print("The license text path does not exist.") + if not path_exists(license_text_path): + print("ERROR: LICENSE_TEXT_LOCATION path does not exist.") sys.exit(errno.EINVAL) - if mapping_config and not _exists('MAPPING.CONFIG'): - print("The file 'MAPPING.CONFIG' does not exist.") + mapping_config_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'MAPPING.CONFIG') + if mapping_config and not path_exists(mapping_config_path): + print("ERROR: The file 'MAPPING.CONFIG' does not exist.") sys.exit(errno.EINVAL) if extract_license: api_url = extract_license[0].partition('--api_url=')[2] - api_username = extract_license[1].partition('--api_username=')[2] - api_key = extract_license[2].partition('--api_key=')[2] + api_key = extract_license[1].partition('--api_key=')[2] gen_license = True if not len(args) == 2: - print('Input and Output paths are required.') + print('ERROR: and are required.') print() parser.print_help() sys.exit(errno.EEXIST) @@ -753,25 +762,25 @@ def main(parser, options, args): output_path += '/' if not exists(input_path): - print('Input path does not exist.') + print('ERROR: file does not exist.') print() parser.print_help() sys.exit(errno.EEXIST) if not exists(output_path): - print('Output path does not exist.') + print('ERROR: directory does not exist.') print() parser.print_help() sys.exit(errno.EEXIST) if not isdir(output_path): - print('Output must be a directory, not a file.') + print('ERROR: must be a directory, not a file.') print() parser.print_help() sys.exit(errno.EISDIR) if not input_path.endswith('.csv'): - print("Input file name must be a CSV file ends with '.csv'") + print("ERROR: file must be a CSV file ends with '.csv'") print() parser.print_help() sys.exit(errno.EINVAL) @@ -780,8 +789,8 @@ def main(parser, options, args): dup_keys = gen.get_duplicated_keys(input_path) if dup_keys: - print('The input file contains duplicated keys. ' - 'Duplicated keys are not allowed.') + print('ERROR: The CSV file contains duplicated column keys. ' + 'Duplicated column keys are not allowed.') print(dup_keys) print() print('Please fix the input file and re-run the tool.') @@ -795,53 +804,53 @@ def main(parser, options, args): file_handler = logging.FileHandler(log_path) file_logger.addHandler(file_handler) - input_list = gen.get_input_list(input_path) - input_list = gen.get_non_empty_rows_list(input_list) + input_data = load_data_from_csv(input_path) + input_data = filter_dicts_of_empty_values(input_data) + user_keys = [] if mapping_config: - mapping_list = gen.get_mapping_list() - input_list = gen.convert_input_list(input_list, mapping_list) - mapping_keys = mapping_list.keys() + mappings = get_mappings(location=None) + input_data = apply_mappings(input_data, mappings) + user_keys = mappings.keys() - gen.validate(input_list) + gen.validate(input_data) - ignored_fields_list = gen.get_non_supported_fields(input_list, - mapping_keys) + ignored_fields_list = get_unknown_fields(input_data, user_keys) if ignored_fields_list: - input_list = gen.get_only_supported_fields(input_list, - ignored_fields_list) + input_list = gen.get_only_supported_fields(input_data, ignored_fields_list) + else: + input_list = input_data if copy_files_path: if not isdir(copy_files_path): - print("The '--copy_files' must be a directory.") - print("'--copy_files' is skipped.") + print("WARNING: The COPY_FILES path must be a directory.") + print("'--copy_files' option ignored.") else: licenses_in_project = True license_list = gen.verify_files_existence(input_list, copy_files_path, licenses_in_project) if not license_list: - print("None of the file is found. '--copy_files' is ignored.") + print("WARNING: No file found. '--copy_files' is ignored.") else: gen.copy_files(output_path, license_list) if license_text_path: if not isdir(license_text_path): - print("The '--license_text_location' " - "must be a directory.") - print("'--license_text_location' is skipped.") + print("WARNING: The LICENSE_TEXT_LOCATION path must be a directory.") + print("'--license_text_location' option ignored.") else: licenses_in_project = False license_list = gen.verify_files_existence(input_list, license_text_path, licenses_in_project) if not license_list: - print("None of the file is found. '--copy_files' is ignored.") + print("WARNING: No file found. '--copy_files' option ignored.") else: gen.copy_files(output_path, license_list) if extract_license: - if not api_url or not api_username or not api_key: + if not api_url or not api_key: print("Missing argument for --extract_license") sys.exit(errno.EINVAL) for line in input_list: @@ -850,98 +859,53 @@ def main(parser, options, args): break except Exception as e: print(repr(e)) - print("The input does not have the 'dje_license_key' " - "key which is required.") + print("ERROR: The CSV does not contain the required column 'dje_license_key' ") sys.exit(errno.EINVAL) if gen_license: - dje_license_dict = gen.pre_process_and_dje_license_dict(input_list, - api_url, - api_username, - api_key) - - dje_license_list = gen.get_dje_license_list(output_path, - input_list, - gen_license, - dje_license_dict) - components_list = gen.pre_generation(output_path, - input_list, - action_num) + # Strip the ' and " for api_url, and api_key from input + api_url = api_url.strip("'").strip("\"") + api_key = api_key.strip("'").strip("\"") + dje_license_dict = gen.pre_process_and_dje_license_dict(input_list, api_url, api_key) + + dje_license_list = gen.get_dje_license_list(output_path, input_list, gen_license, dje_license_dict) + components_list = gen.pre_generation(output_path, input_list, action_num) formatted_output = gen.format_output(components_list) gen.write_output(formatted_output) if dje_license_list: - license_list_context = gen.process_dje_licenses(dje_license_list, - dje_license_dict, - output_path) + license_list_context = gen.process_dje_licenses(dje_license_list, dje_license_dict, output_path) gen.write_licenses(license_list_context) + print('Completed.') gen.warnings_errors_summary() print('Warnings: %s' % len(gen.warnings)) print('Errors: %s' % len(gen.errors)) def get_parser(): - - class MyFormatter(optparse.IndentedHelpFormatter): - def _format_text(self, text): - """ - Overridden to allow description to be printed without - modification - """ - return text - - def format_option(self, option): - """ - Overridden to allow options help text to be printed without - modification - """ - result = [] - opts = self.option_strings[option] - opt_width = self.help_position - self.current_indent - 2 - if len(opts) > opt_width: - opts = '%*s%s\n' % (self.current_indent, '', opts) - indent_first = self.help_position - else: # start help on same line as opts - opts = '%*s%-*s ' % (self.current_indent, '', opt_width, opts) - indent_first = 0 - result.append(opts) - if option.help: - help_text = self.expand_default(option) - help_lines = help_text.split('\n') - # help_lines = textwrap.wrap(help_text, self.help_width) - result.append('%*s%s\n' % (indent_first, '', help_lines[0])) - result.extend(['%*s%s\n' % (self.help_position, '', line) - for line in help_lines[1:]]) - elif opts[-1] != '\n': - result.append('\n') - return ''.join(result) - + """ + Return a command line options parser. + """ parser = optparse.OptionParser( usage='%prog [options] input_path output_path', description=USAGE_SYNTAX, add_help_option=False, - formatter=MyFormatter(), + formatter=ImprovedFormatter(), ) - parser.add_option('-h', '--help', action='help', help='Display help') - parser.add_option('--version', action='store_true', - help='Display version, license and copyright notice') - parser.add_option('--verbosity', type=int, - help=VERBOSITY_HELP) - parser.add_option('--action', type=int, - help=ACTION_HELP) - parser.add_option('--copy_files', type='string', - help=COPY_FILES_HELP) - parser.add_option('--license_text_location', type='string', - help=LICENSE_TEXT_LOCATION_HELP) - parser.add_option('--mapping', action='store_true', - help=MAPPING_HELP) - parser.add_option('--extract_license', type='string', nargs=3, - help=EXTRACT_LICENSE_HELP) + parser.add_option('-h', '--help', action='help', help='Print this help message and exit.') + parser.add_option('--version', action='store_true', help='Print the current version and copyright notice and exit.') + parser.add_option('--verbosity', type=int, help=VERBOSITY_HELP) + parser.add_option('--action', type=int, help=ACTION_HELP) + parser.add_option('--copy_files', type='string', help=COPY_FILES_HELP) + parser.add_option('--license_text_location', type='string', help=LICENSE_TEXT_LOCATION_HELP) + parser.add_option('--mapping', action='store_true', help=MAPPING_HELP) + parser.add_option('--extract_license', type='string', nargs=2, help=EXTRACT_LICENSE_HELP) return parser if __name__ == '__main__': + print(__version_info__) parser = get_parser() options, args = parser.parse_args() main(parser, options, args) diff --git a/about_code_tool/genattrib.py b/about_code_tool/genattrib.py index 30544d19..f5da7ce9 100644 --- a/about_code_tool/genattrib.py +++ b/about_code_tool/genattrib.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2016 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,24 +15,39 @@ # ============================================================================ """ -This tool is used to generate component attribution based on a set of .ABOUT -files. Optionally, one could pass a subset list of specific components for set -of .ABOUT files to generate attribution. +Tool to generate component attribution based on a set of .ABOUTfiles. + +Optionally accepts a list (i.e. a subset) of ABOUT file paths to limit the +generated attribution to this subset. """ from __future__ import print_function +from about import Collector +from help import MAPPING_HELP +from help import VERBOSITY_HELP +from help import __full_info__ +from help import __version_info__ +from os.path import abspath +from os.path import basename +from os.path import dirname +from os.path import exists +from os.path import expanduser +from os.path import isdir +from os.path import join +from os.path import normpath +from util import ImprovedFormatter +from util import apply_mappings +from util import extract_zip + import csv import errno import logging import optparse import os +import posixpath import sys -from os.path import exists, dirname, join, abspath, isdir, basename, expanduser, normpath - -from about import Collector -import genabout LOG_FILENAME = 'error.log' @@ -43,95 +58,75 @@ logger.addHandler(handler) file_logger = logging.getLogger(__name__ + '_file') -__version__ = '2.0.0' - -__about_spec_version__ = '1.0.0' # See http://dejacode.org - -__copyright__ = """ -Copyright (c) 2013-2014 nexB Inc. 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 - - 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. -""" - - -def component_subset_to_sublist(input_list): - sublist = [row["about_file"] for row in input_list - if "about_file" in row.keys()] - return sublist - - -def update_path_to_about(input_list): - output_list = [] - for row in input_list: - if not row.endswith('.ABOUT'): - if row.endswith('/'): - row += basename(dirname(row)) - output_list.append(row + '.ABOUT') +def get_about_file_paths(abouts): + """ + Return a list of about_file paths given a list of About data dictionaries. + """ + return [row['about_file'] for row in abouts if 'about_file' in row] + + +def as_about_paths(paths): + """ + Given a list of paths, return a list of paths that point all to .ABOUT files. + """ + normalized_paths = [] + for path in paths: + if path.endswith('.ABOUT'): + normalized_paths.append(path) else: - output_list.append(row) - return output_list - - -def convert_dict_key_to_lower_case(input_list): - output_list = [] - for line in input_list: - lower_dict = {} - for key in line: - lower_dict[key.lower()] = line[key] - output_list.append(lower_dict) - return output_list - - -def check_about_file_existence_and_format(input_list): - try: - for row in input_list: - # Force the path to start with the '/' to map with the project - # structure - if not row['about_file'].startswith('/'): - row['about_file'] = '/' + row['about_file'] - return input_list - except Exception: - return [] + if path.endswith('/'): + path += basename(dirname(path)) + normalized_paths.append(path + '.ABOUT') + return normalized_paths + + +def lower_keys(dicts): + """ + Return a new a list of 'dicts' dictionaries such that all the keys are + lowercased. + """ + lowered_dicts = [] + for dct in dicts: + lowered = {} + for key, value in dct.items(): + lowered[key.lower()] = value + lowered_dicts.append(lowered) + return lowered_dicts + + +def has_about_file_keys(abouts): + """ + Return True if all dicts in a list of About dictionaries have an about_file key. + """ + return all(about.get('about_file') for about in abouts) + + +def normalize_about_file_paths(abouts): + """ + Update a list of About data dictionaries such that all 'about_file' paths are + absolute POSIX paths (i.e. prefixed with a POSIX / "slash"). + """ + for about in abouts: + about_file_path = about.get('about_file') + if about_file_path and not about_file_path.startswith(posixpath.sep): + about['about_file'] = '/' + about_file_path + return abouts USAGE_SYNTAX = """\ - Input can be a file or directory. - Output of rendered template must be a file (e.g. .html). - - Optional: - Component List must be a .csv file which has at least an "about_file" column. -""" - - -VERBOSITY_HELP = """\ -Print more or fewer verbose messages while processing ABOUT files -0 - Do not print any warning or error messages, just a total count (default) -1 - Print error messages -2 - Print error and warning messages + can be a file or directory containing ABOUT files. + is a file path to save the rendered attribution (e.g. .html). + is an optional .csv file with at least an "about_file" column to limit attribution generation to that list. """ TEMPLATE_LOCATION_HELP = """\ -Use the custom template for the Attribution Generation -""" - - -MAPPING_HELP = """\ -Configure the mapping key from the MAPPING.CONFIG +Optional path to a custom template to use for the generating the attribution. +Default to 'about_code_tool/templates/default.html' """ VERIFICATION_HELP = """\ -Create a verification CSV output for the attribution +Optional path to a verification CSV file created from the generated attribution. """ def main(parser, options, args): @@ -142,7 +137,7 @@ def main(parser, options, args): verification_location = options.verification_location if options.version: - print('ABOUT tool {0}\n{1}'.format(__version__, __copyright__)) + print(__full_info__) sys.exit(0) if verbosity == 1: @@ -150,31 +145,31 @@ def main(parser, options, args): elif verbosity >= 2: handler.setLevel(logging.WARNING) - if mapping_config: - if not exists('MAPPING.CONFIG'): - print("The file 'MAPPING.CONFIG' does not exist.") + mapping_config_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'MAPPING.CONFIG') + if mapping_config and not exists(mapping_config_path): + print("ERROR: The file 'MAPPING.CONFIG' does not exist.") sys.exit(errno.EINVAL) if template_location: template_location = abspath(expanduser(template_location)) if not exists(template_location): - print('The defined template location does not exist.') + print('ERROR: The TEMPLATE_LOCATION file does not exist.') parser.print_help() sys.exit(errno.EINVAL) if verification_location: verification_location = abspath(expanduser(verification_location)) if not verification_location.endswith('.csv'): - print('The verification output must ends with ".csv".') + print('ERROR: The VERIFICATION_LOCATION file path must end with ".csv".') parser.print_help() sys.exit(errno.EINVAL) if not exists(dirname(verification_location)): - print('The verification output directory does not exist.') + print('ERROR: The VERIFICATION_LOCATION file parent directory does not exist.') parser.print_help() sys.exit(errno.EINVAL) if not len(args) >= 2 or not len(args) < 4: - print('The number of arguments is incorrect.\n') + print('ERROR: The number of arguments is incorrect.') parser.print_help() sys.exit(errno.EEXIST) @@ -196,29 +191,34 @@ def main(parser, options, args): sys.setdefaultencoding('utf-8') # @UndefinedVariable if not exists(input_path): - print('Input path does not exist.') + print('ERROR: does not exist.') parser.print_help() sys.exit(errno.EEXIST) + if input_path.lower().endswith('.zip'): + # accept zipped ABOUT files as input + input_path = extract_zip(input_path) + if isdir(output_path): - print('Output must be a HTML file.') + print('ERROR: cannot be a directory') parser.print_help() sys.exit(errno.EISDIR) + """ # We only support HTML currently if not output_path.endswith('.html'): - print('Output must be a HTML file.') + print('ERROR: must be an HTML file.') parser.print_help() sys.exit(errno.EINVAL) + """ if exists(output_path) and not overwrite: - print('Output file already exists. Select a different file name ' - 'or use the --overwrite option.') + print('ERROR: A file at already exists. Select a different file name or use the --overwrite option.') parser.print_help() sys.exit(errno.EEXIST) if component_subset_path and not exists(component_subset_path): - print('Component Subset path does not exist.') + print('ERROR: the CSV file does not exist.') parser.print_help() sys.exit(errno.EEXIST) @@ -227,37 +227,41 @@ def main(parser, options, args): outlist = None if not component_subset_path: sublist = None + else: - input_list = [] - with open(component_subset_path, "rU") as f: - input_dict = csv.DictReader(f) - for row in input_dict: - input_list.append(row) - updated_list = convert_dict_key_to_lower_case(input_list) + with open(component_subset_path, 'rU') as inp: + reader = csv.DictReader(inp) + abouts = [data for data in reader] + + abouts = lower_keys(abouts) + if mapping_config: - mapping_list = genabout.GenAbout().get_mapping_list() - updated_list = genabout.GenAbout().convert_input_list(updated_list, mapping_list) - if not check_about_file_existence_and_format(updated_list): - print('The required key "about_file" was not found.') - print('Please use the "--mapping" option to map the input ' - 'keys and verify the mapping information are correct.') + abouts = apply_mappings(abouts) + + if not has_about_file_keys(abouts): + print('ERROR: The required column key "about_file" was not found in the CSV file.') + print('Please use the "--mapping" option to map the input keys and verify the mapping information are correct.') print('OR, correct the header keys from the component list.') parser.print_help() sys.exit(errno.EISDIR) - sublist = component_subset_to_sublist(updated_list) - outlist = update_path_to_about(sublist) + + abouts = normalize_about_file_paths(abouts) + + sublist = get_about_file_paths(abouts) + outlist = as_about_paths(sublist) attrib_str = collector.generate_attribution(template_path=template_location, limit_to=outlist, verification=verification_location) errors = collector.get_genattrib_errors() if attrib_str: try: - with open(output_path, "w") as f: + with open(output_path, 'w') as f: f.write(attrib_str) except Exception as e: - print("Problem occurs. Attribution was not generated.") + print('An error occurred. Attribution was not generated.') print(e) + print('Completed.') # Remove the previous log file if exist log_path = join(dirname(output_path), LOG_FILENAME) if exists(log_path): @@ -269,70 +273,35 @@ def main(parser, options, args): logger.error(error_msg) file_logger.error(error_msg) if errors: - print("%d errors detected." % len(errors)) + print('%d errors detected.' % len(errors)) else: # we should never reach this - assert False, "Unsupported option(s)." + assert False, 'Unsupported option(s).' def get_parser(): - class MyFormatter(optparse.IndentedHelpFormatter): - def _format_text(self, text): - """ - Overridden to allow description to be printed without - modification - """ - return text - - def format_option(self, option): - """ - Overridden to allow options help text to be printed without - modification - """ - result = [] - opts = self.option_strings[option] - opt_width = self.help_position - self.current_indent - 2 - if len(opts) > opt_width: - opts = "%*s%s\n" % (self.current_indent, "", opts) - indent_first = self.help_position - else: # start help on same line as opts - opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) - indent_first = 0 - result.append(opts) - if option.help: - help_text = self.expand_default(option) - help_lines = help_text.split('\n') - result.append("%*s%s\n" % (indent_first, "", help_lines[0])) - result.extend(["%*s%s\n" % (self.help_position, "", line) - for line in help_lines[1:]]) - elif opts[-1] != "\n": - result.append("\n") - return "".join(result) - + """ + Return a command line options parser. + """ parser = optparse.OptionParser( usage='%prog [options] input_path output_path [component_list]', description=USAGE_SYNTAX, add_help_option=False, - formatter=MyFormatter(), + formatter=ImprovedFormatter(), ) - parser.add_option("-h", "--help", action="help", help="Display help") - parser.add_option("-v", "--version", action="store_true", - help='Display current version, license notice, and copyright notice') - parser.add_option('--overwrite', action='store_true', - help='Overwrites the output file if it exists') - parser.add_option('--verbosity', type=int, - help=VERBOSITY_HELP) - parser.add_option('--template_location', type='string', - help=TEMPLATE_LOCATION_HELP) - parser.add_option('--mapping', action='store_true', - help=MAPPING_HELP) - parser.add_option('--verification_location', type='string', - help=VERIFICATION_HELP) + parser.add_option('-h', '--help', action='help', help='Print this help message and exit.') + parser.add_option('--version', action='store_true', help='Print the current version and copyright notice and exit') + parser.add_option('--overwrite', action='store_true', help='Overwrites the file if it exists.') + parser.add_option('--verbosity', type=int, help=VERBOSITY_HELP) + parser.add_option('--template_location', type='string', help=TEMPLATE_LOCATION_HELP) + parser.add_option('--mapping', action='store_true', help=MAPPING_HELP) + parser.add_option('--verification_location', type='string', help=VERIFICATION_HELP) return parser -if __name__ == "__main__": +if __name__ == '__main__': + print(__version_info__) parser = get_parser() options, args = parser.parse_args() main(parser, options, args) diff --git a/about_code_tool/help.py b/about_code_tool/help.py new file mode 100644 index 00000000..2d92a78a --- /dev/null +++ b/about_code_tool/help.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +# ============================================================================ +# Copyright (c) 2013-2016 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 +# 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. +# ============================================================================ + +from __future__ import print_function + + +__about_spec_version__ = '1.0' + +__version__ = '2.3.2' + +__copyright__ = """ +Copyright (c) 2013-2016 nexB Inc. 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 + + 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. +""" + +__version_info__ = 'AboutCode v{0}\n'.format(__version__) + + +__full_info__ = 'AboutCode tool v{0}\n{1}'.format(__version__, __copyright__) + + +VERBOSITY_HELP = """\ +Control warning and errors printed while processing: +0 - Do not print warning or error messages, only a total count (default). +1 - Print only error messages. +2 - Print error and warning messages. +""" + + +MAPPING_HELP = """\ +Load the about_code_tool/MAPPING.CONFIG file. This file contains a mapping between +known AboutCode key/column names and custom key/column name used in your CSVs files. +""" + diff --git a/about_code_tool/licenses.py b/about_code_tool/licenses.py new file mode 100644 index 00000000..1d6433f7 --- /dev/null +++ b/about_code_tool/licenses.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +# ============================================================================ +# Copyright (c) 2013-2016 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 +# 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. +# ============================================================================ + +from __future__ import print_function + + +# SPDX License Identifiers from http://spdx.org/licenses/ +# based on SPDX License List version 1.18 released on 2013-04-10 +SPDX_LICENSES = ( + 'AFL-1.1', + 'AFL-1.2', + 'AFL-2.0', + 'AFL-2.1', + 'AFL-3.0', + 'APL-1.0', + 'Aladdin', + 'ANTLR-PD', + 'Apache-1.0', + 'Apache-1.1', + 'Apache-2.0', + 'APSL-1.0', + 'APSL-1.1', + 'APSL-1.2', + 'APSL-2.0', + 'Artistic-1.0', + 'Artistic-2.0', + 'AAL', + 'BitTorrent-1.0', + 'BitTorrent-1.1', + 'BSL-1.0', + 'BSD-2-Clause', + 'BSD-2-Clause-FreeBSD', + 'BSD-2-Clause-NetBSD', + 'BSD-3-Clause', + 'BSD-3-Clause-Clear', + 'BSD-4-Clause', + 'BSD-4-Clause-UC', + 'CECILL-1.0', + 'CECILL-1.1', + 'CECILL-2.0', + 'CECILL-B', + 'CECILL-C', + 'ClArtistic', + 'CNRI-Python', + 'CNRI-Python-GPL-Compatible', + 'CPOL-1.02', + 'CDDL-1.0', + 'CDDL-1.1', + 'CPAL-1.0', + 'CPL-1.0', + 'CATOSL-1.1', + 'Condor-1.1', + 'CC-BY-1.0', + 'CC-BY-2.0', + 'CC-BY-2.5', + 'CC-BY-3.0', + 'CC-BY-ND-1.0', + 'CC-BY-ND-2.0', + 'CC-BY-ND-2.5', + 'CC-BY-ND-3.0', + 'CC-BY-NC-1.0', + 'CC-BY-NC-2.0', + 'CC-BY-NC-2.5', + 'CC-BY-NC-3.0', + 'CC-BY-NC-ND-1.0', + 'CC-BY-NC-ND-2.0', + 'CC-BY-NC-ND-2.5', + 'CC-BY-NC-ND-3.0', + 'CC-BY-NC-SA-1.0', + 'CC-BY-NC-SA-2.0', + 'CC-BY-NC-SA-2.5', + 'CC-BY-NC-SA-3.0', + 'CC-BY-SA-1.0', + 'CC-BY-SA-2.0', + 'CC-BY-SA-2.5', + 'CC-BY-SA-3.0', + 'CC0-1.0', + 'CUA-OPL-1.0', + 'D-FSL-1.0', + 'WTFPL', + 'EPL-1.0', + 'eCos-2.0', + 'ECL-1.0', + 'ECL-2.0', + 'EFL-1.0', + 'EFL-2.0', + 'Entessa', + 'ErlPL-1.1', + 'EUDatagrid', + 'EUPL-1.0', + 'EUPL-1.1', + 'Fair', + 'Frameworx-1.0', + 'FTL', + 'AGPL-1.0', + 'AGPL-3.0', + 'GFDL-1.1', + 'GFDL-1.2', + 'GFDL-1.3', + 'GPL-1.0', + 'GPL-1.0+', + 'GPL-2.0', + 'GPL-2.0+', + 'GPL-2.0-with-autoconf-exception', + 'GPL-2.0-with-bison-exception', + 'GPL-2.0-with-classpath-exception', + 'GPL-2.0-with-font-exception', + 'GPL-2.0-with-GCC-exception', + 'GPL-3.0', + 'GPL-3.0+', + 'GPL-3.0-with-autoconf-exception', + 'GPL-3.0-with-GCC-exception', + 'LGPL-2.1', + 'LGPL-2.1+', + 'LGPL-3.0', + 'LGPL-3.0+', + 'LGPL-2.0', + 'LGPL-2.0+', + 'gSOAP-1.3b', + 'HPND', + 'IPL-1.0', + 'Imlib2', + 'IJG', + 'Intel', + 'IPA', + 'ISC', + 'JSON', + 'LPPL-1.3a', + 'LPPL-1.0', + 'LPPL-1.1', + 'LPPL-1.2', + 'LPPL-1.3c', + 'Libpng', + 'LPL-1.02', + 'LPL-1.0', + 'MS-PL', + 'MS-RL', + 'MirOS', + 'MIT', + 'Motosoto', + 'MPL-1.0', + 'MPL-1.1', + 'MPL-2.0', + 'MPL-2.0-no-copyleft-exception', + 'Multics', + 'NASA-1.3', + 'Naumen', + 'NBPL-1.0', + 'NGPL', + 'NOSL', + 'NPL-1.0', + 'NPL-1.1', + 'Nokia', + 'NPOSL-3.0', + 'NTP', + 'OCLC-2.0', + 'ODbL-1.0', + 'PDDL-1.0', + 'OGTSL', + 'OLDAP-2.2.2', + 'OLDAP-1.1', + 'OLDAP-1.2', + 'OLDAP-1.3', + 'OLDAP-1.4', + 'OLDAP-2.0', + 'OLDAP-2.0.1', + 'OLDAP-2.1', + 'OLDAP-2.2', + 'OLDAP-2.2.1', + 'OLDAP-2.3', + 'OLDAP-2.4', + 'OLDAP-2.5', + 'OLDAP-2.6', + 'OLDAP-2.7', + 'OPL-1.0', + 'OSL-1.0', + 'OSL-2.0', + 'OSL-2.1', + 'OSL-3.0', + 'OLDAP-2.8', + 'OpenSSL', + 'PHP-3.0', + 'PHP-3.01', + 'PostgreSQL', + 'Python-2.0', + 'QPL-1.0', + 'RPSL-1.0', + 'RPL-1.1', + 'RPL-1.5', + 'RHeCos-1.1', + 'RSCPL', + 'Ruby', + 'SAX-PD', + 'SGI-B-1.0', + 'SGI-B-1.1', + 'SGI-B-2.0', + 'OFL-1.0', + 'OFL-1.1', + 'SimPL-2.0', + 'Sleepycat', + 'SMLNJ', + 'SugarCRM-1.1.3', + 'SISSL', + 'SPL-1.0', + 'Watcom-1.0', + 'NCSA', + 'VSL-1.0', + 'W3C', + 'WXwindows', + 'Xnet', + 'X11', + 'XFree86-1.1', + 'YPL-1.0', + 'YPL-1.1', + 'Zimbra-1.3', + 'Zlib', + 'ZPL-1.1', + 'ZPL-2.0', + 'ZPL-2.1', +) + + +# Maps lowercase id to standard ids with official case +SPDX_LICENSE_IDS = dict((name.lower(), name) for name in SPDX_LICENSES) + + +# Use DJE License Name +COMMON_LICENSES = ( + 'AES-128 v3.0 License', + 'Apache License 1.1', + 'Apache License 2.0', + 'Apple Attribution License 1997', + 'Apple Example Code License', + 'Apple Public Source License 2.0', + 'Arphic Public License', + 'Artistic License (Perl) 1.0', + 'Artistic License 2.0', + 'Bitstream Vera Font License', + 'Boost Software License 1.0', + 'Broadcom CFE License', + 'BSD-Modified', + 'BSD-Original', + 'BSD-Original-UC', + 'BSD-Simplified', + 'CMU Computing Services License', + 'Common Development and Distribution License 1.0', + 'Common Development and Distribution License 1.1', + 'Common Public License 1.0', + 'Creative Commons Attribution License 2.5', + 'Creative Commons Attribution Share Alike License 3.0', + 'Curl License', + 'FreeType Project License', + 'GNU General Public License 2.0', + 'GNU General Public License 2.0 with Bison exception', + 'GNU General Public License 2.0 with GLIBC exception', + 'GNU General Public License 3.0', + 'GNU Lesser General Public License 2.1', + 'GNU Library General Public License 2.0', + 'GPL 2.0 or later with Linking exception', + 'GPL 2.0 with Broadcom Linking exception', + 'Independent JPEG Group License', + 'ISC License (ISCL)', + 'Larabie Fonts EULA', + 'Libpng License', + 'Microsoft Limited Public License', + 'Microsoft Public License', + 'Microsoft Reciprocal License', + 'Microsoft TrueType Fonts EULA', + 'MIT License', + 'Mozilla Public License 1.1', + 'Net SNMP License', + 'Netscape Public License 1.1', + 'NTP License', + 'OpenSSL/SSLeay License', + 'Original SSLeay License with Windows exception', + 'RSA Data Security MD4', + 'RSA Data Security MD5', + 'SFL License Agreement', + 'SGI Free Software License B v2.0', + 'Sun RPC License', + 'TCL/TK License', + 'Tidy License', + 'University of Illinois/NCSA Open Source License', + 'X11 License', + 'ZLIB License', +) diff --git a/about_code_tool/templates/default.html b/about_code_tool/templates/default.html index 570f3781..69912217 100644 --- a/about_code_tool/templates/default.html +++ b/about_code_tool/templates/default.html @@ -53,7 +53,7 @@

{{ about_object.name }} {% if about_object.version %}{{ about_object.version }}{% endif %}

{% if about_object.dje_license_name %} -

This component is licensed under {{about_object.dje_license_name }}. +

This component is licensed under {{about_object.dje_license_name }}.

{% endif %} {% if about_object.copyright %}
{{about_object.copyright}}
diff --git a/about_code_tool/templates/json_template.template b/about_code_tool/templates/json_template.template new file mode 100644 index 00000000..f745803e --- /dev/null +++ b/about_code_tool/templates/json_template.template @@ -0,0 +1,18 @@ +{ + "ossAttribution": { + "product": "", + "productVersion": "", + "entries": [ + {% for about_object in about_objects %} + { + "component": {{ about_object.component }} + "componentVersion": {{ about_object.version }} + "componentUrl": {{ about_object.componenturl }} + "license": {{ about_object.license }} + "licenseUrl": {{ about_object.licenseurl }} + "notice": {{ about_object.copyright }} + }, + {% endfor %} + ] + } +} \ No newline at end of file diff --git a/about_code_tool/tests/test_about.py b/about_code_tool/tests/test_about.py index b6cce448..36b6c4d1 100644 --- a/about_code_tool/tests/test_about.py +++ b/about_code_tool/tests/test_about.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2016 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,80 +16,53 @@ from __future__ import print_function +import os +from os.path import abspath +from os.path import dirname +from os.path import join +import re import string from StringIO import StringIO -import tempfile import unittest from unittest.case import skip -import os -import re -import stat -from os.path import abspath, dirname, join, split - -from about_code_tool import about +from about_code_tool.about import Collector +from about_code_tool.about import AboutFile +from about_code_tool.about import check_invalid_chars +from about_code_tool.about import check_network_connection +from about_code_tool.about import IGNORED +from about_code_tool.about import FILE +from about_code_tool.about import VALUE +from about_code_tool.about import DATE +from about_code_tool.about import SPDX +from about_code_tool.about import is_about_file +from about_code_tool.about import ASCII + +from about_code_tool.util import on_windows +from about_code_tool.util import UNC_PREFIX +from about_code_tool.util import posix_path + +from about_code_tool.tests.tstutil import get_temp_file +from about_code_tool.util import extract_zip TESTDATA_DIR = join(abspath(dirname(__file__)), 'testdata') -def create_dir(location): - """ - Create directory or directory tree at location, ensuring it is readable - and writeable. - """ - if not os.path.exists(location): - os.makedirs(location) - os.chmod(location, stat.S_IRWXU | stat.S_IRWXG - | stat.S_IROTH | stat.S_IXOTH) - - -def build_temp_dir(prefix='test-about-code-'): - """ - Create and return a new unique empty directory created in base_dir. - """ - location = tempfile.mkdtemp(prefix=prefix) - create_dir(location) - return location - - -def get_temp_file(file_name='test-about-code-tempfile'): - """ - Return a unique new temporary file location to a non-existing - temporary file that can safely be created without a risk of name - collision. - """ - temp_dir = get_temp_dir() - location = os.path.join(temp_dir, file_name) - return location - - -def get_temp_dir(sub_dir_path=None): - """ - Create a unique new temporary directory location. Create directories - identified by sub_dir_path if provided in this temporary directory. - Return the location for this unique directory joined with the - sub_dir_path if any. - """ - new_temp_dir = build_temp_dir() - - if sub_dir_path: - # create a sub directory hierarchy if requested - new_temp_dir = os.path.join(new_temp_dir, sub_dir_path) - create_dir(new_temp_dir) - return new_temp_dir - - class CollectorTest(unittest.TestCase): + maxDiff = None + def test_return_path_is_not_abspath_and_contains_subdirs_on_file(self): # Using a relative path for the purpose of this test - test_file = ('about_code_tool/tests/testdata/thirdparty' - '/django_snippets_2413.ABOUT') + test_file = 'about_code_tool/tests/testdata/thirdparty/django_snippets_2413.ABOUT' output = get_temp_file() - collector = about.Collector(test_file) + collector = Collector(test_file) collector.write_to_csv(output) - expected = ('about_code_tool/tests/testdata/thirdparty' - '/django_snippets_2413.ABOUT') + expected = 'about_code_tool/tests/testdata/thirdparty/django_snippets_2413.ABOUT' # FIXME: why [2]? what this test means? + # CY: Since the output is going to have 2 rows (header row and row with + # the test file data), the below partition('\n')[2] means to only read + # the data row and ignroe the header row. This test is to make sure + # the path in the data row is not an absolute path. with open(output) as f: self.assertTrue(f.read().partition('\n')[2].startswith(expected)) @@ -97,33 +70,38 @@ def test_return_path_is_not_abspath_and_contains_subdirs_on_dir(self): # Using a relative path for the purpose of this test test_file = 'about_code_tool/tests/testdata/basic' output = get_temp_file() - collector = about.Collector(test_file) + collector = Collector(test_file) collector.write_to_csv(output) expected = '/basic' # FIXME: why [2]? what this test means? + # CY: Since the output is going to have 2 rows (header row and row with + # the test file data), the below partition('\n')[2] means to only read + # the data row and ignroe the header row. This test is to make sure + # the path in the data row is not an absolute path. with open(output) as f: self.assertTrue(f.read().partition('\n')[2].startswith(expected)) def test_header_row_in_csv_output(self): - expected_header = ('about_file,name,version,about_resource,' - 'spec_version,date,description,description_file,' - 'home_url,download_url,readme,readme_file,install,install_file,' - 'changelog,changelog_file,news,news_file,news_url,notes,notes_file,' - 'contact,owner,author,author_file,copyright,copyright_file,' - 'notice_file,notice_url,license_text_file,license_url,license_spdx,' - 'redistribute,attribute,track_changes,vcs_tool,vcs_repository,' - 'vcs_path,vcs_tag,vcs_branch,vcs_revision,checksum_sha1,checksum_md5,' - 'checksum_sha256,dje_component,dje_license_key,dje_organization,' - 'dje_license_name,scm_branch,scm_repository,signature_gpg_file,' - 'redistribute_sources,dje_license,about_format,usage,' - 'license_text,notice,scm_path,scm_tool,scm_rev,scm_tag,organization,' - 'warnings,errors') + expected_header = ( + 'about_file,name,version,about_resource,' + 'spec_version,date,description,description_file,' + 'home_url,download_url,readme,readme_file,install,install_file,' + 'changelog,changelog_file,news,news_file,news_url,notes,notes_file,' + 'contact,owner,author,author_file,copyright,copyright_file,' + 'notice_file,notice_url,license_text_file,license_url,license_spdx,' + 'redistribute,attribute,track_changes,vcs_tool,vcs_repository,' + 'vcs_path,vcs_tag,vcs_branch,vcs_revision,checksum_sha1,checksum_md5,' + 'checksum_sha256,dje_component,dje_license_key,dje_organization,' + 'dje_license_name,scm_branch,scm_repository,signature_gpg_file,' + 'redistribute_sources,dje_license,about_format,usage,' + 'license_text,notice,scm_path,scm_tool,scm_rev,scm_tag,organization,' + 'warnings,errors' + ) test_file = 'about_code_tool/tests/testdata/basic' output = get_temp_file() - collector = about.Collector(test_file) + collector = Collector(test_file) collector.write_to_csv(output) - header_row = '' with open(output) as f: header_row = f.readline().replace('\n', '').replace('\r', '') header_row_array = header_row.split(',') @@ -134,133 +112,115 @@ def test_header_row_in_csv_output(self): def test_collect_can_collect_a_directory_tree(self): test_dir = 'about_code_tool/tests/testdata/DateTest' - expected = [('about_code_tool/tests/testdata/DateTest' - '/non-supported_date_format.ABOUT'), - ('about_code_tool/tests/testdata/DateTest' - '/supported_date_format.ABOUT')] - result = about.Collector.collect(test_dir) + if on_windows: + expected = [ + (posix_path(UNC_PREFIX + os.path.abspath('about_code_tool/tests/testdata/DateTest/non-supported_date_format.ABOUT'))), + (posix_path(UNC_PREFIX + os.path.abspath('about_code_tool/tests/testdata/DateTest/supported_date_format.ABOUT'))) + ] + else: + expected = [ + (os.path.abspath('about_code_tool/tests/testdata/DateTest/non-supported_date_format.ABOUT')), + (os.path.abspath('about_code_tool/tests/testdata/DateTest/supported_date_format.ABOUT')) + ] + result = Collector.collect(test_dir) self.assertEqual(sorted(expected), sorted(result)) def test_collect_can_collect_a_single_file(self): - test_file = ('about_code_tool/tests/testdata/thirdparty' - '/django_snippets_2413.ABOUT') - expected = ['about_code_tool/tests/testdata/thirdparty' - '/django_snippets_2413.ABOUT'] - result = about.Collector.collect(test_file) + test_file = ('about_code_tool/tests/testdata/thirdparty/django_snippets_2413.ABOUT') + if on_windows: + expected = [posix_path(UNC_PREFIX + os.path.abspath('about_code_tool/tests/testdata/thirdparty/django_snippets_2413.ABOUT'))] + else: + expected = [os.path.abspath('about_code_tool/tests/testdata/thirdparty/django_snippets_2413.ABOUT')] + result = Collector.collect(test_file) self.assertEqual(expected, result) + def test_collect_can_collect_a_directory_tree_with_long_and_deep_paths(self): + test_zip = 'about_code_tool/tests/testdata/longpath/longpath.zip' + test_dir = extract_zip(test_zip) + + + longpath = 'longpath1/' * 28 + expected = 'longpath/' + longpath + 'non-supported_date_format.ABOUT' + + result = Collector.collect(test_dir)[0] + def rel_path(pth): + p = posix_path(pth) + return p.partition('/longpath/')[2] + print() + print(result) + print(rel_path(result)) + self.assertEqual(expected, rel_path(result)) + def test_collector_errors_encapsulation(self): test_file = 'about_code_tool/tests/testdata/DateTest' - collector = about.Collector(test_file) + collector = Collector(test_file) self.assertEqual(2, len(collector.errors)) def test_collector_warnings_encapsulation(self): test_file = 'about_code_tool/tests/testdata/allAboutInOneDir' - collector = about.Collector(test_file) + collector = Collector(test_file) # self.assertEqual(4, len(collector.warnings)) # No warning is thrown as all fields from ABOUT files are accepted. self.assertEqual(0, len(collector.warnings)) + class ParserTest(unittest.TestCase): + maxDiff = None + def test_valid_chars_in_field_name(self): name = string.digits + string.ascii_letters + '_' line = string.digits + string.ascii_letters + '_' - result, _warn = about.check_invalid_chars(name, line) + result, _warn = check_invalid_chars(name, line) expected = [] self.assertEqual(expected, result) def test_result_chars_in_field_name(self): name = '_$asafg:' line = '_$asafg: test' - result, _warn = about.check_invalid_chars(name, line) + result, _warn = check_invalid_chars(name, line) expected = ['$', ':'] self.assertEqual(expected, result) def test_result_space_in_field_name(self): name = '_ Hello' line = '_ Hello' - result, _warn = about.check_invalid_chars(name, line) + result, _warn = check_invalid_chars(name, line) expected = [' '] self.assertEqual(expected, result) def test_valid_chars_in_file_name(self): - about_obj = about.AboutFile() + about_obj = AboutFile() name = string.digits + string.ascii_letters + '_-.+' result = about_obj.invalid_chars_in_about_file_name(name) expected = [] self.assertEqual(expected, result) def test_result_chars_in_file_name(self): - about_obj = about.AboutFile() + about_obj = AboutFile() result = about_obj.invalid_chars_in_about_file_name('_$a+s/afg:') expected = [':'] self.assertEqual(expected, result) def test_result_chars_in_file_name_path(self): - about_obj = about.AboutFile() + about_obj = AboutFile() name = '%6571351()275612$/_$asafg:/' result = about_obj.invalid_chars_in_about_file_name(name) expected = [] self.assertEqual(expected, result) def test_result_chars_in_file_name_path2(self): - about_obj = about.AboutFile() + about_obj = AboutFile() name = '%6571351()275612$_$asafg:' result = about_obj.invalid_chars_in_about_file_name(name) expected = ['%', '(', ')', '$', '$', ':'] self.assertEqual(expected, result) def test_result_space_in_file_name(self): - about_obj = about.AboutFile() + about_obj = AboutFile() result = about_obj.invalid_chars_in_about_file_name('_ Hello') expected = [' '] self.assertEqual(expected, result) - def test_resource_name(self): - expected = 'first' - result = about.resource_name('some/things/first') - self.assertEqual(expected, result) - - def test_resource_name1(self): - expected = 'first' - result = about.resource_name('some/things/first/') - self.assertEqual(expected, result) - - def test_resource_name2(self): - expected = r'things\first' - result = about.resource_name(r'c:\some/things\first') - self.assertEqual(expected, result) - - def test_resource_name3(self): - expected = 'first' - result = about.resource_name(r'some\thi ngs//first') - self.assertEqual(expected, result) - - def test_resource_name4(self): - expected = r'\\' - result = about.resource_name(r'%6571351()275612$/_$asafg:/\\') - self.assertEqual(expected, result) - - def test_resource_name5(self): - expected = '_$asafg:' - result = about.resource_name('%6571351()2/75612$/_$asafg:') - self.assertEqual(expected, result) - - def test_resource_name_does_not_recurse_infinitely(self): - expected = '' - result = about.resource_name('/') - self.assertEqual(expected, result) - - def test_resource_name_does_not_recurse_infinitely2(self): - expected = '' - result = about.resource_name('/ / ') - self.assertEqual(expected, result) - - def test_resource_name_does_not_recurse_infinitely3(self): - expected = '' - result = about.resource_name(' / ') - self.assertEqual(expected, result) - def test_pre_process_when_user_forgets_colon(self): text_input = ''' about_resource: jquery.js @@ -276,12 +236,14 @@ def test_pre_process_when_user_forgets_colon(self): version: 1.2.3 date: 2013-01-02 ''' - expected_warnings = [(about.IGNORED, 'notes this is the first line.\n'), - (about.IGNORED, ' this is the second.\n',), - (about.IGNORED, ' this is the third.\n',)] - - about_obj = about.AboutFile() - result, warn = about.AboutFile.pre_process(about_obj, StringIO(text_input)) + expected_warnings = [ + (IGNORED, 'notes this is the first line.\n'), + (IGNORED, ' this is the second.\n',), + (IGNORED, ' this is the third.\n',) + ] + + about_obj = AboutFile() + result, warn = AboutFile.pre_process(about_obj, StringIO(text_input)) self.assertEqual(expected, result.read()) for i, w in enumerate(warn): self.assertEqual(expected_warnings[i][0], w.code) @@ -305,10 +267,10 @@ def test_user_forget_space_for_continuation_line(self): date: 2013-01-02 ''' - expected_warnings = [(about.IGNORED, 'this is the second.\n'), - (about.IGNORED, ' this is the third.\n')] - about_obj = about.AboutFile() - result, warn = about.AboutFile.pre_process(about_obj, StringIO(text_input)) + expected_warnings = [(IGNORED, 'this is the second.\n'), + (IGNORED, ' this is the third.\n')] + about_obj = AboutFile() + result, warn = AboutFile.pre_process(about_obj, StringIO(text_input)) self.assertEqual(expected, result.read()) for i, w in enumerate(warn): self.assertEqual(expected_warnings[i][0], w.code) @@ -323,9 +285,9 @@ def test_pre_process_with_invalid_chars_in_field_name(self): expected = '''about_resource: jquery.js name: jQuery ''' - about_obj = about.AboutFile() - result, warn = about.AboutFile.pre_process(about_obj, StringIO(text_input)) - self.assertEqual(about.IGNORED, warn[0].code) + about_obj = AboutFile() + result, warn = AboutFile.pre_process(about_obj, StringIO(text_input)) + self.assertEqual(IGNORED, warn[0].code) self.assertEqual('vers|ion', warn[0].field_name) self.assertEqual(expected, result.read()) @@ -339,33 +301,33 @@ def test_pre_process_with_spaces_left_of_colon(self): name: jQuery version: 1.2.3 ''' - about_obj = about.AboutFile() - result, _warn = about.AboutFile.pre_process(about_obj, + about_obj = AboutFile() + result, _warn = AboutFile.pre_process(about_obj, StringIO(text_input)) self.assertEqual(expected, result.read()) def test_handles_last_line_is_a_continuation_line(self): warnings = [] - warn = about.AboutFile.check_line_continuation(' Last line is a continuation line.', True) + warn = AboutFile.check_line_continuation(' Last line is a continuation line.', True) warnings.append(warn) self.assertEqual(warnings, ['']) def test_handles_last_line_is_not_a_continuation_line(self): warnings = [] - warn = about.AboutFile.check_line_continuation(' Last line is NOT a continuation line.', False) + warn = AboutFile.check_line_continuation(' Last line is NOT a continuation line.', False) warnings.append(warn) self.assertEqual(1, len(warnings)) def test_normalize_dupe_field_names(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/dupe_field_name.ABOUT')) - expected_warnings = [about.IGNORED, 'Apache HTTP Server'] + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/dupe_field_name.ABOUT')) + expected_warnings = [IGNORED, 'Apache HTTP Server'] self.assertEqual(1, len(about_file.warnings)) for w in about_file.warnings: self.assertEqual(expected_warnings[0], w.code) self.assertEqual(expected_warnings[1], w.field_value) def test_normalize_lowercase(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/upper_field_names.ABOUT')) + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/upper_field_names.ABOUT')) expected = {'name': 'Apache HTTP Server\nthis is a continuation', 'home_url': 'http://httpd.apache.org', 'download_url': 'http://archive.apache.org/dist/httpd/httpd-2.4.3.tar.gz', @@ -380,47 +342,55 @@ def test_normalize_lowercase(self): def test_validate_about_ref_testing_the_about_resource_field_is_present(self): test_file = join(TESTDATA_DIR, 'parser_tests/about_resource_field_present.ABOUT') - about_file = about.AboutFile(test_file) + about_file = AboutFile(test_file) expected = 'about_resource.c' self.assertEqual(about_file.about_resource, expected) def test_validate_about_ref_no_about_ref_key(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/.ABOUT')) + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/.ABOUT')) # We do not need 'about_resource' now, so no error should be thrown. - # expected_errors = [about.VALUE, 'about_resource'] + # expected_errors = [VALUE, 'about_resource'] self.assertEqual(0, len(about_file.errors)) '''for w in about_file.errors: self.assertEqual(expected_errors[0], w.code) self.assertEqual(expected_errors[1], w.field_name)''' def test_validate_about_resource_error_thrown_when_file_referenced_by_about_file_does_not_exist(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/missing_about_ref.ABOUT')) - expected_errors = [about.FILE, 'about_resource'] + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/missing_about_ref.ABOUT')) + expected_errors = [FILE, 'about_resource'] self.assertEqual(1, len(about_file.errors)) for w in about_file.errors: self.assertEqual(expected_errors[0], w.code) self.assertEqual(expected_errors[1], w.field_name) def test_validate_mand_fields_name_and_version_and_about_resource_present(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/missing_mand.ABOUT')) - expected_errors = [(about.VALUE, 'name'), - (about.VALUE, 'version'), ] - self.assertEqual(2, len(about_file.errors)) + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/missing_mand.ABOUT')) + expected_errors = [(VALUE, 'name'),] + expected_warnings = [(VALUE, 'version'),] + self.assertEqual(1, len(about_file.errors)) + self.assertEqual(1, len(about_file.warnings)) for i, w in enumerate(about_file.errors): self.assertEqual(expected_errors[i][0], w.code) self.assertEqual(expected_errors[i][1], w.field_name) + for i, w in enumerate(about_file.warnings): + self.assertEqual(expected_warnings[i][0], w.code) + self.assertEqual(expected_warnings[i][1], w.field_name) - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/missing_mand_values.ABOUT')) - expected_errors = [(about.VALUE, 'name'), - (about.VALUE, 'version')] - self.assertEqual(2, len(about_file.errors)) + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/missing_mand_values.ABOUT')) + expected_errors = [(VALUE, 'name'),] + expected_warnings = [(VALUE, 'version'),] + self.assertEqual(1, len(about_file.errors)) + self.assertEqual(1, len(about_file.warnings)) for i, w in enumerate(about_file.errors): self.assertEqual(expected_errors[i][0], w.code) self.assertEqual(expected_errors[i][1], w.field_name) + for i, w in enumerate(about_file.warnings): + self.assertEqual(expected_warnings[i][0], w.code) + self.assertEqual(expected_warnings[i][1], w.field_name) def test_validate_optional_file_field_value(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'parser_tests/about_file_ref.c.ABOUT')) - expected_warnings = [about.VALUE, 'notice_file'] + about_file = AboutFile(join(TESTDATA_DIR, 'parser_tests/about_file_ref.c.ABOUT')) + expected_warnings = [VALUE, 'notice_file'] self.assertEqual(1, len(about_file.warnings)) for w in about_file.warnings: self.assertEqual(expected_warnings[0], w.code) @@ -430,95 +400,95 @@ def test_validate_optional_file_field_value(self): class UrlCheckTest(unittest.TestCase): @skip('# FIXME: we should use a mock HTTP server AND NEVER do live HTTP requests') def test_check_url__with_network(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url('http://www.google.com', True)) self.assertTrue(about_file.check_url('http://www.google.co.uk/', True)) @skip('# FIXME: we should use a mock HTTP server AND NEVER do live HTTP requests') def test_check_url__with_network__not_starting_with_www(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url('https://nexb.com', True)) self.assertTrue(about_file.check_url('http://archive.apache.org/dist/httpcomponents/commons-httpclient/2.0/source/commons-httpclient-2.0-alpha2-src.tar.gz', True)) - if about.check_network_connection(): + if check_network_connection(): self.assertFalse(about_file.check_url('http://nothing_here.com', True)) @skip('# FIXME: we should use a mock HTTP server AND NEVER do live HTTP requests') def test_check_url__with_network__not_starting_with_www_and_spaces(self): # TODO: this does work yet as we do not have a solution for now (URL with spaces) - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)', True)) @skip('# FIXME: we should use a mock HTTP server AND NEVER do live HTTP requests') def test_check_url__with_network__no_schemes(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertFalse(about_file.check_url('google.com', True)) self.assertFalse(about_file.check_url('www.google.com', True)) self.assertFalse(about_file.check_url('', True)) @skip('# FIXME: we should use a mock HTTP server AND NEVER do live HTTP requests') def test_check_url__with_network__not_reachable(self): - about_file = about.AboutFile() - if about.check_network_connection(): + about_file = AboutFile() + if check_network_connection(): self.assertFalse(about_file.check_url('http://www.google', True)) @skip('# FIXME: we should use a mock HTTP server AND NEVER do live HTTP requests') def test_check_url__with_network__empty_URL(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertFalse(about_file.check_url('http:', True)) def test_check_url__without_network(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url('http://www.google.com', False)) def test_check_url__without_network__not_starting_with_www(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url('https://nexb.com', False)) self.assertTrue(about_file.check_url('http://archive.apache.org/dist/httpcomponents/commons-httpclient/2.0/source/commons-httpclient-2.0-alpha2-src.tar.gz', False)) self.assertTrue(about_file.check_url('http://de.wikipedia.org/wiki/Elf (Begriffsklärung)', False)) self.assertTrue(about_file.check_url('http://nothing_here.com', False)) def test_check_url__without_network__no_schemes(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertFalse(about_file.check_url('google.com', False)) self.assertFalse(about_file.check_url('www.google.com', False)) self.assertFalse(about_file.check_url('', False)) def test_check_url__without_network__not_ends_with_com(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url('http://www.google', False)) def test_check_url__without_network__ends_with_slash(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_url('http://www.google.co.uk/', False)) def test_check_url__without_network__empty_URL(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertFalse(about_file.check_url('http:', False)) class ValidateTest(unittest.TestCase): def test_is_valid_about_file(self): - self.assertTrue(about.is_about_file('test.About')) - self.assertTrue(about.is_about_file('test2.aboUT')) - self.assertFalse(about.is_about_file('no_about_ext.something')) + self.assertTrue(is_about_file('test.About')) + self.assertTrue(is_about_file('test2.aboUT')) + self.assertFalse(is_about_file('no_about_ext.something')) def test_validate_is_ascii_key(self): - about_file = about.AboutFile() + about_file = AboutFile() self.assertTrue(about_file.check_is_ascii('abc')) self.assertTrue(about_file.check_is_ascii('123')) self.assertTrue(about_file.check_is_ascii('!!!')) self.assertFalse(about_file.check_is_ascii(u'測試')) def test_validate_is_ascii_value(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'filesfields/non_ascii_field.about')) - expected_errors = [about.ASCII] + about_file = AboutFile(join(TESTDATA_DIR, 'filesfields/non_ascii_field.about')) + expected_errors = [ASCII] self.assertEqual(1, len(about_file.errors)) self.assertEqual(about_file.errors[0].code, expected_errors[0]) def test_validate_spdx_licenses(self): test_file = join(TESTDATA_DIR, 'spdx_licenses/incorrect_spdx.about') - about_file = about.AboutFile(test_file) - expected_errors = [about.SPDX] + about_file = AboutFile(test_file) + expected_errors = [SPDX] self.assertEqual(1, len(about_file.errors)) for w in about_file.errors: self.assertEqual(expected_errors[0], w.code) @@ -526,8 +496,8 @@ def test_validate_spdx_licenses(self): def test_validate_spdx_licenses1(self): test_file = join(TESTDATA_DIR, 'spdx_licenses/invalid_multi_format_spdx.ABOUT') - about_file = about.AboutFile(test_file) - expected_errors = [about.SPDX] + about_file = AboutFile(test_file) + expected_errors = [SPDX] self.assertEqual(1, len(about_file.errors)) for w in about_file.errors: self.assertEqual(expected_errors[0], w.code) @@ -535,8 +505,8 @@ def test_validate_spdx_licenses1(self): def test_validate_spdx_licenses2(self): test_file = join(TESTDATA_DIR, 'spdx_licenses/invalid_multi_name.ABOUT') - about_file = about.AboutFile(test_file) - expected_errors = [about.SPDX] + about_file = AboutFile(test_file) + expected_errors = [SPDX] # The test case is: license_spdx: Something and SomeOtherThings self.assertEqual(1, len(about_file.errors)) for w in about_file.errors: @@ -544,8 +514,8 @@ def test_validate_spdx_licenses2(self): def test_validate_spdx_licenses3(self): test_file = join(TESTDATA_DIR, 'spdx_licenses/lower_case_spdx.ABOUT') - about_file = about.AboutFile(test_file) - expected_warnings = [about.SPDX] + about_file = AboutFile(test_file) + expected_warnings = [SPDX] self.assertEqual(1, len(about_file.warnings)) for w in about_file.warnings: self.assertEqual(expected_warnings[0], w.code) @@ -553,15 +523,15 @@ def test_validate_spdx_licenses3(self): def test_validate_not_supported_date_format(self): test_file = join(TESTDATA_DIR, 'DateTest/non-supported_date_format.ABOUT') - about_file = about.AboutFile(test_file) - expected_warnings = [about.DATE] + about_file = AboutFile(test_file) + expected_warnings = [DATE] self.assertEqual(1, len(about_file.warnings)) for w in about_file.warnings: self.assertEqual(expected_warnings[0], w.code) def test_validate_supported_date_format(self): test_file = join(TESTDATA_DIR, 'DateTest/supported_date_format.ABOUT') - about_file = about.AboutFile(test_file) + about_file = AboutFile(test_file) self.assertEqual(0, len(about_file.warnings)) def test_remove_blank_lines_and_field_spaces(self): @@ -577,9 +547,9 @@ def test_remove_blank_lines_and_field_spaces(self): ''' msg = 'field with spaces: This is a test case for field with spaces\n' - expected_warnings = [(about.IGNORED, msg)] - about_obj = about.AboutFile() - result, warn = about.AboutFile.pre_process(about_obj, + expected_warnings = [(IGNORED, msg)] + about_obj = AboutFile() + result, warn = AboutFile.pre_process(about_obj, StringIO(text_input)) self.assertEqual(expected, result.read()) for i, w in enumerate(warn): @@ -599,11 +569,10 @@ def test_remove_blank_lines_and_no_colon_fields(self): about_resource: about.py ''' - expected_warnings = [(about.IGNORED, 'test\n'), - (about.IGNORED, 'test with no colon\n')] - about_obj = about.AboutFile() - result, warn = about.AboutFile.pre_process(about_obj, - StringIO(text_input)) + expected_warnings = [(IGNORED, 'test\n'), + (IGNORED, 'test with no colon\n')] + about_obj = AboutFile() + result, warn = AboutFile.pre_process(about_obj, StringIO(text_input)) self.assertEqual(expected, result.read()) for i, w in enumerate(warn): @@ -612,11 +581,11 @@ def test_remove_blank_lines_and_no_colon_fields(self): def test_generate_attribution_with_custom_template(self): expected = (u'notice_text:' - 'version:2.4.3' - 'about_resource:httpd-2.4.3.tar.gz' - 'name:Apache HTTP Serverlicense_text:') + u'version:2.4.3' + u'about_resource:httpd-2.4.3.tar.gz' + u'name:Apache HTTP Serverlicense_text:') test_file = join(TESTDATA_DIR, 'attrib/attrib.ABOUT') - collector = about.Collector(test_file) + collector = Collector(test_file) template = join(TESTDATA_DIR, 'attrib/test.template') result = collector.generate_attribution(template, limit_to=['']) self.assertEqual(expected, result) @@ -625,18 +594,27 @@ def test_generate_attribution_with_default_template(self): f = open(join(TESTDATA_DIR, 'attrib/attrib.html')) expected = f.read() test_file = join(TESTDATA_DIR, 'attrib/attrib.ABOUT') - collector = about.Collector(test_file) + collector = Collector(test_file) result = collector.generate_attribution(limit_to=['']) # Strip all the white spaces self.assertEqual(re.sub(r'\s+', '', expected), re.sub(r'\s+', '', result)) + def test_generate_attribution_with_limit_to(self): + f = open(join(TESTDATA_DIR, 'attrib/attrib.html')) + expected = f.read() + test_file = join(TESTDATA_DIR, 'attrib/') + collector = Collector(test_file) + result = collector.generate_attribution(limit_to=['/attrib.ABOUT']) + # Strip all the white spaces + self.assertEqual(re.sub(r'\s+', '', expected), re.sub(r'\s+', '', result)) + def test_generate_attribution_verification(self): expected = (u'name,version,copyright,dje_license_name\n' - 'Apache HTTP Server,2.4.3,,') + u'Apache HTTP Server,2.4.3,,') test_file = join(TESTDATA_DIR, 'attrib/attrib.ABOUT') - collector = about.Collector(test_file) + collector = Collector(test_file) test_path = get_temp_file('test.csv') - result = collector.generate_attribution(limit_to=[''], verification=test_path) + collector.generate_attribution(limit_to=[''], verification=test_path) with open(test_path, 'rU') as f: self.assertEqual(f.read().rstrip(), expected) @@ -647,68 +625,68 @@ def test_license_text_extracted_from_license_text_file(self): * Email Test@tester.com for any questions''' test_file = join(TESTDATA_DIR, 'attrib/license_text.ABOUT') - about_file = about.AboutFile(test_file) + about_file = AboutFile(test_file) result = about_file.license_text() self.assertEqual(expected, result) def test_notice_text_extacted_from_notice_text_file(self): expected = '''Test component is released to Public Domain.''' test_file = join(TESTDATA_DIR, 'attrib/license_text.ABOUT') - about_file = about.AboutFile(test_file) + about_file = AboutFile(test_file) result = about_file.notice_text() self.assertEqual(result, expected) def test_license_text_returns_empty_string_when_no_field_present(self): expected = '' test_file = join(TESTDATA_DIR, 'attrib/no_text_file_field.ABOUT') - about_file = about.AboutFile(test_file) + about_file = AboutFile(test_file) result = about_file.license_text() self.assertEqual(result, expected) def test_notice_text_returns_empty_string_when_no_field_present(self): test_file = join(TESTDATA_DIR, 'attrib/no_text_file_field.ABOUT') - about_file = about.AboutFile(test_file) + about_file = AboutFile(test_file) result = about_file.notice_text() expected = '' self.assertEqual(result, expected) def test_license_text_returns_empty_string_when_ref_file_doesnt_exist(self): expected = '' - test_file = join(TESTDATA_DIR, - 'attrib/missing_notice_license_files.ABOUT') - about_file = about.AboutFile(test_file) + test_file = join(TESTDATA_DIR, 'attrib/missing_notice_license_files.ABOUT') + about_file = AboutFile(test_file) result = about_file.license_text() self.assertEqual(result, expected) def test_notice_text_returns_empty_string_when_ref_file_doesnt_exist(self): expected = '' - test_file = join(TESTDATA_DIR, - 'attrib/missing_notice_license_files.ABOUT') - about_file = about.AboutFile(test_file) + test_file = join(TESTDATA_DIR, 'attrib/missing_notice_license_files.ABOUT') + about_file = AboutFile(test_file) result = about_file.notice_text() self.assertEqual(result, expected) -class OtherTest(unittest.TestCase): +class MiscTest(unittest.TestCase): def test_get_custom_field_keys(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'basic/basic.about')) + about_file = AboutFile(join(TESTDATA_DIR, 'basic/basic.about')) result = about_file.get_custom_field_keys() - expected = ['scm_branch', 'scm_repository', 'signature_gpg_file', - 'redistribute_sources', 'dje_license', - 'about_format', 'usage', - # These two keys are removed from the spec and therefore - # become a custom keys - 'license_text', 'notice', - 'scm_path', 'scm_tool', 'scm_rev', 'scm_tag', - 'organization'] + expected = [ + 'scm_branch', 'scm_repository', 'signature_gpg_file', + 'redistribute_sources', 'dje_license', + 'about_format', 'usage', + # These two keys are removed from the spec and therefore + # become a custom keys + 'license_text', 'notice', + 'scm_path', 'scm_tool', 'scm_rev', 'scm_tag', + 'organization' + ] self.assertEqual(result, expected) def test_get_about_name(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'basic/simple.about')) + about_file = AboutFile(join(TESTDATA_DIR, 'basic/simple.about')) result = about_file.get_about_name() self.assertEqual(result, 'simple') def test_get_dje_license_name(self): - about_file = about.AboutFile(join(TESTDATA_DIR, 'basic/simple.about')) + about_file = AboutFile(join(TESTDATA_DIR, 'basic/simple.about')) result = about_file.get_dje_license_name() self.assertEqual(result, 'Apache License 2.0') diff --git a/about_code_tool/tests/test_genabout.py b/about_code_tool/tests/test_genabout.py index 03db877c..13ecb1de 100644 --- a/about_code_tool/tests/test_genabout.py +++ b/about_code_tool/tests/test_genabout.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2016 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 @@ -19,10 +19,13 @@ import os import unittest -from os.path import abspath, dirname, join +from os.path import abspath +from os.path import dirname +from os.path import join -import test_about from about_code_tool import genabout +from about_code_tool.tests.tstutil import get_temp_dir +from about_code_tool.tests import test_about TESTDATA_DIR = join(abspath(dirname(__file__)), 'testdata') @@ -30,82 +33,71 @@ class GenAboutTest(unittest.TestCase): - def test_get_input_list(self): - gen = genabout.GenAbout() + def test_load_data_from_csv(self): test_file = join(TESTDATA_DIR, 'test_files_for_genabout/about.csv') - expected = [{'about_file': 'about.ABOUT', + expected = [ + { + 'about_file': 'about.ABOUT', + 'about_resource': '.', + 'name': 'ABOUT tool', + 'version': '0.8.1' + } + ] + result = genabout.load_data_from_csv(test_file) + self.assertEqual(expected, result) + + def test_load_data_from_csv_with_trailing_spaces(self): + test_file = join(TESTDATA_DIR, 'test_files_for_genabout/about_with_trailling_spaces.csv') + expected = [{'about_file': 'about.c', 'about_resource': '.', 'name': 'ABOUT tool', 'version': '0.8.1'}] - - result = gen.get_input_list(test_file) + result = genabout.load_data_from_csv(test_file) self.assertEqual(expected, result) - def test_get_input_list_covert_all_keys_to_lower(self): - gen = genabout.GenAbout() - test_input = join(TESTDATA_DIR, 'test_files_for_genabout' - '/about_key_with_upper_case.csv') - + def test_load_data_from_csv_does_converts_all_keys_to_lower(self): + test_input = join(TESTDATA_DIR, 'test_files_for_genabout/about_key_with_upper_case.csv') expected = [{'about_file': 'about.ABOUT', 'about_resource': '.', 'name': 'ABOUT tool', 'version': '0.8.1'}] - - result = gen.get_input_list(test_input) + result = genabout.load_data_from_csv(test_input) self.assertEqual(expected, result) - def test_get_non_empty_rows_list(self): - gen = genabout.GenAbout() - test_fields = [{'about_file': '/about.ABOUT', - 'about_resource': '.', - 'name': 'ABOUT tool', - 'version': '0.8.1'}, - {'about_file': '', - 'about_resource': '', - 'name': '', - 'version': ''}] + def test_filter_dicts_of_empty_values(self): + test_abouts = [ + {'about_file': '/about.ABOUT', + 'about_resource': '.', + 'name': 'ABOUT tool', + 'version': '0.8.1'}, + {'about_file': '', + 'about_resource': '', + 'name': '', + 'version': ''} + ] expected = [{'about_file': '/about.ABOUT', 'about_resource': '.', 'name': 'ABOUT tool', 'version': '0.8.1'}] - result = gen.get_non_empty_rows_list(test_fields) - self.assertEqual(result, expected) - - def test_get_mapping_list(self): - gen = genabout.GenAbout() - expected = {'about_file': 'directory/filename', - 'version': 'confirmed version', - 'name': 'component', - 'copyright': 'confirmed copyright', - 'confirmed_license': 'confirmed license'} - - result = gen.get_mapping_list() - self.assertEqual(result, expected) - - def test_convert_input_list(self): - gen = genabout.GenAbout() - mappings = {'about_file': 'Directory/Filename', - 'version': 'Confirmed Version', - 'about_resource': 'file_name', - 'name': 'Component'} + result = genabout.filter_dicts_of_empty_values(test_abouts) + self.assertEqual(expected, result) - test_fields = [{'file_name': 'opensans', - 'ignore field': 'i', - 'Component': 'OpenSans Fonts', - 'Confirmed Version': '1', - 'Directory/Filename': - '/extension/streamer/opensans/'}] + def test_filter_dicts_of_empty_values_does_not_filter_data_with_value(self): + test_abouts = [{'asaszname': '', 'version': '1'}] + result = genabout.filter_dicts_of_empty_values(test_abouts) + self.assertEqual(test_abouts, result) - expected = [{'about_file': '/extension/streamer/opensans/', - 'name': 'OpenSans Fonts', - 'ignore field': 'i', - 'version': '1', - 'about_resource': 'opensans'}] + def test_filter_dicts_of_empty_values_does_filter_data_with_empty_string_values(self): + test_abouts = [{'asaszname': '', 'version': ''}] + result = genabout.filter_dicts_of_empty_values(test_abouts) + self.assertEqual([], result) - result = gen.convert_input_list(test_fields, mappings) - self.assertEqual(result, expected) + def test_filter_dicts_of_empty_values_does_filter_data_with_space_only_values(self): + test_abouts = [{'asaszname': ' ', 'version': ' '}] + result = genabout.filter_dicts_of_empty_values(test_abouts) + self.assertEqual([], result) def test_validate_value_in_essential_missing_about_file(self): gen = genabout.GenAbout() @@ -146,8 +138,7 @@ def test_validate_value_in_essential_fields_no_missing(self): 'version': '0.8.1'}] self.assertTrue(gen.validate_value_in_essential_fields(test_fields)) - def test_validate_duplication_with_duplicates(self): - gen = genabout.GenAbout() + def test_has_duplicate_about_file_paths_with_duplicates(self): test_fields = [{'about_file': '/about.ABOUT', 'about_resource': '.', 'name': 'ABOUT tool', 'version': '0.8.1'}, @@ -156,11 +147,10 @@ def test_validate_duplication_with_duplicates(self): 'name': 'ABOUT tool', 'version': ''}] - result = gen.validate_duplication(test_fields) + result = genabout.has_duplicate_about_file_paths(test_fields) self.assertTrue(result) - def test_validate_duplication_with_no_duplicates(self): - gen = genabout.GenAbout() + def test_has_duplicate_about_file_paths_with_no_duplicates(self): test_fields = [{'about_file': '/about.ABOUT', 'about_resource': '.', 'name': 'ABOUT tool', @@ -170,7 +160,7 @@ def test_validate_duplication_with_no_duplicates(self): 'name': 'ABOUT tool', 'version': ''}] - result = gen.validate_duplication(test_fields) + result = genabout.has_duplicate_about_file_paths(test_fields) self.assertFalse(result) def test_get_duplicated_keys_have_dup(self): @@ -182,8 +172,7 @@ def test_get_duplicated_keys_have_dup(self): def test_get_duplicated_keys_have_dup_diff_case(self): gen = genabout.GenAbout() - test_file = join(TESTDATA_DIR, 'test_files_for_genabout' - '/dup_keys_with_diff_case.csv') + test_file = join(TESTDATA_DIR, 'test_files_for_genabout/dup_keys_with_diff_case.csv') expected = ['copyright', 'Copyright'] result = gen.get_duplicated_keys(test_file) @@ -214,28 +203,26 @@ def test_validate_mandatory_fields_missing_about_resource(self): result = gen.validate_mandatory_fields(test_fields) self.assertTrue(result) - def test_get_non_supported_fields_no_mapping(self): - gen = genabout.GenAbout() - test_fields = [{'about_file': '', + def test_get_unknown_fields_with_no_user_keys(self): + test_abouts = [{'about_file': '', 'name': 'OpenSans Fonts', 'non_supported field': 'TEST', 'version': '1', 'about_resource': 'opensans'}] - mapping_keys = [] - result = gen.get_non_supported_fields(test_fields, mapping_keys) + user_keys = [] + result = genabout.get_unknown_fields(test_abouts, user_keys) expected = ['non_supported field'] self.assertEqual(expected, result) - def test_get_non_supported_fields_with_mapping(self): - gen = genabout.GenAbout() + def test_get_unknown_fields__with_user_keys(self): test_fields = [{'about_file': '', 'name': 'OpenSans Fonts', 'non_supported field': 'TEST', 'version': '1', 'about_resource': 'opensans'}] - mapping_keys = ['non_supported field'] - result = gen.get_non_supported_fields(test_fields, mapping_keys) + user_keys = ['non_supported field'] + result = genabout.get_unknown_fields(test_fields, user_keys) expected = [] self.assertEqual(expected, result) @@ -252,8 +239,7 @@ def test_get_only_supported_fields(self): 'name': 'ABOUT tool', 'version': '0.8.1'}] - results = gen.get_only_supported_fields(test_fields, - ['non_supported']) + results = gen.get_only_supported_fields(test_fields, ['non_supported']) self.assertEqual(expected, results) def test_get_dje_license_list_no_gen_license_with_no_license_text_file(self): @@ -298,13 +284,12 @@ def test_get_dje_license_list_no_gen_license_with_license_text_file_key_not_exis def test_get_dje_license_list_file_no_gen_license_with_license_text_file_key_exist(self): gen = genabout.GenAbout() - # FIXME: this is using the about own license, not a test file gen_location = join(TESTDATA_DIR, 'test_files_for_genabout/') test_fields = [{'about_file': '/about.py.ABOUT', 'version': '0.8.1', 'about_resource': '.', 'name': 'ABOUT tool', - 'license_text_file': '../../../../apache-2.0.LICENSE'}] + 'license_text_file': 'apache-2.0.LICENSE'}] result = gen.get_dje_license_list(gen_location=gen_location, input_list=test_fields, gen_license=False, @@ -316,14 +301,13 @@ def test_get_dje_license_list_file_no_gen_license_with_license_text_file_key_exi def test_get_dje_license_list_dir_no_gen_license_with_license_text_file_key_exist(self): gen = genabout.GenAbout() - # FIXME: this is using the about own license, not a test file gen_location = join(TESTDATA_DIR, 'test_files_for_genabout/') test_fields = [{'about_file': '/ABOUT/', 'version': '0.8.1', 'about_resource': '.', 'name': 'ABOUT tool', 'license_text_file': - '../../../../../apache-2.0.LICENSE'}] + '../apache-2.0.LICENSE'}] expected = [] result = gen.get_dje_license_list(gen_location, test_fields, @@ -372,10 +356,8 @@ def test_get_dje_license_list_gen_license_with_dje_license_key_empty_license_tex gen_license, dje_license_dict) - # FIXME: not why a loop is needed asserting on actual test data? - for field in test_fields: - self.assertEqual(field['license_text_file'], - 'apache-2.0.LICENSE') + self.assertEqual(test_fields[0]['license_text_file'], + 'apache-2.0.LICENSE') expected = [('/', 'Apache License 2.0')] self.assertEqual(expected, result) @@ -532,6 +514,21 @@ def test_pre_generation_about_exists_action_3(self): self.assertFalse(gen.warnings, 'No warnings should be returned.') self.assertFalse(gen.errors, 'No errors should be returned.') + def test_pre_generation_dir_endswith_space(self): + gen = genabout.GenAbout() + test_fields = [{'about_file': '/abc /about.py.ABOUT', + 'version': '0.8.2', + 'about_resource': '.', + 'name': '', + 'test': 'test sample'}] + + result = gen.pre_generation(GEN_LOCATION, + test_fields, + action_num=0) + + self.assertTrue(len(gen.errors) == 1, 'Should return 1 error.') + self.assertTrue(gen.errors, 'It should prompt error because directory ends with sapce') + def test_format_output(self): gen = genabout.GenAbout() test_fields = [ @@ -550,15 +547,13 @@ def test_format_output(self): def test_format_output_with_continuation(self): gen = genabout.GenAbout() - test_fields = [[join(TESTDATA_DIR, - 'test_files_for_genabout/about.py.ABOUT'), + test_fields = [[join(TESTDATA_DIR, 'test_files_for_genabout/about.py.ABOUT'), {'about_file': '/about.py.ABOUT', 'version': '0.8.1', 'about_resource': '.', 'name': 'ABOUT Tool', 'readme': 'This is a readme test with \nline continuation.'}]] - expected = [[join(TESTDATA_DIR, - 'test_files_for_genabout/about.py.ABOUT'), + expected = [[join(TESTDATA_DIR, 'test_files_for_genabout/about.py.ABOUT'), 'about_resource: .\nname: ABOUT Tool\n' 'version: 0.8.1\n\n' 'readme: This is a readme test with \n line continuation.\n']] @@ -569,15 +564,15 @@ def test_format_output_with_continuation(self): def test_verify_files_existence_exist(self): gen = genabout.GenAbout() - # FIXME: this is using the files at the root, not testfiles + gen_location = join(TESTDATA_DIR, 'test_files_for_genabout/') test_fields = [{'version': '0.8.1', 'about_file': '/TESTCASE/', 'license_text_file': 'apache-2.0.LICENSE', 'name': 'ABOUT tool', 'about_resource': '.'}] - expected = [(join('.', 'apache-2.0.LICENSE'), 'TESTCASE')] + expected = [(join(gen_location, 'apache-2.0.LICENSE'), 'TESTCASE')] result = gen.verify_files_existence(input_list=test_fields, - project_dir='.', + project_dir=gen_location, file_in_project=False) self.assertEqual(expected, result) self.assertFalse(gen.warnings, 'No warnings should be returned.') @@ -585,15 +580,15 @@ def test_verify_files_existence_exist(self): def test_verify_files_existence_exist_license_in_project(self): gen = genabout.GenAbout() - # FIXME: this is using the files at the root, not testfiles + gen_location = join(TESTDATA_DIR, 'test_files_for_genabout/') test_fields = [{'version': '0.8.1', 'about_file': '.', 'license_text_file': 'apache-2.0.LICENSE', 'name': 'ABOUT tool', 'about_resource': '.'}] - expected = [(join('.', 'apache-2.0.LICENSE'), '')] + expected = [(join(gen_location, 'apache-2.0.LICENSE'), '')] result = gen.verify_files_existence(input_list=test_fields, - project_dir='.', + project_dir=gen_location, file_in_project=True) self.assertEqual(expected, result) self.assertFalse(gen.warnings, 'No warnings should be returned.') @@ -666,20 +661,18 @@ def test_gen_license_list_no_license_text_file_key(self): self.assertEqual(expected, result) def test_copy_files_test_path_not_endswith_slash(self): - # FIXME: this is using the files at the root, not testfiles gen = genabout.GenAbout() - test = [('apache-2.0.LICENSE', '.')] - test_dir = test_about.get_temp_dir() + test = [(join(TESTDATA_DIR, 'test_files_for_genabout/apache-2.0.LICENSE'), '.')] + test_dir = get_temp_dir() gen.copy_files(test_dir, test) expected = ['apache-2.0.LICENSE'] self.assertEqual(expected, os.listdir(test_dir)) def test_copy_files_test_path_endswith_slash(self): gen = genabout.GenAbout() - # FIXME: this is using the files at the root, not testfiles - test = [('apache-2.0.LICENSE', '.')] + test = [(join(TESTDATA_DIR, 'test_files_for_genabout/apache-2.0.LICENSE'), '.')] expected = ['apache-2.0.LICENSE'] - test_dir = test_about.get_temp_dir() + '/' + test_dir = get_temp_dir() + '/' gen.copy_files(test_dir, test) self.assertEqual(expected, os.listdir(test_dir)) @@ -695,15 +688,11 @@ def test_write_licenses(self): def test_process_dje_licenses(self): gen = genabout.GenAbout() test_license_list = [('/', 'test')] - test_license_dict = {'test': [u'test_key', - u'This is a test license.']} + test_license_dict = {'test': [u'test_key', u'This is a test license.']} test_path = '/test' - expected = [[join(u'/test', 'test_key.LICENSE'), - 'This is a test license.']] - result = gen.process_dje_licenses(test_license_list, - test_license_dict, - test_path) - self.assertEqual(result, expected) + expected = [[join(u'/test', 'test_key.LICENSE'), 'This is a test license.']] + result = gen.process_dje_licenses(test_license_list, test_license_dict, test_path) + self.assertEqual(expected, result) def test_update_about_resource_about_file_and_field_exist(self): gen = genabout.GenAbout() @@ -738,10 +727,11 @@ def test_update_about_resource_no_about_file_field_exist(self): gen = genabout.GenAbout() test_fields = {'about_resource': 'test.c', 'about_file': '/tmp/test.c'} + expected_fields = {'about_resource': 'test.c', + 'about_file': '/tmp/test.c'} about_file_exist = False gen.update_about_resource(test_fields, about_file_exist) - # FIXME: this will always be true: the test is incorrect - self.assertTrue(test_fields == test_fields, 'The dict should not be changed.') + self.assertTrue(test_fields == expected_fields, 'The dict should not be changed.') def test_update_about_resource_no_about_file_no_field_isFile(self): gen = genabout.GenAbout() diff --git a/about_code_tool/tests/test_genattrib.py b/about_code_tool/tests/test_genattrib.py index 575e1101..29d01b7d 100644 --- a/about_code_tool/tests/test_genattrib.py +++ b/about_code_tool/tests/test_genattrib.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2013-2016 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 @@ -21,51 +21,176 @@ from about_code_tool import genattrib +from about_code_tool.tests.test_about import get_temp_file +from about_code_tool.util import add_unc + TESTS_DIR = os.path.abspath(os.path.dirname(__file__)) TESTDATA_DIR = os.path.join(TESTS_DIR, 'testdata') GEN_LOCATION = os.path.join(TESTDATA_DIR, 'test_files_for_genabout') +def check_about_file_existence_and_format(input_list): + try: + for row in input_list: + # Force the path to start with the '/' to map with the project + # structure + if not row['about_file'].startswith('/'): + row['about_file'] = '/' + row['about_file'] + return input_list + except Exception: + return [] + class GenAttribTest(unittest.TestCase): def test_convert_dict_key_to_lower_case(self): - test = [{'Directory': '/test/', 'file_name': 'test.c'}] - expected = [{'directory': '/test/', 'file_name': 'test.c'}] - result = genattrib.convert_dict_key_to_lower_case(test) + test = [{'Directory': '/Test/', 'filE_name': 'tesT.c'}] + expected = [{'directory': '/Test/', 'file_name': 'tesT.c'}] + result = genattrib.lower_keys(test) self.assertEqual(expected, result) - def test_check_no_about_file_existence(self): + def test_has_about_file_keys(self): test = [{'Directory': '/test/', 'file_name': '/test.c'}] - result = genattrib.check_about_file_existence_and_format(test) + result = genattrib.has_about_file_keys(test) self.assertFalse(result) - def test_check_have_about_file_existence(self): + def test_normalize_about_file_paths(self): test = [{'Directory': '/test/', 'about_file': '/test.ABOUT'}] - result = genattrib.check_about_file_existence_and_format(test) + result = genattrib.normalize_about_file_paths(test) self.assertEqual(test, result) - def test_check_no_about_file_not_start_with_slash(self): + def test_normalize_about_file_paths_does_not_change_other_paths(self): test = [{'Directory': '/test/', 'file_name': 'test.c'}] - result = genattrib.check_about_file_existence_and_format(test) - self.assertFalse(result) + result = genattrib.normalize_about_file_paths(test) + self.assertEqual(test, result) - def test_check_have_about_file_not_start_with_slash(self): + def test_normalize_about_file_paths_updates_about_file_paths(self): test = [{'Directory': '/test/', 'about_file': 'test.ABOUT'}] expected = [{'Directory': '/test/', 'about_file': '/test.ABOUT'}] - result = genattrib.check_about_file_existence_and_format(test) + result = genattrib.normalize_about_file_paths(test) self.assertEqual(expected, result) - def test_update_path_to_about(self): - test = ['/test/test1.ABOUT', '/test/test2/', 'test/test3.c'] - expected = ['/test/test1.ABOUT', - '/test/test2/test2.ABOUT', - 'test/test3.c.ABOUT'] - result = genattrib.update_path_to_about(test) + def test_as_about_paths(self): + test = [ + '/test/test1.ABOUT', + '/test/test2/', + 'test/test3.c' + ] + expected = [ + '/test/test1.ABOUT', + '/test/test2/test2.ABOUT', + 'test/test3.c.ABOUT' + ] + result = genattrib.as_about_paths(test) self.assertEqual(expected, result) - def test_component_subset_to_sublist(self): + def test_get_about_file_paths(self): test = [{'about_file': '/tmp/', 'notes': 'test'}, {'about_file': '/tmp/t1/', 'dje_license': 'bsd-new'}] expected = ['/tmp/', '/tmp/t1/'] - result = genattrib.component_subset_to_sublist(test) + result = genattrib.get_about_file_paths(test) self.assertEqual(expected, result) + + def test_genattrib_basic(self): + self.maxDiff = None + about_dir = 'about_code_tool/tests/testdata/genattrib/basic/' + generated_attrib = get_temp_file('generated.html') + args = [about_dir, generated_attrib] + options = None + genattrib_command_tester(args, options) + result = open(generated_attrib).read() + expected = [ + 'ElasticSearch 1.6.0', + 'bootstrap 2.3.2', + 'djangosnippets.org_2413 2011-04-12', + 'Annotator 1.2.10', + 'component_4', + ] + for ex in expected: + self.assertTrue(ex in result) + + def test_genattrib_basic_with_filter(self): + self.maxDiff = None + # note: this contains an about_files subdir that is the root of all ABOUT files in the "project" + about_dir = 'about_code_tool/tests/testdata/genattrib/project' + generated_attrib = get_temp_file('generated.html') + # note: all the about_fioles columns are paths starting with /about_files + filter_csv = 'about_code_tool/tests/testdata/genattrib/project_filter.csv' + args = [about_dir, generated_attrib, filter_csv] + options = None + genattrib_command_tester(args, options) + result = open(generated_attrib).read() + expected = [ + 'ElasticSearch 1.6.0', + 'bootstrap 2.3.2', + ] + for ex in expected: + self.assertTrue(ex in result, ex) + + not_expected = [ + 'Annotator 1.2.10', + 'component_4', + 'djangosnippets.org_2413 2011-04-12', + ] + for ex in not_expected: + self.assertFalse(ex in result, ex) + + def test_genattrib_from_zipped_dir(self): + self.maxDiff = None + about_dir = 'about_code_tool/tests/testdata/genattrib/zipped_about.zip' + generated_attrib = get_temp_file('generated.html') + args = [about_dir, generated_attrib] + options = None + genattrib_command_tester(args, options) + result = open(generated_attrib).read() + expected = [ + 'ElasticSearch 1.6.0', + 'bootstrap 2.3.2', + 'djangosnippets.org_2413 2011-04-12', + 'Annotator 1.2.10', + 'python-memcached 1.53', + 'component_94', + 'Groovy 2.4.0', + ] + for ex in expected: + self.assertTrue(ex in result, ex) + + def test_genattrib_zip_with_filter(self): + self.maxDiff = None + # note: this contains an about_files subdir that is the root of all ABOUT files in the "project" + about_dir = 'about_code_tool/tests/testdata/genattrib/about_files.zip' + generated_attrib = get_temp_file('generated.html') + # note: all the about_files columns are paths starting with /about_files + filter_csv = 'about_code_tool/tests/testdata/genattrib/project_filter.csv' + args = [about_dir, generated_attrib, filter_csv] + options = None + genattrib_command_tester(args, options) + result = open(generated_attrib).read() + expected = [ + 'ElasticSearch 1.6.0', + 'bootstrap 2.3.2', + ] + for ex in expected: + self.assertTrue(ex in result, ex) + + not_expected = [ + 'Annotator 1.2.10', + 'component_4', + 'djangosnippets.org_2413 2011-04-12', + ] + for ex in not_expected: + self.assertFalse(ex in result, ex) + + def test_extract_deep_zip(self): + test_zip = 'about_code_tool/tests/testdata/longpath/longpath.zip' + extracted = genattrib.extract_zip(test_zip) + unc_extracted = add_unc(extracted) + all_files = set() + for _, _, files in os.walk(unc_extracted): + all_files.update(files) + self.assertTrue('non-supported_date_format.ABOUT' in all_files) + + +def genattrib_command_tester(args, options): + parser = genattrib.get_parser() + options, args = parser.parse_args(args, options) + genattrib.main(parser, options, args) diff --git a/about_code_tool/tests/test_tstutil.py b/about_code_tool/tests/test_tstutil.py new file mode 100644 index 00000000..8757fefd --- /dev/null +++ b/about_code_tool/tests/test_tstutil.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +# ============================================================================ +# Copyright (c) 2013-2016 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 +# 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. +# ============================================================================ + +from __future__ import print_function + +import unittest + +from about_code_tool import util + + +class UtilTest(unittest.TestCase): + + def test_get_mappings(self): + expected = { + 'name': 'component', + 'copyright': 'confirmed copyright', + 'confirmed_license': 'confirmed license', + 'version': 'confirmed version', + 'about_file': 'directory/filename' + } + + result = util.get_mappings() + self.assertEqual(expected, result) + + def test_apply_mappings(self): + mappings = { + 'about_file': 'Directory/Filename', + 'version': 'Confirmed Version', + 'about_resource': 'file_name', + 'name': 'Component' + } + + test_fields = [ + { + 'file_name': 'opensans', + 'ignore field': 'i', + 'Component': 'OpenSans Fonts', + 'Confirmed Version': '1', + 'Directory/Filename': '/extension/streamer/opensans/', + } + ] + + expected = [ + { + 'about_resource': 'opensans', + 'ignore field': 'i', + 'name': 'OpenSans Fonts', + 'version': '1', + 'about_file': '/extension/streamer/opensans/', + } + ] + + result = util.apply_mappings(test_fields, mappings) + self.assertEqual(expected, result) + + def test_apply_mappings_same_name(self): + mappings = { + 'about_file': 'Directory/Filename', + 'version': 'Confirmed Version', + 'about_resource': 'file_name', + 'name': 'Component', + 'component' : 'Component' + } + + test_fields = [ + { + 'file_name': 'opensans', + 'ignore field': 'i', + 'Component': 'OpenSans Fonts', + 'Confirmed Version': '1', + 'Directory/Filename': '/extension/streamer/opensans/', + } + ] + + expected = [ + { + 'about_resource': 'opensans', + 'ignore field': 'i', + 'name': 'OpenSans Fonts', + 'version': '1', + 'about_file': '/extension/streamer/opensans/', + 'component': 'OpenSans Fonts', + } + ] + + result = util.apply_mappings(test_fields, mappings) + self.assertEqual(expected, result) + + def test_util_resource_name(self): + expected = 'first' + result = util.resource_name('some/things/first') + self.assertEqual(expected, result) + + def test_util_resource_name1(self): + expected = 'first' + result = util.resource_name('some/things/first/') + self.assertEqual(expected, result) + + def test_util_resource_name2(self): + expected = r'things\first' + result = util.resource_name(r'c:\some/things\first') + self.assertEqual(expected, result) + + def test_util_resource_name3(self): + expected = 'first' + result = util.resource_name(r'some\thi ngs//first') + self.assertEqual(expected, result) + + def test_util_resource_name4(self): + expected = r'\\' + result = util.resource_name(r'%6571351()275612$/_$asafg:/\\') + self.assertEqual(expected, result) + + def test_util_resource_name5(self): + expected = '_$asafg:' + result = util.resource_name('%6571351()2/75612$/_$asafg:') + self.assertEqual(expected, result) + + def test_util_resource_name_does_not_recurse_infinitely(self): + expected = '' + result = util.resource_name('/') + self.assertEqual(expected, result) + + def test_util_resource_name_does_not_recurse_infinitely2(self): + expected = '' + result = util.resource_name('/ / ') + self.assertEqual(expected, result) + + def test_util_resource_name_does_not_recurse_infinitely3(self): + expected = '' + result = util.resource_name(' / ') + self.assertEqual(expected, result) diff --git a/about_code_tool/tests/testdata/genattrib/about_files.zip b/about_code_tool/tests/testdata/genattrib/about_files.zip new file mode 100644 index 00000000..802d0f8c Binary files /dev/null and b/about_code_tool/tests/testdata/genattrib/about_files.zip differ diff --git a/about_code_tool/tests/testdata/genattrib/basic/bootstrap.ABOUT b/about_code_tool/tests/testdata/genattrib/basic/bootstrap.ABOUT new file mode 100644 index 00000000..a298cf5d --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/bootstrap.ABOUT @@ -0,0 +1,16 @@ +about_resource: bootstrap-2.3.2.zip +download_url: https://github.com/twbs/bootstrap/archive/v2.3.2.zip +version: 2.3.2 + +name: bootstrap +home_url: http://twitter.github.com/bootstrap/ +owner: Twitter, Inc. + +description: Sleek, intuitive, and powerful front-end framework for faster and easier web development. +dje_license: apache-2.0 +license_text_file: bootstrap.LICENSE +copyright: Copyright 2012 Twitter, Inc. + +vcs_tool: git +vcs_repository: https://github.com/twitter/bootstrap.git +vcs_branch: /tree/v2.3.2 diff --git a/about_code_tool/tests/testdata/genattrib/basic/bootstrap.LICENSE b/about_code_tool/tests/testdata/genattrib/basic/bootstrap.LICENSE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/bootstrap.LICENSE @@ -0,0 +1,176 @@ + 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/about_code_tool/tests/testdata/genattrib/basic/django_snippets.LICENSE b/about_code_tool/tests/testdata/genattrib/basic/django_snippets.LICENSE new file mode 100644 index 00000000..01b3fadf --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/django_snippets.LICENSE @@ -0,0 +1,9 @@ +Terms of Service +We hate legal-speak as much as anybody, but on a site which is geared toward sharing code there has to be at least a little bit of it, so here goes: + +By creating an account here you agree to three things: + +That you will only post code which you wrote yourself and that you have the legal right to release under these terms. +That you grant any third party who sees the code you post a royalty-free, non-exclusive license to copy and distribute that code and to make and distribute derivative works based on that code. You may include license terms in snippets you post, if you wish to use a particular license (such as the BSD license or GNU GPL), but that license must permit royalty-free copying, distribution and modification of the code to which it is applied. +That if you post code of which you are not the author or for which you do not have the legal right to distribute according to these terms, you will indemnify and hold harmless the operators of this site and any third parties who are exposed to liability as a result of your actions. +If you can't legally agree to these terms, or don't want to, you cannot create an account here. \ No newline at end of file diff --git a/about_code_tool/tests/testdata/genattrib/basic/django_snippets_2413.ABOUT b/about_code_tool/tests/testdata/genattrib/basic/django_snippets_2413.ABOUT new file mode 100644 index 00000000..f1018a04 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/django_snippets_2413.ABOUT @@ -0,0 +1,14 @@ +about_resource: django_snippets_2413.py +version: 2011-04-12 +download_url: http://djangosnippets.org/snippets/2413/download/ + +name: djangosnippets.org_2413 +home_url: http://djangosnippets.org/snippets/2413/ + +license_url: http://djangosnippets.org/about/tos/ +license_text_file: django_snippets.LICENSE +dje_license: mit +notes: The http://djangosnippets.org/ notice gives us permission to use the + stuff under just about any open source license, we assert MIT for them. + This file was modified to include the line "register = Library()" + without which the template tag is not registered. \ No newline at end of file diff --git a/about_code_tool/tests/testdata/genattrib/basic/elasticsearch-sources.ABOUT b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch-sources.ABOUT new file mode 100644 index 00000000..1ede24c4 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch-sources.ABOUT @@ -0,0 +1,19 @@ +about_resource: elasticsearch-1.6.0-src.tar.xz +download_url: https://github.com/elasticsearch/elasticsearch/archive/v1.6.0.tar.gz +version: 1.6.0 + +owner: ElasticSearch and Shay Banon +name: ElasticSearch + +home_url: http://www.elasticsearch.org/ + +vcs_tool: git +vcs_repository: https://github.com/elasticsearch/elasticsearch.git + +dje_license: apache-2.0 +notice_file: elasticsearch.NOTICE +license_text_file: elasticsearch.LICENSE +copyright: Copyright 2009-2014 Elasticsearch + +notes: Source code for the pre-built binaries we use, pruned from docs and + tests to keep the size small enough. diff --git a/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.ABOUT b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.ABOUT new file mode 100644 index 00000000..8e94018a --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.ABOUT @@ -0,0 +1,22 @@ +about_resource: elasticsearch-1.6.0.zip +download_url: https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.6.0.zip +version: 1.6.0 + +owner: ElasticSearch and Shay Banon +name: ElasticSearch + +home_url: http://www.elasticsearch.org/ + +vcs_tool: git +vcs_repository: https://github.com/elasticsearch/elasticsearch.git + +dje_license: apache-2.0 +notice_file: elasticsearch.NOTICE +license_text_file: elasticsearch.LICENSE +copyright: Copyright 2009-2015 Elasticsearch + +notes: This a prebuilt version working on all OSes. + The tar.gz works only with POSIX OSses and not Windows while the zip works on + all OS. See https://github.com/elasticsearch/elasticsearch/pull/2793 + ES contains a prebuilt binary of Apache-licensed Hyperic Sigar, Apache Lucene + and Apache Log4J as well as JNA which is LGPL-licensed. diff --git a/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.LICENSE b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.LICENSE @@ -0,0 +1,202 @@ + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.NOTICE b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.NOTICE new file mode 100644 index 00000000..23cae9e2 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/elasticsearch.NOTICE @@ -0,0 +1,5 @@ +Elasticsearch +Copyright 2009-2015 Elasticsearch + +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). diff --git a/about_code_tool/tests/testdata/genattrib/basic/subdir/annotator.ABOUT b/about_code_tool/tests/testdata/genattrib/basic/subdir/annotator.ABOUT new file mode 100644 index 00000000..0a08ed9f --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/subdir/annotator.ABOUT @@ -0,0 +1,14 @@ +about_resource: annotator-full.1.2.10.zip +download_url: https://github.com/openannotation/annotator/releases/download/v1.2.10/annotator-full.1.2.10.zip +version: 1.2.10 + +home_url: http://okfnlabs.org/projects/annotator/ +name: Annotator +owner: Open Knowledge + +license_text_file: annotator.LICENSE +license_url: https://okfn.org/ip-policy/ +dje_license: mit + +vcs_tool: git +vcs_repository: https://github.com/openannotation/annotator.git diff --git a/about_code_tool/tests/testdata/genattrib/basic/subdir/annotator.LICENSE b/about_code_tool/tests/testdata/genattrib/basic/subdir/annotator.LICENSE new file mode 100644 index 00000000..05ce546a --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/basic/subdir/annotator.LICENSE @@ -0,0 +1,25 @@ +# Annotator licensing terms + +Annotator is free software, and you may use it under the terms of either the +MIT or the GNU GPL licenses: + +## GNU GPLv3 + +You can redistribute this program and/or modify it under the terms of the +GNU General Public License as published by the Free Software Foundation, +either version 3 of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. See LICENSE-GPL, or, if this file is missing, +. + +## MIT + +You may use the software under the terms of the MIT license, which can be +found in LICENSE-MIT, or, if this file is missing, +. diff --git a/about_code_tool/tests/testdata/genattrib/filter_list.csv b/about_code_tool/tests/testdata/genattrib/filter_list.csv new file mode 100644 index 00000000..bbbc6533 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/filter_list.csv @@ -0,0 +1,3 @@ +about_file,name,version,about_resource,spec_version,date,description,description_file,home_url,download_url,readme,readme_file,install,install_file,changelog,changelog_file,news,news_file,news_url,notes,notes_file,contact,owner,author,author_file,copyright,copyright_file,notice_file,notice_url,license_text_file,license_url,license_spdx,redistribute,attribute,track_changes,vcs_tool,vcs_repository,vcs_path,vcs_tag,vcs_branch,vcs_revision,checksum_sha1,checksum_md5,checksum_sha256,dje_component,dje_license_key,dje_organization,dje_license_name,dje_license,notice,license_text,warnings,errors +/thirdparty/annotator.ABOUT,Annotator,1.2.10,annotator-full.1.2.10.zip,,,,,http://okfnlabs.org/projects/annotator/,https://github.com/openannotation/annotator/releases/download/v1.2.10/annotator-full.1.2.10.zip,,,,,,,,,,,,,Open Knowledge,,,,,,,annotator.LICENSE,https://okfn.org/ip-policy/,,,,,git,https://github.com/openannotation/annotator.git,,,,,,,,,,,,mit,,,,"Field: about_resource, Value: annotator-full.1.2.10.zip, Message: File does not exist." +/thirdparty/bootstrap.ABOUT,bootstrap,2.3.2,bootstrap-2.3.2.zip,,,"Sleek, intuitive, and powerful front-end framework for faster and easier web development.",,http://twitter.github.com/bootstrap/,https://github.com/twbs/bootstrap/archive/v2.3.2.zip,,,,,,,,,,,,,"Twitter, Inc.",,,"Copyright 2012 Twitter, Inc.",,,,bootstrap.LICENSE,,,,,,git,https://github.com/twitter/bootstrap.git,,,/tree/v2.3.2,,,,,,,,,apache-2.0,,,,"Field: about_resource, Value: bootstrap-2.3.2.zip, Message: File does not exist." diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/bootstrap.ABOUT b/about_code_tool/tests/testdata/genattrib/project/about_files/bootstrap.ABOUT new file mode 100644 index 00000000..a298cf5d --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/bootstrap.ABOUT @@ -0,0 +1,16 @@ +about_resource: bootstrap-2.3.2.zip +download_url: https://github.com/twbs/bootstrap/archive/v2.3.2.zip +version: 2.3.2 + +name: bootstrap +home_url: http://twitter.github.com/bootstrap/ +owner: Twitter, Inc. + +description: Sleek, intuitive, and powerful front-end framework for faster and easier web development. +dje_license: apache-2.0 +license_text_file: bootstrap.LICENSE +copyright: Copyright 2012 Twitter, Inc. + +vcs_tool: git +vcs_repository: https://github.com/twitter/bootstrap.git +vcs_branch: /tree/v2.3.2 diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/bootstrap.LICENSE b/about_code_tool/tests/testdata/genattrib/project/about_files/bootstrap.LICENSE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/bootstrap.LICENSE @@ -0,0 +1,176 @@ + 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/about_code_tool/tests/testdata/genattrib/project/about_files/django_snippets.LICENSE b/about_code_tool/tests/testdata/genattrib/project/about_files/django_snippets.LICENSE new file mode 100644 index 00000000..01b3fadf --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/django_snippets.LICENSE @@ -0,0 +1,9 @@ +Terms of Service +We hate legal-speak as much as anybody, but on a site which is geared toward sharing code there has to be at least a little bit of it, so here goes: + +By creating an account here you agree to three things: + +That you will only post code which you wrote yourself and that you have the legal right to release under these terms. +That you grant any third party who sees the code you post a royalty-free, non-exclusive license to copy and distribute that code and to make and distribute derivative works based on that code. You may include license terms in snippets you post, if you wish to use a particular license (such as the BSD license or GNU GPL), but that license must permit royalty-free copying, distribution and modification of the code to which it is applied. +That if you post code of which you are not the author or for which you do not have the legal right to distribute according to these terms, you will indemnify and hold harmless the operators of this site and any third parties who are exposed to liability as a result of your actions. +If you can't legally agree to these terms, or don't want to, you cannot create an account here. \ No newline at end of file diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/django_snippets_2413.ABOUT b/about_code_tool/tests/testdata/genattrib/project/about_files/django_snippets_2413.ABOUT new file mode 100644 index 00000000..f1018a04 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/django_snippets_2413.ABOUT @@ -0,0 +1,14 @@ +about_resource: django_snippets_2413.py +version: 2011-04-12 +download_url: http://djangosnippets.org/snippets/2413/download/ + +name: djangosnippets.org_2413 +home_url: http://djangosnippets.org/snippets/2413/ + +license_url: http://djangosnippets.org/about/tos/ +license_text_file: django_snippets.LICENSE +dje_license: mit +notes: The http://djangosnippets.org/ notice gives us permission to use the + stuff under just about any open source license, we assert MIT for them. + This file was modified to include the line "register = Library()" + without which the template tag is not registered. \ No newline at end of file diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch-sources.ABOUT b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch-sources.ABOUT new file mode 100644 index 00000000..1ede24c4 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch-sources.ABOUT @@ -0,0 +1,19 @@ +about_resource: elasticsearch-1.6.0-src.tar.xz +download_url: https://github.com/elasticsearch/elasticsearch/archive/v1.6.0.tar.gz +version: 1.6.0 + +owner: ElasticSearch and Shay Banon +name: ElasticSearch + +home_url: http://www.elasticsearch.org/ + +vcs_tool: git +vcs_repository: https://github.com/elasticsearch/elasticsearch.git + +dje_license: apache-2.0 +notice_file: elasticsearch.NOTICE +license_text_file: elasticsearch.LICENSE +copyright: Copyright 2009-2014 Elasticsearch + +notes: Source code for the pre-built binaries we use, pruned from docs and + tests to keep the size small enough. diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.ABOUT b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.ABOUT new file mode 100644 index 00000000..8e94018a --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.ABOUT @@ -0,0 +1,22 @@ +about_resource: elasticsearch-1.6.0.zip +download_url: https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.6.0.zip +version: 1.6.0 + +owner: ElasticSearch and Shay Banon +name: ElasticSearch + +home_url: http://www.elasticsearch.org/ + +vcs_tool: git +vcs_repository: https://github.com/elasticsearch/elasticsearch.git + +dje_license: apache-2.0 +notice_file: elasticsearch.NOTICE +license_text_file: elasticsearch.LICENSE +copyright: Copyright 2009-2015 Elasticsearch + +notes: This a prebuilt version working on all OSes. + The tar.gz works only with POSIX OSses and not Windows while the zip works on + all OS. See https://github.com/elasticsearch/elasticsearch/pull/2793 + ES contains a prebuilt binary of Apache-licensed Hyperic Sigar, Apache Lucene + and Apache Log4J as well as JNA which is LGPL-licensed. diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.LICENSE b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.LICENSE @@ -0,0 +1,202 @@ + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.NOTICE b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.NOTICE new file mode 100644 index 00000000..23cae9e2 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/elasticsearch.NOTICE @@ -0,0 +1,5 @@ +Elasticsearch +Copyright 2009-2015 Elasticsearch + +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/subdir/annotator.ABOUT b/about_code_tool/tests/testdata/genattrib/project/about_files/subdir/annotator.ABOUT new file mode 100644 index 00000000..0a08ed9f --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/subdir/annotator.ABOUT @@ -0,0 +1,14 @@ +about_resource: annotator-full.1.2.10.zip +download_url: https://github.com/openannotation/annotator/releases/download/v1.2.10/annotator-full.1.2.10.zip +version: 1.2.10 + +home_url: http://okfnlabs.org/projects/annotator/ +name: Annotator +owner: Open Knowledge + +license_text_file: annotator.LICENSE +license_url: https://okfn.org/ip-policy/ +dje_license: mit + +vcs_tool: git +vcs_repository: https://github.com/openannotation/annotator.git diff --git a/about_code_tool/tests/testdata/genattrib/project/about_files/subdir/annotator.LICENSE b/about_code_tool/tests/testdata/genattrib/project/about_files/subdir/annotator.LICENSE new file mode 100644 index 00000000..05ce546a --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project/about_files/subdir/annotator.LICENSE @@ -0,0 +1,25 @@ +# Annotator licensing terms + +Annotator is free software, and you may use it under the terms of either the +MIT or the GNU GPL licenses: + +## GNU GPLv3 + +You can redistribute this program and/or modify it under the terms of the +GNU General Public License as published by the Free Software Foundation, +either version 3 of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. See LICENSE-GPL, or, if this file is missing, +. + +## MIT + +You may use the software under the terms of the MIT license, which can be +found in LICENSE-MIT, or, if this file is missing, +. diff --git a/about_code_tool/tests/testdata/genattrib/project_filter.csv b/about_code_tool/tests/testdata/genattrib/project_filter.csv new file mode 100644 index 00000000..fb5a1cd6 --- /dev/null +++ b/about_code_tool/tests/testdata/genattrib/project_filter.csv @@ -0,0 +1,9 @@ +"about_file","name","version","about_resource","spec_version","date","description","description_file","home_url","download_url","readme","readme_file","install","install_file","changelog","changelog_file","news","news_file","news_url","notes","notes_file","contact","owner","author","author_file","copyright","copyright_file","notice_file","notice_url","license_text_file","license_url","license_spdx","redistribute","attribute","track_changes","vcs_tool","vcs_repository","vcs_path","vcs_tag","vcs_branch","vcs_revision","checksum_sha1","checksum_md5","checksum_sha256","dje_component","dje_license_key","dje_organization","dje_license_name","dje_license","warnings","errors" +"/about_files/elasticsearch-sources.ABOUT","ElasticSearch","1.6.0","elasticsearch-1.6.0-src.tar.xz",,,,,"http://www.elasticsearch.org/","https://github.com/elasticsearch/elasticsearch/archive/v1.6.0.tar.gz",,,,,,,,,,"Source code for the pre-built binaries we use, pruned from docs and +tests to keep the size small enough.",,,"ElasticSearch and Shay Banon",,,"Copyright 2009-2014 Elasticsearch",,"elasticsearch.NOTICE",,"elasticsearch.LICENSE",,,,,,"git","https://github.com/elasticsearch/elasticsearch.git",,,,,,,,,,,,"apache-2.0",,"Field: about_resource, Value: elasticsearch-1.6.0-src.tar.xz, Message: File does not exist." +"/about_files/bootstrap.ABOUT","bootstrap","2.3.2","bootstrap-2.3.2.zip",,,"Sleek, intuitive, and powerful front-end framework for faster and easier web development.",,"http://twitter.github.com/bootstrap/","https://github.com/twbs/bootstrap/archive/v2.3.2.zip",,,,,,,,,,,,,"Twitter, Inc.",,,"Copyright 2012 Twitter, Inc.",,,,"bootstrap.LICENSE",,,,,,"git","https://github.com/twitter/bootstrap.git",,,"/tree/v2.3.2",,,,,,,,,"apache-2.0",,"Field: about_resource, Value: bootstrap-2.3.2.zip, Message: File does not exist." +"/about_files/elasticsearch.ABOUT","ElasticSearch","1.6.0","elasticsearch-1.6.0.zip",,,,,"http://www.elasticsearch.org/","https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.6.0.zip",,,,,,,,,,"This a prebuilt version working on all OSes. +The tar.gz works only with POSIX OSses and not Windows while the zip works on +all OS. See https://github.com/elasticsearch/elasticsearch/pull/2793 +ES contains a prebuilt binary of Apache-licensed Hyperic Sigar, Apache Lucene +and Apache Log4J as well as JNA which is LGPL-licensed.",,,"ElasticSearch and Shay Banon",,,"Copyright 2009-2015 Elasticsearch",,"elasticsearch.NOTICE",,"elasticsearch.LICENSE",,,,,,"git","https://github.com/elasticsearch/elasticsearch.git",,,,,,,,,,,,"apache-2.0",,"Field: about_resource, Value: elasticsearch-1.6.0.zip, Message: File does not exist." diff --git a/about_code_tool/tests/testdata/genattrib/zipped_about.zip b/about_code_tool/tests/testdata/genattrib/zipped_about.zip new file mode 100644 index 00000000..3af0df7e Binary files /dev/null and b/about_code_tool/tests/testdata/genattrib/zipped_about.zip differ diff --git a/about_code_tool/tests/testdata/longpath/longpath.zip b/about_code_tool/tests/testdata/longpath/longpath.zip new file mode 100644 index 00000000..d132a38b Binary files /dev/null and b/about_code_tool/tests/testdata/longpath/longpath.zip differ diff --git a/about_code_tool/tests/testdata/parser_tests/missing_mand.ABOUT b/about_code_tool/tests/testdata/parser_tests/missing_mand.ABOUT index 7d9a52d2..867ecc64 100644 --- a/about_code_tool/tests/testdata/parser_tests/missing_mand.ABOUT +++ b/about_code_tool/tests/testdata/parser_tests/missing_mand.ABOUT @@ -1,6 +1,4 @@ download_url: http://archive.apache.org/dist/httpd/httpd-2.4.3.tar.gz date: 2012-08-21 license_spdx: Apache-2.0 -license_text_file: httpd.LICENSE -copyright: Copyright 2012 The Apache Software Foundation. -notice_file: httpd.NOTICE \ No newline at end of file +copyright: Copyright 2012 The Apache Software Foundation. \ No newline at end of file diff --git a/about_code_tool/tests/testdata/parser_tests/missing_mand_values.ABOUT b/about_code_tool/tests/testdata/parser_tests/missing_mand_values.ABOUT index 16e591ea..d2e6dc97 100644 --- a/about_code_tool/tests/testdata/parser_tests/missing_mand_values.ABOUT +++ b/about_code_tool/tests/testdata/parser_tests/missing_mand_values.ABOUT @@ -1,9 +1,6 @@ name: -about_resource: download_url: http://archive.apache.org/dist/httpd/httpd-2.4.3.tar.gz version: date: 2012-08-21 license_spdx: Apache-2.0 -license_text_file: httpd.LICENSE -copyright: Copyright 2012 The Apache Software Foundation. -notice_file: httpd.NOTICE \ No newline at end of file +copyright: Copyright 2012 The Apache Software Foundation. \ No newline at end of file diff --git a/about_code_tool/tests/testdata/test_files_for_genabout/about_with_trailling_spaces.csv b/about_code_tool/tests/testdata/test_files_for_genabout/about_with_trailling_spaces.csv new file mode 100644 index 00000000..d1672728 --- /dev/null +++ b/about_code_tool/tests/testdata/test_files_for_genabout/about_with_trailling_spaces.csv @@ -0,0 +1,2 @@ +about_file,about_resource,name,version +about.c ,.,ABOUT tool,0.8.1 diff --git a/about_code_tool/tests/testdata/test_files_for_genabout/apache-2.0.LICENSE b/about_code_tool/tests/testdata/test_files_for_genabout/apache-2.0.LICENSE new file mode 100644 index 00000000..d9a10c0d --- /dev/null +++ b/about_code_tool/tests/testdata/test_files_for_genabout/apache-2.0.LICENSE @@ -0,0 +1,176 @@ + 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/about_code_tool/tests/tstutil.py b/about_code_tool/tests/tstutil.py new file mode 100644 index 00000000..f1ab4476 --- /dev/null +++ b/about_code_tool/tests/tstutil.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +# ============================================================================ +# Copyright (c) 2013-2016 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 +# 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. +# ============================================================================ + +from __future__ import print_function + +import os +import stat +import tempfile + + +def create_dir(location): + """ + Create directory or directory tree at location, ensuring it is readable + and writeable. + """ + if not os.path.exists(location): + os.makedirs(location) + os.chmod(location, stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH) + + +def build_temp_dir(prefix='test-about-code-'): + """ + Create and return a new unique empty directory created in base_dir. + """ + return tempfile.mkdtemp(prefix=prefix) + + +def get_temp_file(file_name='test-about-code-tempfile'): + """ + Return a unique new temporary file location to a non-existing + temporary file that can safely be created without a risk of name + collision. + """ + temp_dir = get_temp_dir() + location = os.path.join(temp_dir, file_name) + return location + + +def get_temp_dir(sub_dir_path=None): + """ + Create a unique new temporary directory location. Create directories + identified by sub_dir_path if provided in this temporary directory. + Return the location for this unique directory joined with the + sub_dir_path if any. + """ + new_temp_dir = build_temp_dir() + + if sub_dir_path: + # create a sub directory hierarchy if requested + new_temp_dir = os.path.join(new_temp_dir, sub_dir_path) + create_dir(new_temp_dir) + return new_temp_dir + diff --git a/about_code_tool/util.py b/about_code_tool/util.py new file mode 100644 index 00000000..ebc4a36d --- /dev/null +++ b/about_code_tool/util.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +# ============================================================================ +# Copyright (c) 2013-2016 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 +# 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. +# ============================================================================ + +from __future__ import print_function + +import os +import sys +import ntpath +import posixpath +import optparse +from os.path import dirname +from os.path import abspath +from os.path import join +import errno + + +""" +Utility functions +""" + + +on_windows = 'win32' in sys.platform + + +def is_about_file(path): + """ + Return True if the path represents a valid ABOUT file name. + """ + return path.lower().endswith('.about') + + +def path_exists(location): + """ + Return True if the path exists. + """ + return location and os.path.exists(abspath(location)) + + +def canonical_path(location): + """ + Return a fully resolved absolute (possible UNC'ed) path for location. + """ + # path need to be unicode on Windows to ensure proper operations + if on_windows: + location = unicode(location) + + location = os.path.expanduser(location) + location = os.path.expandvars(location) + location = add_unc(location) + location = os.path.normpath(location) + location = os.path.abspath(location) + return location + +def posix_path(path): + """ + Return a path using POSIX path separators given a path that may + contain POSIX or windows separators, converting \ to /. + """ + return path.replace(ntpath.sep, posixpath.sep) + + +UNC_PREFIX = u'\\\\?\\' +UNC_PREFIX_POSIX = posix_path(UNC_PREFIX) +UNC_PREFIXES = (UNC_PREFIX_POSIX, UNC_PREFIX,) + +def add_unc(location): + """ + Convert a location to an absolute Window UNC path to support long paths on + Windows. Return the location unchanged if not on Windows. See + https://msdn.microsoft.com/en-us/library/aa365247.aspx + """ + if on_windows and not location.startswith(UNC_PREFIXES): + return UNC_PREFIX + os.path.abspath(location) + return location + + +def remove_unc(location): + """ + Return location with leading UNC prefix removed if present. + """ + if on_windows and location.startswith(UNC_PREFIXES): + return location[len(UNC_PREFIX):] + return location + + +def extract_zip(location): + """ + Extract a zip file at location in a temp directory and return the temporary + directory where the archive was extracted. + """ + import zipfile + import tempfile + if not zipfile.is_zipfile(location): + raise Exception('Incorrect zip file %(location)r' % locals()) + + archive_base_name = os.path.basename(location).replace('.zip', '') + base_dir = tempfile.mkdtemp() + target_dir = os.path.join(base_dir, archive_base_name) + target_dir = add_unc(target_dir) + os.makedirs(target_dir) + + if target_dir.endswith((ntpath.sep, posixpath.sep)): + target_dir = target_dir[:-1] + + with zipfile.ZipFile(location) as zipf: + for info in zipf.infolist(): + name = info.filename + content = zipf.read(name) + target = os.path.join(target_dir, name) + is_dir = target.endswith((ntpath.sep, posixpath.sep)) + if is_dir: + target = target[:-1] + parent = os.path.dirname(target) + if on_windows: + target = target.replace(posixpath.sep, ntpath.sep) + parent = parent.replace(posixpath.sep, ntpath.sep) + if not os.path.exists(parent): + os.makedirs(parent) + if not content and is_dir: + if not os.path.exists(target): + os.makedirs(target) + if not os.path.exists(target): + with open(target, 'wb') as f: + f.write(content) + return target_dir + + +class ImprovedFormatter(optparse.IndentedHelpFormatter): + """ + Improved formatter. + """ + def _format_text(self, text): + """ + Overridden to allow description to be printed without + modification. + """ + return text + + def format_option(self, option): + """ + Overridden to allow options help text to be printed without + modification. + """ + result = [] + opts = self.option_strings[option] + opt_width = self.help_position - self.current_indent - 2 + if len(opts) > opt_width: + opts = '%*s%s\n' % (self.current_indent, '', opts) + indent_first = self.help_position + else: # start help on same line as opts + opts = '%*s%-*s ' % (self.current_indent, '', + opt_width, opts) + indent_first = 0 + result.append(opts) + if option.help: + help_text = self.expand_default(option) + help_lines = help_text.split('\n') + # help_lines = textwrap.wrap(help_text, self.help_width) + result.append('%*s%s\n' % (indent_first, '', help_lines[0])) + result.extend(['%*s%s\n' % (self.help_position, '', line) + for line in help_lines[1:]]) + elif opts[-1] != '\n': + result.append('\n') + return ''.join(result) + + +def get_mappings(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 = {} + try: + with open(join(location, 'MAPPING.CONFIG'), 'rU') as mapping_file: + for line in mapping_file: + if not line or not line.strip() or line.strip().startswith('#'): + continue + + if ':' in line: + line = line.lower() + key, sep, value = line.partition(':') + about_key = key.strip().replace(' ', '_') + user_key = value.strip() + #mappings[user_key] = about_key + mappings[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 + sys.exit(errno.EACCES) + + return mappings + + +def apply_mappings(abouts, mappings=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. + """ + mappings = mappings or get_mappings() + mapped_abouts = [] + for about in abouts: + mapped_about = {} + for key in about: + mapped = [] + for mapping_keys, input_keys in mappings.items(): + if key == input_keys: + mapped.append(mapping_keys) + if not mapped: + mapped.append(key) + for mapped_key in mapped: + mapped_about[mapped_key] = about[key] + mapped_abouts.append(mapped_about) + return mapped_abouts + + +def resource_name(resource_path): + """ + Return a resource name based on a posix path (either the filename or + directory name). Recurse to handle paths that ends with a path separator. + """ + left, right = posixpath.split(resource_path) + if right: + return right.strip() + elif left and left != '/': + # recurse for directories that end up with a / + return resource_name(left) + else: + return '' + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..d0ad0cdd --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,9 @@ +version: '{build}' + +install: + - configure + +build: off + +test_script: + - python setup.py test diff --git a/configure b/configure index c1a4de17..eb7586c3 100755 --- a/configure +++ b/configure @@ -1,13 +1,29 @@ #!/bin/bash # -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) 2015 nexB Inc. http://www.nexb.com/ - All rights reserved. # +################################ +# change these variables to customize this script locally +################################ +# you can define one or more thirdparty dirs, each prefixed with TPP_DIR +export TPP_DIR="thirdparty" + +# default configurations +CONF_DEFAULT="etc/conf" +################################# CFG_CMD_LINE_ARGS="$@" +if [ "$1" == "--init" ]; then + CFG_CMD_LINE_ARGS=$CONF_INIT +fi + if [ "$1" == "" ]; then - # default configuration if not argument is provided - CFG_CMD_LINE_ARGS="etc/conf" + # default conf if not argument is provided + CFG_CMD_LINE_ARGS=$CONF_DEFAULT fi -source etc/configure $CFG_CMD_LINE_ARGS +python2.7 etc/configure.py $CFG_CMD_LINE_ARGS +if [ -f "bin/activate" ]; then + source bin/activate +fi diff --git a/configure.bat b/configure.bat index be058fff..a629b5c5 100644 --- a/configure.bat +++ b/configure.bat @@ -1,27 +1,46 @@ -@echo OFF -@rem Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. - -set ROOT_DIR=%~dp0 - -set CFG_CMD_LINE_ARGS= -@rem Collect all command line arguments in a variable -:collectarg - if ""%1""=="""" goto continue - call set CFG_CMD_LINE_ARGS=%CFG_CMD_LINE_ARGS% %1 - shift - goto collectarg - -:continue - -@rem default configuration when no args are passed -if "%CFG_CMD_LINE_ARGS%"==" " ( - set CFG_CMD_LINE_ARGS=etc/conf - goto configure -) - -:configure -call %ROOT_DIR%\etc\configure %CFG_CMD_LINE_ARGS% -goto EOS - - -:EOS \ No newline at end of file +@echo OFF + +@rem Copyright (c) 2015 nexB Inc. http://www.nexb.com/ - All rights reserved. + +@rem ################################ +@rem # change these variables to customize this script locally +@rem ################################ +@rem # you can define one or more thirdparty dirs, each prefixed with TPP_DIR +set TPP_DIR=thirdparty + + +@rem # default configurations +set CONF_DEFAULT="etc/conf" +@rem ################################# + +set CFG_CMD_LINE_ARGS= +@rem Collect/Slurp all command line arguments in a variable +:collectarg + if ""%1""=="""" ( + goto continue + ) + call set CFG_CMD_LINE_ARGS=%CFG_CMD_LINE_ARGS% %1 + shift + goto collectarg + +:continue + +@rem default configuration when no args are passed +if "%CFG_CMD_LINE_ARGS%"==" " ( + set CFG_CMD_LINE_ARGS="%CONF_DEFAULT%" + goto configure +) + +if "%CFG_CMD_LINE_ARGS%"==" --init" ( + set CFG_CMD_LINE_ARGS="%CONF_INIT%" + goto configure +) + +:configure +call c:\Python27\python.exe etc/configure.py %CFG_CMD_LINE_ARGS% +if exist bin\activate ( + bin\activate +) +goto EOS + +:EOS diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 5a8ed1ef..a69df9ff 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -1,3 +1,55 @@ +2015-10-22 Chin-Yeung Li + + Release 2.2.0 + + * Improved CLI error messages + * Fixed the filtering of dicts with empty values. + * Refined help texts + * Updated configure script + * Refactorings and code simplifications + * Fixed misleading error message when using invalid api_url + + +2015-10-08 Chin-Yeung Li + + Release 2.1.0 + + * Minor code refactoring + * Handle long path error on Windows OS when using genattrib with a zip + + +2015-09-28 Chin-Yeung Li + + Release 2.0.4 + + * Added support to run genattrib with a zip file and tests + * Display a "Completed" message once the generation is completed + + +2015-07-31 Chin-Yeung Li + + Release 2.0.3 + + * Fix the bug of using genattrib.py on Windows OS + * Display version when running about.py, genabout.py and genattrib.py + + +2015-07-06 Chin-Yeung Li + + Release 2.0.2 + + * Handle input's encoding issues + * Better error handling + * Writing to and reading from Windows OS with paths > 255 chars + + +2015-06-08 Chin-Yeung Li + + Release 2.0.1 + + * Fixes the configure scripts and updates basic documentation. + + 2015-03-06 Chin-Yeung Li Release 2.0.0 diff --git a/docs/UsingAboutCodetoDocumentYourSoftwareAssets.pdf b/docs/UsingAboutCodetoDocumentYourSoftwareAssets.pdf index 6586fc5e..f7354128 100644 Binary files a/docs/UsingAboutCodetoDocumentYourSoftwareAssets.pdf and b/docs/UsingAboutCodetoDocumentYourSoftwareAssets.pdf differ diff --git a/etc/conf/base.txt b/etc/conf/base.txt index c05dea4b..165e377d 100644 --- a/etc/conf/base.txt +++ b/etc/conf/base.txt @@ -1,9 +1,11 @@ # Base -certifi==14.05.14 -setuptools==7.0 -wheel==0.24.0 -pip==1.5.6 +certifi +setuptools +wheel +pip # used for templating -jinja2==2.7.3 -MarkupSafe==0.23 +MarkupSafe +jinja2 >= 2.7.3, < 3.0.0 + +-e . \ No newline at end of file diff --git a/etc/conf/dev/eclipse.project.in b/etc/conf/dev/eclipse.project.in deleted file mode 100644 index baa4dfc6..00000000 --- a/etc/conf/dev/eclipse.project.in +++ /dev/null @@ -1,17 +0,0 @@ - - - about_code_tool - - - - - - org.python.pydev.PyDevBuilder - - - - - - org.python.pydev.pythonNature - - diff --git a/etc/conf/dev/eclipse.pydevproject.posix.in b/etc/conf/dev/eclipse.pydevproject.posix.in deleted file mode 100644 index d050fac3..00000000 --- a/etc/conf/dev/eclipse.pydevproject.posix.in +++ /dev/null @@ -1,9 +0,0 @@ - - -Default -python 2.7 - - /${PROJECT_DIR_NAME} - /${PROJECT_DIR_NAME}/lib/site-packages - - diff --git a/etc/conf/dev/eclipse.pydevproject.win.in b/etc/conf/dev/eclipse.pydevproject.win.in deleted file mode 100644 index c567f4b7..00000000 --- a/etc/conf/dev/eclipse.pydevproject.win.in +++ /dev/null @@ -1,9 +0,0 @@ - - -Default -python 2.7 - - /${PROJECT_DIR_NAME} - /${PROJECT_DIR_NAME}/Lib/site-packages - - diff --git a/etc/conf/dev/posix.sh b/etc/conf/dev/posix.sh deleted file mode 100644 index 21f882be..00000000 --- a/etc/conf/dev/posix.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -cp -f etc/conf/dev/eclipse.project.in .project -cp -f etc/conf/dev/eclipse.pydevproject.posix.in .pydevproject \ No newline at end of file diff --git a/etc/conf/dev/win.bat b/etc/conf/dev/win.bat deleted file mode 100644 index 1f4454ea..00000000 --- a/etc/conf/dev/win.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo OFF -copy /Y etc\conf\dev\eclipse.pydevproject.win.in .pydevproject >NUL -copy /Y etc\conf\dev\eclipse.project.in .project >NUL \ No newline at end of file diff --git a/etc/conf/win.txt b/etc/conf/win.txt index d73c1744..f6ee7e91 100644 --- a/etc/conf/win.txt +++ b/etc/conf/win.txt @@ -1 +1 @@ -wincertstore==0.2 +wincertstore diff --git a/etc/configure b/etc/configure deleted file mode 100644 index d819b69a..00000000 --- a/etc/configure +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. -# - -ETC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -ROOT_DIR="$( dirname "$ETC_DIR" )" - -if [ "$1" == "--clean" ]; then - echo "* Cleaning ..." - cd $ROOT_DIR && rm -rf build bin lib include dist about_code_tool.egg-info - exit 0 -fi - - -CONFIGURED_PYTHON=$ROOT_DIR/bin/python - -# Install and activate a virtualenv without any download -if [ ! -f "$CONFIGURED_PYTHON" ]; then - echo "" - echo "* Configuring Python ..." - python2.7 $ROOT_DIR/thirdparty/virtualenv.py --never-download --extra-search-dir=$ROOT_DIR/thirdparty/ $ROOT_DIR -fi - -source $ROOT_DIR/bin/activate - - -# Install components from selected requirements -echo "" -echo "* Installing components ..." -for req in $($CONFIGURED_PYTHON $ETC_DIR/getconf.py --requirements $@) - do pip install --upgrade --no-allow-external --use-wheel --no-index --find-links=$ROOT_DIR/thirdparty/ -r $ROOT_DIR/$req -done - -# Run selected configuration python scripts -echo "" -echo "* Configuring ..." -for script in $($CONFIGURED_PYTHON $ETC_DIR/getconf.py --python $@) - do python $ROOT_DIR/$script -done - -# Run selected configuration command line scripts -for script in $($CONFIGURED_PYTHON $ETC_DIR/getconf.py --shell $@) - do source $ROOT_DIR/$script -done - -# Set exec permission on all files in bin -chmod -R ogu+x $ROOT_DIR/bin diff --git a/etc/configure.bat b/etc/configure.bat deleted file mode 100644 index 90b1b8d0..00000000 --- a/etc/configure.bat +++ /dev/null @@ -1,76 +0,0 @@ -@echo OFF -@rem Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. -@rem - -@rem std python -set PYTHON="c:\Python27\python.exe" - -@rem ROOT_DIR must have been set by the calling script - -set CONFIGURED_PYTHON=%ROOT_DIR%\Scripts\python.exe - -if "%1"=="--clean" goto clean - -@rem create bin dir -if not exist %ROOT_DIR%\bin mkdir %ROOT_DIR%\bin - -set CMD_LINE_ARGS= -@rem Collect all command line arguments in a variable -:collectarg - if ""%1""=="""" goto continue - call set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 - shift - goto collectarg - -:continue - -if exist %CONFIGURED_PYTHON% goto pip_requirement - -@rem Install and activate a virtualenv without any download -echo. -echo * Configuring Python ... -"%PYTHON%" %ROOT_DIR%\thirdparty\virtualenv.py --never-download --extra-search-dir=%ROOT_DIR%\thirdparty\ %ROOT_DIR% - - -:pip_requirement - -call %ROOT_DIR%\Scripts\activate.bat - -echo. -echo * Installing components ... -@rem Install components from selected requirements -%CONFIGURED_PYTHON% %ROOT_DIR%\etc\getconf.py --requirements %CMD_LINE_ARGS%> tmpreqfile -for /F %%i in (tmpreqfile) do ( - pip install --upgrade --no-index --no-allow-external --use-wheel --find-links=%ROOT_DIR%\thirdparty\ -r %ROOT_DIR%\%%i -) -del tmpreqfile > NUL - -echo. -echo * Configuring ... -:scripts -@rem Run selected configuration python scripts -%CONFIGURED_PYTHON% %ROOT_DIR%\etc\getconf.py --python %CMD_LINE_ARGS% > tmppyfile -for /F %%i in (tmppyfile) do ( - %CONFIGURED_PYTHON% %ROOT_DIR%\%%i -) -del tmppyfile > NUL - - -@rem Run selected configuration bat scripts -%CONFIGURED_PYTHON% %ROOT_DIR%\etc\getconf.py --shell %CMD_LINE_ARGS% > tmpscrfile -for /F %%i in (tmpscrfile) do ( - call %ROOT_DIR%\%%i -) -del tmpscrfile > NUL - -goto EOS - -:clean -echo * Cleaning ... -if exist %ROOT_DIR%\Scripts\deactivate.bat call %ROOT_DIR%\Scripts\deactivate -cd %ROOT_DIR% -rmdir /S /Q bin build Scripts Lib Include 2>NUL -goto EOS - - -:EOS \ No newline at end of file diff --git a/etc/configure.py b/etc/configure.py new file mode 100644 index 00000000..2d01ac40 --- /dev/null +++ b/etc/configure.py @@ -0,0 +1,386 @@ +#!/usr/bin/python + +# Copyright (c) 2015 nexB Inc. http://www.nexb.com/ - All rights reserved. + +""" +This script a configuration helper to select pip requirement files to install +and python and shell configuration scripts to execute based on provided config +directories paths arguments and the operating system platform. To use, create +a configuration directory tree that contains any of these: + + * Requirements files named with this convention: + - base.txt contains common requirements installed on all platforms. + - win.txt, linux.txt, mac.txt, posix.txt are os-specific requirements. + + * Python scripts files named with this convention: + - base.py is a common script executed on all os before os-specific scripts. + - win.py, linux.py, mac.py, posix.py are os-specific scripts to execute. + + * Shell or Windows CMD scripts files named with this convention: + - win.bat is a windows bat file to execute + - posix.sh, linux.sh, mac.sh are os-specific scripts to execute. + +The config directory structure contains one or more directories paths. This +way you can have a main configuration and additional sub-configurations of a +product such as for prod, test, ci, dev, or anything else. + +All scripts and requirements are optional and only used if presents. Scripts +are executed in sequence, one after the other after all requirements are +installed, so they may import from any installed requirement. + +The execution order is: + - requirements installation + - python scripts execution + - shell scripts execution + +On posix, posix Python and shell scripts are executed before mac or linux +scripts. + +The base scripts or packages are always installed first before platform- +specific ones. + +For example a tree could be looking like this:: + etc/conf + base.txt : base pip requirements for all platforms + linux.txt : linux-only pip requirements + base.py : base config script for all platforms + win.py : windows-only config script + posix.sh: posix-only shell script + + etc/conf/prod + base.txt : base pip requirements for all platforms + linux.txt : linux-only pip requirements + linux.sh : linux-only script + base.py : base config script for all platforms + mac.py : mac-only config script +""" + +from __future__ import print_function + +import os +import stat +import sys +import shutil +import subprocess + + +# platform-specific file base names +sys_platform = str(sys.platform).lower() +on_win = False +if 'linux' in sys_platform: + platform_names = ('posix', 'linux',) +elif'win32' in sys_platform: + platform_names = ('win',) + on_win = True +elif 'darwin' in sys_platform: + platform_names = ('posix', 'mac',) +else: + raise Exception('Unsupported OS/platform') + platform_names = tuple() + + +# common file basenames for requirements and scripts +base = ('base',) + +# known full file names with txt extension for requirements +# base is always last +requirements = tuple(p + '.txt' for p in platform_names + base) + +# known full file names with py extensions for scripts +# base is always last +python_scripts = tuple(p + '.py' for p in platform_names + base) + +# known full file names of shell scripts +# there is no base for scripts: they cannot work cross OS (cmd vs. sh) +shell_scripts = tuple(p + '.sh' for p in platform_names) +if on_win: + shell_scripts = ('win.bat',) + + +def call(cmd, root_dir): + """ Run a `cmd` command (as a list of args) with all env vars.""" + cmd = ' '.join(cmd) + if subprocess.Popen(cmd, shell=True, env=dict(os.environ), cwd=root_dir).wait() != 0: + print() + print('Failed to execute command:\n%(cmd)s. Aborting...' % locals()) + sys.exit(1) + + +def find_pycache(root_dir): + """ + Yield __pycache__ directory paths found in root_dir as paths relative to + root_dir. + """ + for top, dirs, _files in os.walk(root_dir): + for d in dirs: + if d == '__pycache__': + dir_path = os.path.join(top, d) + dir_path = dir_path.replace(root_dir, '', 1) + dir_path = dir_path.strip(os.path.sep) + yield dir_path + + +def clean(root_dir): + """ + Remove cleanable directories and files in root_dir. + """ + print('* Cleaning ...') + cleanable = '''build bin lib Lib include Include Scripts local + django_background_task.log + develop-eggs eggs parts .installed.cfg + .Python + .cache + pip-selfcheck.json + '''.split() + + # also clean __pycache__ if any + cleanable.extend(find_pycache(root_dir)) + + for d in cleanable: + try: + loc = os.path.join(root_dir, d) + if os.path.exists(loc): + if os.path.isdir(loc): + shutil.rmtree(loc) + else: + os.remove(loc) + except: + pass + + +def build_pip_dirs_args(paths, root_dir, option='--extra-search-dir='): + """ + Return an iterable of pip command line options for `option` of pip using a + list of `paths` to directories. + """ + for path in paths: + if not os.path.isabs(path): + path = os.path.join(root_dir, path) + if os.path.exists(path): + yield option + path + + +def create_virtualenv(std_python, root_dir, tpp_dirs, quiet=False): + """ + Create a virtualenv in `root_dir` using the `std_python` Python + executable. One of the `tpp_dirs` must contain a vendored virtualenv.py and + virtualenv dependencies such as setuptools and pip packages. + + @std_python: Path or name of the Python executable to use. + + @root_dir: directory in which the virtualenv will be created. This is also + the root directory for the project and the base directory for vendored + components directory paths. + + @tpp_dirs: list of directory paths relative to `root_dir` containing + vendored Python distributions that pip will use to find required + components. + """ + print("* Configuring Python ...") + # search virtualenv.py in the tpp_dirs. keep the first found + venv_py = None + for tpd in tpp_dirs: + venv = os.path.join(root_dir, tpd, 'virtualenv.py') + if os.path.exists(venv): + venv_py = venv + break + + # error out if venv_py not found + if not venv_py: + print("Configuration Error ... aborting.") + exit(1) + + vcmd = [std_python, venv_py, '--never-download'] + if quiet: + vcmd += ['--quiet'] + # third parties may be in more than one directory + vcmd.extend(build_pip_dirs_args(tpp_dirs, root_dir)) + # we create the virtualenv in the root_dir + vcmd.append(root_dir) + call(vcmd, root_dir) + + +def activate(root_dir): + """ Activate a virtualenv in the current process.""" + activate_this = os.path.join(bin_dir, 'activate_this.py') + with open(activate_this) as f: + code = compile(f.read(), activate_this, 'exec') + exec(code, dict(__file__=activate_this)) + + +def install_3pp(configs, root_dir, tpp_dirs, quiet=False): + """ + Install requirements from requirement files found in `configs` with pip, + using the vendored components in `tpp_dirs`. + """ + print("* Installing components ...") + requirement_files = get_conf_files(configs, root_dir, requirements) + for req_file in requirement_files: + pcmd = ['pip', 'install', '--no-allow-external', + '--use-wheel', '--no-index'] + if quiet: + pcmd += ['--quiet'] + pip_dir_args = list(build_pip_dirs_args(tpp_dirs, root_dir, '--find-links=')) + pcmd.extend(pip_dir_args) + req_loc = os.path.join(root_dir, req_file) + pcmd.extend(['-r' , req_loc]) + call(pcmd, root_dir) + + +def run_scripts(configs, root_dir, configured_python): + """ + Run Python scripts and shell scripts found in `configs`. + """ + print("* Configuring ...") + # Run Python scripts for each configurations + for py_script in get_conf_files(configs, root_dir, python_scripts): + cmd = [configured_python, os.path.join(root_dir, py_script)] + call(cmd, root_dir) + + # Run sh_script scripts for each configurations + for sh_script in get_conf_files(configs, root_dir, shell_scripts): + # we source the scripts on posix + cmd = ['.'] + if on_win: + cmd = [] + cmd = cmd + [os.path.join(root_dir, sh_script)] + call(cmd, root_dir) + + +def chmod_bin(directory): + """ + Makes the directory and its children executable recursively. + """ + rwx = (stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR + | stat.S_IXGRP | stat.S_IXOTH) + for path, _, files in os.walk(directory): + for f in files: + os.chmod(os.path.join(path, f), rwx) + + +def get_conf_files(config_dir_paths, root_dir, file_names=requirements): + """ + Return a list of collected path-prefixed file paths matching names in a + file_names tuple, based on config_dir_paths, root_dir and the types of + file_names requested. Returned paths are posix paths. + + @config_dir_paths: Each config_dir_path is a relative from the project + root to a config dir. This script should always be called from the project + root dir. + + @root_dir: The project absolute root dir. + + @file_names: get requirements, python or shell files based on list of + supported file names provided as a tuple of supported file_names. + + Scripts or requirements are optional and only used if presents. Unknown + scripts or requirements file_names are ignored (but they could be used + indirectly by known requirements with -r requirements inclusion, or + scripts with python imports.) + + Since Python scripts are executed after requirements are installed they + can import from any requirement-installed component such as Fabric. + """ + # collect files for each requested dir path + collected = [] + for config_dir_path in config_dir_paths: + abs_config_dir_path = os.path.join(root_dir, config_dir_path) + if not os.path.exists(abs_config_dir_path): + print('Configuration directory %(config_dir_path)s ' + 'does not exists. Skipping.' % locals()) + continue + # Support args like enterprise or enterprise/dev + paths = config_dir_path.strip('/').replace('\\', '/').split('/') + # a tuple of (relative path, location,) + current = None + for path in paths: + if not current: + current = (path, os.path.join(root_dir, path),) + else: + base_path, base_loc = current + current = (os.path.join(base_path, path), + os.path.join(base_loc, path),) + path, loc = current + # we iterate on known filenames to ensure the defined precedence + # is respected (posix over mac, linux), etc + for n in file_names: + for f in os.listdir(loc): + if f == n: + f_loc = os.path.join(loc, f) + if f_loc not in collected: + collected.append(f_loc) + + return collected + + +if __name__ == '__main__': + # define/setup common directories + etc_dir = os.path.abspath(os.path.dirname(__file__)) + root_dir = os.path.dirname(etc_dir) + + args = sys.argv[1:] + if args[0] == '--clean': + clean(root_dir) + sys.exit(0) + + sys.path.insert(0, root_dir) + bin_dir = os.path.join(root_dir, 'bin') + standard_python = sys.executable + + # you must create a CONFIGURE_QUIET env var if you want to run quietly + run_quiet = 'CONFIGURE_QUIET' in os.environ + + if on_win: + configured_python = os.path.join(bin_dir, 'python.exe') + scripts_dir = os.path.join(root_dir, 'Scripts') + bin_dir = os.path.join(root_dir, 'bin') + if not os.path.exists(scripts_dir): + os.makedirs(scripts_dir) + if not os.path.exists(bin_dir): + cmd = ('mklink /J %(bin_dir)s %(scripts_dir)s' % locals()).split() + call(cmd, root_dir) + else: + configured_python = os.path.join(bin_dir, 'python') + scripts_dir = bin_dir + + # Get requested configuration paths to collect components and scripts later + configs = [] + for path in args[:]: + if not os.path.isabs(path): + abs_path = os.path.join(root_dir, path) + if os.path.exists(abs_path): + configs.append(path) + else: + print() + print('WARNING: Skipping missing Configuration directory:\n' + ' %(path)s does not exist.' % locals()) + print() + + # Collect vendor directories from environment variables: one or more third- + # party directories may exist as environment variables prefixed with TPP_DIR + thirdparty_dirs = [] + for envvar, path in os.environ.items(): + if not envvar.startswith('TPP_DIR'): + continue + if not os.path.isabs(path): + abs_path = os.path.join(root_dir, path) + if os.path.exists(abs_path): + thirdparty_dirs.append(path) + else: + print() + print('WARNING: Skipping missing Python thirdparty directory:\n' + ' %(path)s does not exist.\n' + ' Provided by environment variable:\n' + ' set %(envvar)s=%(path)s' % locals()) + print() + + # Finally execute our three steps: venv, install and scripts + if not os.path.exists(configured_python): + create_virtualenv(standard_python, root_dir, thirdparty_dirs, quiet=run_quiet) + activate(root_dir) + + install_3pp(configs, root_dir, thirdparty_dirs, quiet=run_quiet) + run_scripts(configs, root_dir, configured_python) + chmod_bin(bin_dir) + print("* Configuration completed.") + print() diff --git a/etc/getconf.py b/etc/getconf.py deleted file mode 100644 index 93d84556..00000000 --- a/etc/getconf.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/python - -# Copyright (c) 2014 nexB Inc. http://www.nexb.com/ - All rights reserved. - -""" -This script a configuration helper to select pip requirement files to install -and python and shell configuration scripts to execute based on provided config -directories paths arguments and the operating system platform. To use, create -a configuration directory tree that contains any of these: - - * Requirements files named with this convention: - - base.txt contains common requirements installed on all platforms. - - win.txt, linux.txt, mac.txt, posix.txt, cygwin.txt are platform-specific - requirements to install. - - * Python scripts files named with this convention: - - base.py is a common script executed on all platforms, executed before - os-specific scripts. - - win.py, linux.py, mac.py, posix.py, cygwin.py are platform-specific - scripts to execute. - - * Shell or Windows CMD scripts files named with this convention: - - win.bat is a windows bat file to execute - - posix.sh, linux.sh, mac.sh, cygwin.sh are platform-specific scripts to - execute. - -The config directory structure contains one or more directories paths. This -way you can have a main configuration and additional sub-configurations of a -product such as for prod, test, ci, dev, or anything else. - -All scripts and requirements are optional and only used if presents. Scripts -are executed in sequence, one after the other after all requirements are -installed, so they may import from any installed requirement. - -The execution order is: - - requirements installation - - python scripts execution - - shell scripts execution - -On posix, posix Python and shell scripts are executed before mac or linux -scripts. - -The base scripts or packages are always installed first before platform-specific ones. - -For example a tree could be looking like this:: - etc/conf - base.txt : base pip requirements for all platforms - linux.txt : linux-only pip requirements - base.py : base config script for all platforms - win.py : windows-only config script - posix.sh: posix-only shell script - - etc/conf/prod - base.txt : base pip requirements for all platforms - linux.txt : linux-only pip requirements - linux.sh : linux-only script - base.py : base config script for all platforms - mac.py : mac-only config script -""" - -from __future__ import print_function - -import os -import sys - - -# platform-specific file base names -sys_platform = str(sys.platform).lower() -if 'linux' in sys_platform: - platform_names = ('posix', 'linux',) -elif'win32' in sys_platform: - platform_names = ('win',) -elif 'darwin' in sys_platform: - platform_names = ('posix', 'mac',) -elif 'cygwin' in sys_platform: - platform_names = ('posix', 'cygwin',) -else: - print('Unsupported OS/platform') - platform_names = tuple() - - -# common file basenames for requirements and scripts -base = ('base',) - -# known full file names with txt extension for requirements -requirements = tuple(p + '.txt' for p in platform_names + base) - -# known full file names with py extensions for scripts -python_scripts = tuple(p + '.py' for p in platform_names + base) - -# known full file names of shell scripts -shell_scripts = tuple(p + '.sh' for p in platform_names) -if 'win' in platform_names: - shell_scripts = ('win.bat',) - - -def get_conf_files(config_dir_paths, file_names=requirements): - """ - Based on config_dir_paths return a list of collected path-prefixed file - paths matching names in a file_names tuple. Returned paths are posix - paths. - - @config_dir_paths: Each config_dir_path is a relative from the project - root to a config dir. This script should always be called from the project - root dir. - - @file_names: get requirements, python or shell files based on list of - supported file names provided as a tuple of supported file_names. - - Scripts or requirements are optional and only used if presents. Unknown - scripts or requirements file_names are ignored (but they could be used - indirectly by known requirements with -r requirements inclusion, or - scripts with python imports.) - - Since Python scripts are executed after requirements are installed they - can import from any requirement- installed component such as Fabric. - """ - - # collect files for each requested dir path - collected = [] - - for config_dir_path in config_dir_paths: - # Support args like enterprise or enterprise/dev - paths = config_dir_path.strip('/').replace('\\', '/').split('/') - # a tuple of (relative path, location,) - current = None - for path in paths: - if not current: - current = (path, os.path.abspath(path),) - else: - base_path, base_loc = current - current = (os.path.join(base_path, path), - os.path.join(base_loc, path),) - - path, loc = current - # we iterate on filenames to ensure the precedence of posix over - # mac, linux, etc is repsected - for n in file_names: - for f in os.listdir(loc): - if f == n: - f_loc = os.path.join(path, f) - if f_loc not in collected: - collected.append(f_loc) - - return collected - - -conf_types = {'--requirements': requirements, - '--python': python_scripts, - '--shell': shell_scripts} - - -if __name__ == '__main__': - collect_what = sys.argv[1] - if collect_what not in conf_types: - print('First argument must be one of %s' % ', '.join(conf_types)) - sys.exit(1) - - what_to_collect = conf_types[collect_what] - - try: - prod_confs = sys.argv[2:] - except IndexError: - print('Missing product/config arguments such as "etc/conf/dev".') - sys.exit(1) - - collected = get_conf_files(prod_confs, file_names=what_to_collect) - - collected = '\n'.join(collected) - - print(collected) diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/alocal.m4.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/alocal.m4.ABOUT index c90c8340..79bf5033 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/alocal.m4.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/alocal.m4.ABOUT @@ -5,7 +5,8 @@ version: category: Public Domain confirmed_license: Public Domain copyright: Copyright (c) 1995-2003 Free Software Foundation, Inc. -dje_license: public-domain +dje_license_key: public-domain dje_license_name: Public Domain +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:public-domain license_text_file: public-domain.LICENSE owner: Free Software Foundation diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.guess.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.guess.ABOUT index c0a4f115..28aae5e1 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.guess.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.guess.ABOUT @@ -8,8 +8,9 @@ checksum_sha1: 6bf255982f9104c1423347581c55b4a34336e933 component_type: posix shell script text executable confirmed_license: GPL 2.0 with Autoconf exception copyright: Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -dje_license: gpl-2.0-autoconf +dje_license_key: gpl-2.0-autoconf dje_license_name: GNU General Public License 2.0 with Autoconf exception +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0-autoconf license_text_file: gpl-2.0-autoconf.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.rpath.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.rpath.ABOUT index 81dc829f..26c5e6b4 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.rpath.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.rpath.ABOUT @@ -8,8 +8,9 @@ checksum_sha1: 98461658e371e01ef48f2ea173823c96fecc6145 component_type: posix shell script text executable confirmed_license: GPL 2.0 with Autoconf exception copyright: Copyright 1996-2002 Free Software Foundation, Inc. -dje_license: gpl-2.0-autoconf +dje_license_key: gpl-2.0-autoconf dje_license_name: GNU General Public License 2.0 with Autoconf exception +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0-autoconf license_text_file: gpl-2.0-autoconf.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.sub.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.sub.ABOUT index 26ff9a75..1b96e043 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.sub.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/config.sub.ABOUT @@ -8,8 +8,9 @@ checksum_sha1: c6aba2045763f997fc81c1d881304755b09d2e02 component_type: posix shell script text executable confirmed_license: GPL 2.0 with Autoconf exception copyright: Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -dje_license: gpl-2.0-autoconf +dje_license_key: gpl-2.0-autoconf dje_license_name: GNU General Public License 2.0 with Autoconf exception +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0-autoconf license_text_file: gpl-2.0-autoconf.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/mkinstalldirs.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/mkinstalldirs.ABOUT index c4f8656b..29ef7149 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/mkinstalldirs.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/config/mkinstalldirs.ABOUT @@ -6,8 +6,9 @@ category: Public Domain checksum_sha1: e8066bf9dc4353afffcfc5c2ec1cc9cc757585de component_type: posix shell script text executable confirmed_license: Public Domain -dje_license: public-domain +dje_license_key: public-domain dje_license_name: Public Domain +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:public-domain download_url: http://svn.apache.org/repos/asf/axis/axis1/c/trunk/mkinstalldirs license_text_file: public-domain.LICENSE owner: Noah Friedman diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.c.ABOUT index f58e3fbc..e0f38af9 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.c.ABOUT @@ -8,7 +8,8 @@ checksum_sha1: 318ea46f5d3a08ae60d311b0cfe0b0c19e00a286 component_type: c language text confirmed_license: MIT Old Style legal 2 copyright: Copyright 1999 by Theodore Ts'o -dje_license: mit-old-style-legal-2 +dje_license_key: mit-old-style-legal-2 dje_license_name: MIT Old Style with legal disclaimer 2 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:mit-old-style-legal-2 license_text_file: mit-old-style-legal-2.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.h.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.h.ABOUT index 3c505866..a187b42a 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.h.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/argv_parse.h.ABOUT @@ -8,7 +8,8 @@ checksum_sha1: fbe63cb7e5c5c90ba03b47e1e105ac1e50c2ba2a component_type: c language text confirmed_license: MIT Old Style legal 2 copyright: Copyright 1999 by Theodore Ts'o -dje_license: mit-old-style-legal-2 +dje_license_key: mit-old-style-legal-2 dje_license_name: MIT Old Style with legal disclaimer 2 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:mit-old-style-legal-2 license_text_file: mit-old-style-legal-2.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/journal.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/journal.c.ABOUT index aecb9014..e2d41fc3 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/journal.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/journal.c.ABOUT @@ -10,8 +10,9 @@ confirmed_license: GPL 2.0 copyright: Copyright (C) 2000 Andreas Dilger Copyright (C) 2000 Theodore Ts'o Copyright (C) 1999 Red Hat Software -dje_license: gpl-2.0 +dje_license_key: gpl-2.0 dje_license_name: GNU General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0 license_text_file: gpl-2.0.LICENSE owner: Stephen C. Tweedie redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.c.ABOUT index 48dd8e10..9c726134 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.c.ABOUT @@ -10,8 +10,9 @@ confirmed_license: LGPL 2.0 copyright: Copyright (C) 1991, 1992 Free Software Foundation, Inc. Written April 2, 1991 by John Gilmore of Cygnus Support. Based on mcheck.c by Mike Haertel. -dje_license: lgpl-2.0 +dje_license_key: lgpl-2.0 dje_license_name: GNU Library General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.0 license_text_file: lgpl-2.0.LICENSE owner: Mike Haertel redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.h.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.h.ABOUT index 4b4983f7..8946eb17 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.h.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/mtrace.h.ABOUT @@ -9,8 +9,9 @@ component_type: c language text confirmed_license: LGPL 2.0 copyright: Copyright 1990, 1991, 1992 Free Software Foundation, Inc. Written May 1989 by Mike Haertel. -dje_license: lgpl-2.0 +dje_license_key: lgpl-2.0 dje_license_name: GNU Library General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.0 license_text_file: lgpl-2.0.LICENSE owner: Mike Haertel redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.c.ABOUT index 3438afba..65942ef4 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.c.ABOUT @@ -9,8 +9,9 @@ component_type: c language text confirmed_license: GPL 2.0 copyright: Copyright (C) 2005 by Theodore Ts'o. Copyright (C) 1985-2005 by the Massachusetts Institute of Technology. -dje_license: gpl-2.0 +dje_license_key: gpl-2.0 dje_license_name: GNU General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0 license_text_file: gpl-2.0.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.h.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.h.ABOUT index 67e25f1a..308e684d 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.h.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsck/profile.h.ABOUT @@ -9,8 +9,9 @@ component_type: c language text confirmed_license: GPL 2.0 copyright: Copyright (C) 2005 by Theodore Ts'o. Copyright (C) 1985-2005 by the Massachusetts Institute of Technology. -dje_license: gpl-2.0 +dje_license_key: gpl-2.0 dje_license_name: GNU General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0 license_text_file: gpl-2.0.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.ABOUT index bc066a24..b0f46fc7 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.ABOUT @@ -7,8 +7,9 @@ category: Copyleft component_type: directory confirmed_license: GPL 2.0 copyright: Copyright (c) 1997-2004 Theodore Ts'o -dje_license: gpl-2.0 +dje_license_key: gpl-2.0 dje_license_name: GNU General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0 download_url: http://sourceforge.net/projects/e2fsprogs/files/e2fsprogs/1.39/e2fsprogs-1.39.tar.gz/ license_text_file: gpl-2.0.LICENSE notice_file: e2fsprogs-1.39.NOTICE diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.NOTICE b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.NOTICE index ebb69ef6..6139069b 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.NOTICE +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/e2fsprogs-1.39.NOTICE @@ -26,4 +26,3 @@ enough lead time. 15-Mar-2003 ---------------------------------------------------------------------- - diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/include/nonunix/getopt.h.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/include/nonunix/getopt.h.ABOUT index 2ca45972..e19ce7de 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/include/nonunix/getopt.h.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/include/nonunix/getopt.h.ABOUT @@ -8,8 +8,9 @@ checksum_sha1: 2fede7afd8211e66071476da4553a44029be67d5 component_type: c language text confirmed_license: LGPL 2.0 copyright: Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. -dje_license: lgpl-2.0 +dje_license_key: lgpl-2.0 dje_license_name: GNU Library General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.0 download_url: http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/include/nonunix/getopt.h license_text_file: lgpl-2.0.LICENSE owner: GNU C Library diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/install-utils/convfstab.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/install-utils/convfstab.ABOUT index fd1b4c5c..734c492e 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/install-utils/convfstab.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/install-utils/convfstab.ABOUT @@ -6,8 +6,9 @@ category: Public Domain checksum_sha1: dde2f47f8abbe15627cd5bfe0e2283fbb820eda6 component_type: posix shell script text executable confirmed_license: Public Domain -dje_license: Public Domain +dje_license_key: public-domain dje_license_name: Public Domain +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:public-domain download_url: http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/install-utils/convfstab license_text_file: public-domain.LICENSE owner: M.Weller diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/intl/intl.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/intl/intl.ABOUT index a576bff3..04bf1667 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/intl/intl.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/intl/intl.ABOUT @@ -7,8 +7,9 @@ category: Copyleft Limited component_type: directory confirmed_license: LGPL 2.0 copyright: Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc. -dje_license: lgpl-2.0 +dje_license_key: lgpl-2.0 dje_license_name: GNU Library General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.0 license_text_file: lgpl-2.0.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/blkid/blkid.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/blkid/blkid.ABOUT index c84e43ca..5dfa729a 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/blkid/blkid.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/blkid/blkid.ABOUT @@ -9,8 +9,9 @@ confirmed_license: LGPL 2.1 copyright: Copyright (C) 2001 Andreas Dilger Copyright (C) 2003 Theodore Ts'o Copyright (C) 1999 by Andries Brouwer -dje_license: lgpl-2.1 +dje_license_key: lgpl-2.1 dje_license_name: GNU Lesser General Public License 2.1 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.1 license_text_file: lgpl-2.1.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/e2p/e2p.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/e2p/e2p.ABOUT index bebe7656..b5816e8d 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/e2p/e2p.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/e2p/e2p.ABOUT @@ -8,8 +8,9 @@ component_type: directory confirmed_license: LGPL 2.0 copyright: Copyright (C) 1992, 1993, 1994 Remy Card Copyright (c) 1999 Theodore Ts -dje_license: lgpl-2.0 +dje_license_key: lgpl-2.0 dje_license_name: GNU Library General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.0 license_text_file: lgpl-2.0.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/com_right.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/com_right.c.ABOUT index b3b0568e..eed11de2 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/com_right.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/com_right.c.ABOUT @@ -9,7 +9,8 @@ component_type: c language text confirmed_license: BSD-Modified copyright: Copyright (c) 2003 by Theodore Ts'o Copyright (c) 1997, 1998, 2001 Kungliga Tekniska Hogskolan -dje_license: bsd-new +dje_license_key: bsd-new dje_license_name: BSD-Modified +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:bsd-new license_text_file: bsd-new.LICENSE owner: Kerberos4kth diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/et.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/et.ABOUT index f1effc10..bf1e0f12 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/et.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/et.ABOUT @@ -7,7 +7,8 @@ category: Attribution component_type: directory confirmed_license: Kerberos License copyright: Copyright 2003 by MIT Student Information Processing Board -dje_license: kerberos +dje_license_key: kerberos dje_license_name: Kerberos License +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:kerberos license_text_file: kerberos.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/texinfo.tex.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/texinfo.tex.ABOUT index fc4a026c..bbc57e10 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/texinfo.tex.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/texinfo.tex.ABOUT @@ -8,8 +8,9 @@ checksum_sha1: 1b73dbf5dbc340a945d2bc75f61cc212f5ae3c08 component_type: tex language text confirmed_license: GPL 2.0 copyright: Copyright (C) 1985, 1986, 1988 Richard M. Stallman -dje_license: gpl-2.0 +dje_license_key: gpl-2.0 dje_license_name: GNU General Public License 2.0 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:gpl-2.0 license_text_file: gpl-2.0.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/vfprintf.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/vfprintf.c.ABOUT index 817b0b68..18b4b674 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/vfprintf.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/et/vfprintf.c.ABOUT @@ -6,9 +6,10 @@ attribute: yes category: Attribution checksum_sha1: 01a03815e2550f01bbfe0b40c277e0621c52cec1 component_type: c language text -confirmed_license: Berkeley Software License Agreement +confirmed_license: Berkeley Software License Agreement copyright: Copyright (c) 1988 Regents of the University of California -dje_license: bsla +dje_license_key: bsla dje_license_name: Berkeley Software License Agreement +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:bsla license_text_file: bsla.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/fpopen.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/fpopen.c.ABOUT index 64754608..7bc65e99 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/fpopen.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/fpopen.c.ABOUT @@ -6,9 +6,10 @@ attribute: yes category: Attribution checksum_sha1: 6bd791a73921839a749fce1086ff1ede0c434ec2 component_type: c language text -confirmed_license: Berkeley Software License Agreement +confirmed_license: Berkeley Software License Agreement copyright: Copyright Theodore Ts'o, 1996-1999. -dje_license: bsla +dje_license_key: bsla dje_license_name: Berkeley Software License Agreement +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:bsla license_text_file: bsla.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/ss/ss.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/ss/ss.ABOUT index afc84a63..9dff9c83 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/ss/ss.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/ss/ss.ABOUT @@ -7,7 +7,8 @@ category: Attribution component_type: directory confirmed_license: Kerberos License copyright: Copyright 2003 by MIT Student Information Processing Board -dje_license: kerberos +dje_license_key: kerberos dje_license_name: Kerberos License +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:kerberos license_text_file: kerberos.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/uuid/uuid.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/uuid/uuid.ABOUT index 7caf2f45..ea46f9a2 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/uuid/uuid.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/lib/uuid/uuid.ABOUT @@ -7,7 +7,8 @@ category: Attribution component_type: directory confirmed_license: BSD-Modified copyright: Copyright (C) 1996, 1997 Theodore Ts'o -dje_license: bsd-new +dje_license_key: bsd-new dje_license_name: BSD-Modified +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:bsd-new license_text_file: bsd-new.LICENSE owner: Theodore Ts'o diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/misc/blkid.c.ABOUT b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/misc/blkid.c.ABOUT index bb1bbc37..f5a53710 100644 --- a/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/misc/blkid.c.ABOUT +++ b/example/e2fsprogs-1.39/e2fsprogs-about/e2fsprogs-1.39/misc/blkid.c.ABOUT @@ -8,8 +8,9 @@ checksum_sha1: 6448a75f8212c06bd76f59c6b96024fa94c82f12 component_type: c language text confirmed_license: LGPL 2.1 copyright: Copyright (C) 2001 Andreas Dilger -dje_license: lgpl-2.1 +dje_license_key: lgpl-2.1 dje_license_name: GNU Lesser General Public License 2.1 +dje_license_url: https://enterprise.dejacode.com/urn/?urn=urn:dje:license:lgpl-2.1 license_text_file: lgpl-2.1.LICENSE owner: Theodore Ts'o redistribute: yes diff --git a/example/e2fsprogs-1.39/e2fsprogs-about/error.log b/example/e2fsprogs-1.39/e2fsprogs-about/error.log new file mode 100644 index 00000000..e69de29b diff --git a/example/e2fsprogs-1.39/input/e2fsprogs-1.39-CreateAboutFile.csv b/example/e2fsprogs-1.39/input/e2fsprogs-1.39-CreateAboutFile.csv index fb5d99bf..8e69948c 100644 --- a/example/e2fsprogs-1.39/input/e2fsprogs-1.39-CreateAboutFile.csv +++ b/example/e2fsprogs-1.39/input/e2fsprogs-1.39-CreateAboutFile.csv @@ -1 +1 @@ -pathname,component,cversion,Category,Confirmed_License,dje_license,attribute,redistribute,track_changes,owner,license_text_file,notice_file,download_url,copyright,file_type,sha1 /e2fsprogs-1.39/,e2fsprogs,1.39,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,e2fsprogs-1.39.NOTICE,http://sourceforge.net/projects/e2fsprogs/files/e2fsprogs/1.39/e2fsprogs-1.39.tar.gz/,Copyright (c) 1997-2004 Theodore Ts'o,directory, /e2fsprogs-1.39/alocal.m4,alocal.m4,,Public Domain,Public Domain,public-domain,,,,Free Software Foundation,,,,"Copyright (c) 1995-2003 Free Software Foundation, Inc.",, /e2fsprogs-1.39/config/config.guess,config.guess,,Copyleft,GPL 2.0 with Autoconf exception,gpl-2.0-autoconf,yes,yes,yes,Theodore Ts'o,,,,"Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.",posix shell script text executable,6bf255982f9104c1423347581c55b4a34336e933 /e2fsprogs-1.39/config/config.rpath,config.rpath,,Copyleft,GPL 2.0 with Autoconf exception,gpl-2.0-autoconf,yes,yes,yes,Theodore Ts'o,,,,"Copyright 1996-2002 Free Software Foundation, Inc.",posix shell script text executable,98461658e371e01ef48f2ea173823c96fecc6145 /e2fsprogs-1.39/config/config.sub,config.sub,,Copyleft,GPL 2.0 with Autoconf exception,gpl-2.0-autoconf,yes,yes,yes,Theodore Ts'o,,,,"Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.",posix shell script text executable,c6aba2045763f997fc81c1d881304755b09d2e02 /e2fsprogs-1.39/config/mkinstalldirs,mkinstalldirs,,Public Domain,Public Domain,public-domain,,,,Noah Friedman,,,http://svn.apache.org/repos/asf/axis/axis1/c/trunk/mkinstalldirs,,posix shell script text executable,e8066bf9dc4353afffcfc5c2ec1cc9cc757585de /e2fsprogs-1.39/contrib/dconf,dconf,,Attribution,Ulrich Windl License,,,,,Ulrich Windl,UlrichWindl.LICENSE,,http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/contrib/dconf,Copyright (c) 1994 Ulrich Windl,posix shell script text executable,98bd1184714d0463da59644c4b01559947b5c4e0 /e2fsprogs-1.39/e2fsck/argv_parse.c,argv_parse.c,,Attribution,MIT Old Style legal 2,mit-old-style-legal-2,yes,,,Theodore Ts'o,,,,Copyright 1999 by Theodore Ts'o,c language text,318ea46f5d3a08ae60d311b0cfe0b0c19e00a286 /e2fsprogs-1.39/e2fsck/argv_parse.h,argv_parse.h,,Attribution,MIT Old Style legal 2,mit-old-style-legal-2,yes,,,Theodore Ts'o,,,,Copyright 1999 by Theodore Ts'o,c language text,fbe63cb7e5c5c90ba03b47e1e105ac1e50c2ba2a /e2fsprogs-1.39/e2fsck/dict.c,dict.c,,Attribution,Kaz Kylheku License,,yes,,yes,Kaz Kylheku,KazKylheku.LICENSE,,,Copyright (C) 1997 Kaz Kylheku ,c language text,52e5af00e28008e9fb264a88f46566947e4b09f7 /e2fsprogs-1.39/e2fsck/dict.h,dict.h,,Attribution,Kaz Kylheku License,,yes,,yes,Kaz Kylheku,KazKylheku.LICENSE,,,Copyright (C) 1997 Kaz Kylheku ,c language text,0f99603368345b82318e0fb186421cbaa3d8c3a2 /e2fsprogs-1.39/e2fsck/journal.c,journal.c,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Stephen C. Tweedie,,,,"Copyright (C) 2000 Andreas Dilger Copyright (C) 2000 Theodore Ts'o Copyright (C) 1999 Red Hat Software",c language text,02ef021aec0bea6f3a7377ab72d43491c5866dc5 /e2fsprogs-1.39/e2fsck/mtrace.c,mtrace.c,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Mike Haertel,,,,"Copyright (C) 1991, 1992 Free Software Foundation, Inc. Written April 2, 1991 by John Gilmore of Cygnus Support. Based on mcheck.c by Mike Haertel.",c language text,badc318b64d9485aa965fae4b5c2f954c5001e90 /e2fsprogs-1.39/e2fsck/mtrace.h,mtrace.h,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Mike Haertel,,,,"Copyright 1990, 1991, 1992 Free Software Foundation, Inc. Written May 1989 by Mike Haertel.",c language text,3fd39f30399e003b1de7772173597bdef2993df3 /e2fsprogs-1.39/e2fsck/profile.c,profile.c,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 2005 by Theodore Ts'o. Copyright (C) 1985-2005 by the Massachusetts Institute of Technology.",c language text,87fde75c46dc2248516dda298ef6357ec3a2df6a /e2fsprogs-1.39/e2fsck/profile.h,profile.h,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 2005 by Theodore Ts'o. Copyright (C) 1985-2005 by the Massachusetts Institute of Technology.",c language text,c95dd8d01dc42096b40fa9ac0ee96ce56db61c38 /e2fsprogs-1.39/include/nonunix/getopt.h,getopt.h,,Copyleft Limited,LGPL 2.0,LGPL 2.0,yes,yes,yes,GNU C Library,,,http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/include/nonunix/getopt.h,"Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.",c language text,2fede7afd8211e66071476da4553a44029be67d5 /e2fsprogs-1.39/install-utils/convfstab,convfstab,,Public Domain,Public Domain,Public Domain,,,,M.Weller,,,http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/install-utils/convfstab,,posix shell script text executable,dde2f47f8abbe15627cd5bfe0e2283fbb820eda6 /e2fsprogs-1.39/intl/,intl,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc.",directory, /e2fsprogs-1.39/lib/blkid/,blkid,,Copyleft Limited,LGPL 2.1,lgpl-2.1,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 2001 Andreas Dilger Copyright (C) 2003 Theodore Ts'o Copyright (C) 1999 by Andries Brouwer",directory, /e2fsprogs-1.39/lib/e2p/,e2p,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 1992, 1993, 1994 Remy Card Copyright (c) 1999 Theodore Ts",directory, /e2fsprogs-1.39/lib/et/,et,,Attribution,Kerberos License,kerberos,yes,,,Theodore Ts'o,,,,Copyright 2003 by MIT Student Information Processing Board,directory, /e2fsprogs-1.39/lib/et/com_right.c,com_right.c,,Attribution,BSD-Modified,bsd-new,yes,,,Kerberos4kth,,,,"Copyright (c) 2003 by Theodore Ts'o Copyright (c) 1997, 1998, 2001 Kungliga Tekniska Hšgskolan",c language text,3d14b06ab31477a1fec4354d8b9f9c82b35896bb /e2fsprogs-1.39/lib/et/texinfo.tex,texinfo.tex,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 1985, 1986, 1988 Richard M. Stallman",tex language text,1b73dbf5dbc340a945d2bc75f61cc212f5ae3c08 /e2fsprogs-1.39/lib/et/vfprintf.c,vfprintf.c,,Attribution,Berkeley Software License Agreement ,bsla,yes,,,Theodore Ts'o,,,,Copyright (c) 1988 Regents of the University of California,c language text,01a03815e2550f01bbfe0b40c277e0621c52cec1 /e2fsprogs-1.39/lib/fpopen.c,fpopen.c,,Attribution,Berkeley Software License Agreement ,bsla,yes,,,Theodore Ts'o,,,,"Copyright Theodore Ts'o, 1996-1999.",c language text,6bd791a73921839a749fce1086ff1ede0c434ec2 /e2fsprogs-1.39/lib/ss/,ss,,Attribution,Kerberos License,kerberos,yes,,,Theodore Ts'o,,,,Copyright 2003 by MIT Student Information Processing Board,directory, /e2fsprogs-1.39/lib/uuid/,uuid,,Attribution,BSD-Modified,bsd-new,yes,,,Theodore Ts'o,,,,"Copyright (C) 1996, 1997 Theodore Ts'o",directory, /e2fsprogs-1.39/misc/blkid.c,blkid.c,,Copyleft Limited,LGPL 2.1,lgpl-2.1,yes,yes,yes,Theodore Ts'o,,,,Copyright (C) 2001 Andreas Dilger,c language text,6448a75f8212c06bd76f59c6b96024fa94c82f12 \ No newline at end of file +pathname,component,cversion,Category,Confirmed_License,dje_license_key,attribute,redistribute,track_changes,owner,license_text_file,notice_file,download_url,copyright,file_type,sha1 /e2fsprogs-1.39/,e2fsprogs,1.39,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,e2fsprogs-1.39.NOTICE,http://sourceforge.net/projects/e2fsprogs/files/e2fsprogs/1.39/e2fsprogs-1.39.tar.gz/,Copyright (c) 1997-2004 Theodore Ts'o,directory, /e2fsprogs-1.39/alocal.m4,alocal.m4,,Public Domain,Public Domain,public-domain,,,,Free Software Foundation,,,,"Copyright (c) 1995-2003 Free Software Foundation, Inc.",, /e2fsprogs-1.39/config/config.guess,config.guess,,Copyleft,GPL 2.0 with Autoconf exception,gpl-2.0-autoconf,yes,yes,yes,Theodore Ts'o,,,,"Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.",posix shell script text executable,6bf255982f9104c1423347581c55b4a34336e933 /e2fsprogs-1.39/config/config.rpath,config.rpath,,Copyleft,GPL 2.0 with Autoconf exception,gpl-2.0-autoconf,yes,yes,yes,Theodore Ts'o,,,,"Copyright 1996-2002 Free Software Foundation, Inc.",posix shell script text executable,98461658e371e01ef48f2ea173823c96fecc6145 /e2fsprogs-1.39/config/config.sub,config.sub,,Copyleft,GPL 2.0 with Autoconf exception,gpl-2.0-autoconf,yes,yes,yes,Theodore Ts'o,,,,"Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.",posix shell script text executable,c6aba2045763f997fc81c1d881304755b09d2e02 /e2fsprogs-1.39/config/mkinstalldirs,mkinstalldirs,,Public Domain,Public Domain,public-domain,,,,Noah Friedman,,,http://svn.apache.org/repos/asf/axis/axis1/c/trunk/mkinstalldirs,,posix shell script text executable,e8066bf9dc4353afffcfc5c2ec1cc9cc757585de /e2fsprogs-1.39/contrib/dconf,dconf,,Attribution,Ulrich Windl License,,,,,Ulrich Windl,UlrichWindl.LICENSE,,http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/contrib/dconf,Copyright (c) 1994 Ulrich Windl,posix shell script text executable,98bd1184714d0463da59644c4b01559947b5c4e0 /e2fsprogs-1.39/e2fsck/argv_parse.c,argv_parse.c,,Attribution,MIT Old Style legal 2,mit-old-style-legal-2,yes,,,Theodore Ts'o,,,,Copyright 1999 by Theodore Ts'o,c language text,318ea46f5d3a08ae60d311b0cfe0b0c19e00a286 /e2fsprogs-1.39/e2fsck/argv_parse.h,argv_parse.h,,Attribution,MIT Old Style legal 2,mit-old-style-legal-2,yes,,,Theodore Ts'o,,,,Copyright 1999 by Theodore Ts'o,c language text,fbe63cb7e5c5c90ba03b47e1e105ac1e50c2ba2a /e2fsprogs-1.39/e2fsck/dict.c,dict.c,,Attribution,Kaz Kylheku License,,yes,,yes,Kaz Kylheku,KazKylheku.LICENSE,,,Copyright (C) 1997 Kaz Kylheku ,c language text,52e5af00e28008e9fb264a88f46566947e4b09f7 /e2fsprogs-1.39/e2fsck/dict.h,dict.h,,Attribution,Kaz Kylheku License,,yes,,yes,Kaz Kylheku,KazKylheku.LICENSE,,,Copyright (C) 1997 Kaz Kylheku ,c language text,0f99603368345b82318e0fb186421cbaa3d8c3a2 /e2fsprogs-1.39/e2fsck/journal.c,journal.c,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Stephen C. Tweedie,,,,"Copyright (C) 2000 Andreas Dilger Copyright (C) 2000 Theodore Ts'o Copyright (C) 1999 Red Hat Software",c language text,02ef021aec0bea6f3a7377ab72d43491c5866dc5 /e2fsprogs-1.39/e2fsck/mtrace.c,mtrace.c,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Mike Haertel,,,,"Copyright (C) 1991, 1992 Free Software Foundation, Inc. Written April 2, 1991 by John Gilmore of Cygnus Support. Based on mcheck.c by Mike Haertel.",c language text,badc318b64d9485aa965fae4b5c2f954c5001e90 /e2fsprogs-1.39/e2fsck/mtrace.h,mtrace.h,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Mike Haertel,,,,"Copyright 1990, 1991, 1992 Free Software Foundation, Inc. Written May 1989 by Mike Haertel.",c language text,3fd39f30399e003b1de7772173597bdef2993df3 /e2fsprogs-1.39/e2fsck/profile.c,profile.c,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 2005 by Theodore Ts'o. Copyright (C) 1985-2005 by the Massachusetts Institute of Technology.",c language text,87fde75c46dc2248516dda298ef6357ec3a2df6a /e2fsprogs-1.39/e2fsck/profile.h,profile.h,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 2005 by Theodore Ts'o. Copyright (C) 1985-2005 by the Massachusetts Institute of Technology.",c language text,c95dd8d01dc42096b40fa9ac0ee96ce56db61c38 /e2fsprogs-1.39/include/nonunix/getopt.h,getopt.h,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,GNU C Library,,,http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/include/nonunix/getopt.h,"Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.",c language text,2fede7afd8211e66071476da4553a44029be67d5 /e2fsprogs-1.39/install-utils/convfstab,convfstab,,Public Domain,Public Domain,Public Domain,,,,M.Weller,,,http://stuff.mit.edu/afs/sipb.mit.edu/user/tytso/e2fsprogs/install-utils/convfstab,,posix shell script text executable,dde2f47f8abbe15627cd5bfe0e2283fbb820eda6 /e2fsprogs-1.39/intl/,intl,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc.",directory, /e2fsprogs-1.39/lib/blkid/,blkid,,Copyleft Limited,LGPL 2.1,lgpl-2.1,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 2001 Andreas Dilger Copyright (C) 2003 Theodore Ts'o Copyright (C) 1999 by Andries Brouwer",directory, /e2fsprogs-1.39/lib/e2p/,e2p,,Copyleft Limited,LGPL 2.0,lgpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 1992, 1993, 1994 Remy Card Copyright (c) 1999 Theodore Ts",directory, /e2fsprogs-1.39/lib/et/,et,,Attribution,Kerberos License,kerberos,yes,,,Theodore Ts'o,,,,Copyright 2003 by MIT Student Information Processing Board,directory, /e2fsprogs-1.39/lib/et/com_right.c,com_right.c,,Attribution,BSD-Modified,bsd-new,yes,,,Kerberos4kth,,,,"Copyright (c) 2003 by Theodore Ts'o Copyright (c) 1997, 1998, 2001 Kungliga Tekniska Hogskolan",c language text,3d14b06ab31477a1fec4354d8b9f9c82b35896bb /e2fsprogs-1.39/lib/et/texinfo.tex,texinfo.tex,,Copyleft,GPL 2.0,gpl-2.0,yes,yes,yes,Theodore Ts'o,,,,"Copyright (C) 1985, 1986, 1988 Richard M. Stallman",tex language text,1b73dbf5dbc340a945d2bc75f61cc212f5ae3c08 /e2fsprogs-1.39/lib/et/vfprintf.c,vfprintf.c,,Attribution,Berkeley Software License Agreement ,bsla,yes,,,Theodore Ts'o,,,,Copyright (c) 1988 Regents of the University of California,c language text,01a03815e2550f01bbfe0b40c277e0621c52cec1 /e2fsprogs-1.39/lib/fpopen.c,fpopen.c,,Attribution,Berkeley Software License Agreement ,bsla,yes,,,Theodore Ts'o,,,,"Copyright Theodore Ts'o, 1996-1999.",c language text,6bd791a73921839a749fce1086ff1ede0c434ec2 /e2fsprogs-1.39/lib/ss/,ss,,Attribution,Kerberos License,kerberos,yes,,,Theodore Ts'o,,,,Copyright 2003 by MIT Student Information Processing Board,directory, /e2fsprogs-1.39/lib/uuid/,uuid,,Attribution,BSD-Modified,bsd-new,yes,,,Theodore Ts'o,,,,"Copyright (C) 1996, 1997 Theodore Ts'o",directory, /e2fsprogs-1.39/misc/blkid.c,blkid.c,,Copyleft Limited,LGPL 2.1,lgpl-2.1,yes,yes,yes,Theodore Ts'o,,,,Copyright (C) 2001 Andreas Dilger,c language text,6448a75f8212c06bd76f59c6b96024fa94c82f12 \ No newline at end of file diff --git a/example/e2fsprogs-1.39/input/e2fsprogs-1.39-INV.xlsx b/example/e2fsprogs-1.39/input/e2fsprogs-1.39-INV.xlsx index 0905ffb5..28558382 100644 Binary files a/example/e2fsprogs-1.39/input/e2fsprogs-1.39-INV.xlsx and b/example/e2fsprogs-1.39/input/e2fsprogs-1.39-INV.xlsx differ diff --git a/example/e2fsprogs-1.39/input/template_sample_license_ref_by_confirmed_license.html b/example/e2fsprogs-1.39/input/template_sample_license_ref_by_confirmed_license.html new file mode 100644 index 00000000..1b4da6c0 --- /dev/null +++ b/example/e2fsprogs-1.39/input/template_sample_license_ref_by_confirmed_license.html @@ -0,0 +1,66 @@ + + + + + License Reference for e2fsprogs Version 1.39 + + +

License Reference for e2fsprogs Version 1.39

+ + +
+
+ {% for group in about_objects | groupby('confirmed_license') %} +

+ {{ group.grouper }} + +

+ {% endfor %} +
+
+ + {% for group in about_objects | groupby('confirmed_license') %} +
+

{{ group.grouper }}

+

This product contains the following open source software packages licensed under the terms of the license: {{group.grouper}}

+ +
+ {%for about_object in group.list %} + + {% if loop.first %} + {% if about_object.license_url %} +

License Gallery URL: {{about_object.license_url }}

+ {% endif %} + {% endif %} + +
  • {{ about_object.name }}{% if about_object.version %} - Version {{ about_object.version }}{% endif %}
  • + {% if about_object.audit_ref_nbr %}
    Audit Ref Nbr: {{about_object.audit_ref_nbr }} 
    {% endif %} + {% if about_object.copyright %}
    {{about_object.copyright}}
    {% endif %} + {% if about_object.notice %}
    {{ about_object.notice }}
    + {% elif about_object.notice_file %}
    {{ about_object.notice_text }}
    + {% endif %} + {% if loop.last %} +
    +{{about_object.license_text}}
    +		
    + {% endif %} +
    + {% endfor %} +
    + {% endfor %} +
    + +
    +

    End

    + + diff --git a/example/e2fsprogs-1.39/output/sample_attribution_starship.html b/example/e2fsprogs-1.39/output/sample_attribution_starship.html index 84e0827e..4c7fef03 100644 --- a/example/e2fsprogs-1.39/output/sample_attribution_starship.html +++ b/example/e2fsprogs-1.39/output/sample_attribution_starship.html @@ -130,7 +130,6 @@

    e2fsprogs 15-Mar-2003 ---------------------------------------------------------------------- - diff --git a/example/e2fsprogs-1.39/output/sample_license_ref_starship.html b/example/e2fsprogs-1.39/output/sample_license_ref_starship.html new file mode 100644 index 00000000..bd7f9b08 --- /dev/null +++ b/example/e2fsprogs-1.39/output/sample_license_ref_starship.html @@ -0,0 +1,1800 @@ + + + + + License Reference for e2fsprogs Version 1.39 + + +

    License Reference for e2fsprogs Version 1.39

    + + +
    + +
    + + +
    +

    BSD-Modified

    +

    This product contains the following open source software packages licensed under the terms of the license: BSD-Modified

    + +
    + + + + + + +
  • com_right.c
  • + +
    Copyright (c) 2003 by Theodore Ts'o
    +Copyright (c) 1997, 1998, 2001 Kungliga Tekniska Hogskolan
    + + +
    + + + + +
  • uuid
  • + +
    Copyright (C) 1996, 1997 Theodore Ts'o
    + + +
    +Copyright (c) {{YEAR}}, {{OWNER}} 
    +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 ORGANIZATION nor the names of its contributors}} may be used to endorse or promote products derived from this software without specific prior written permission. 
    +
    +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.
    +
    +		
    + +
    + + + +
    +

    Berkeley Software License Agreement

    +

    This product contains the following open source software packages licensed under the terms of the license: Berkeley Software License Agreement

    + +
    + + + + + + +
  • vfprintf.c
  • + +
    Copyright (c) 1988 Regents of the University of California
    + + +
    + + + + +
  • fpopen.c
  • + +
    Copyright Theodore Ts'o, 1996-1999.
    + + +
    +* Copyright (c) 1983 Regents of the University of California. 
    +* All rights reserved. 
    +* 
    +* Redistribution and use in source and binary forms are permitted 
    +* provided that the above copyright notice and this paragraph are 
    +* duplicated in all such forms and that any documentation, 
    +* advertising materials, and other materials related to such 
    +* distribution and use acknowledge that the software was developed 
    +* by the University of California, Berkeley. The name of the 
    +* University may not be used to endorse or promote products derived 
    +* from this software without specific prior written permission. 
    +* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 
    +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 
    +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
    +
    +		
    + +
    + + + +
    +

    GPL 2.0

    +

    This product contains the following open source software packages licensed under the terms of the license: GPL 2.0

    + +
    + + + + + + +
  • e2fsprogs - Version 1.39
  • + +
    Copyright (c) 1997-2004 Theodore Ts'o
    +
    This package, the EXT2 filesystem utilities, are made available under
    +the GNU Public License, with the exception of the lib/uuid directory
    +which is made available under a BSD-style license.  Please see
    +lib/uuid/COPYING for more details for the license for the files
    +comprising the libuuid library.
    +
    +However, I request that if the version string in the file version.h
    +contains the string "pre-", or "WIP" that this version of e2fsprogs be
    +distributed in source form only.  Please feel free to give a copy of
    +the e2fsck binary to help a friend recover his or her filesystem, as
    +the need arises.  However, "pre" or "WIP" indicates that this release
    +is under development, and available for ALPHA testing.  So for your
    +protection as much as mine, I'd prefer that it not appear in a some
    +distribution --- especially not a CD-ROM distribution!
    +
    +The most recent officially distributed version can be found at
    +http://e2fsprogs.sourceforge.net.  If you need to make a distribution,
    +that's the one you should use.  If there is some reason why you'd like
    +a more recent version that is still in ALPHA testing for your
    +distribution, please contact me (tytso@mit.edu), and we will very
    +likely be able to work out something that will work for all concerned.
    +The release schedules for this package are flexible, if you give me
    +enough lead time.
    +
    +					Theodore Ts'o
    +					15-Mar-2003
    +
    +----------------------------------------------------------------------
    +
    + + +
    + + + + +
  • journal.c
  • + +
    Copyright (C) 2000 Andreas Dilger
    +Copyright (C) 2000 Theodore Ts'o
    +Copyright (C) 1999 Red Hat Software
    + + +
    + + + + +
  • profile.c
  • + +
    Copyright (C) 2005 by Theodore Ts'o.
    +Copyright (C) 1985-2005 by the Massachusetts Institute of Technology.
    + + + + + + + +
  • profile.h
  • + +
    Copyright (C) 2005 by Theodore Ts'o.
    +Copyright (C) 1985-2005 by the Massachusetts Institute of Technology.
    + + + + + + + +
  • texinfo.tex
  • + +
    Copyright (C) 1985, 1986, 1988 Richard M. Stallman
    + + +
    +GNU GENERAL PUBLIC LICENSE
    +Version 2, June 1991
    +
    +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    +
    +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
    +
    + Preamble
    +
    +The licenses for most software are designed to take away your freedom to share and change it.  By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.  This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it.  (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.)  You can apply it to your programs, too.
    +
    +When we speak of free software, we are referring to freedom, 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 or use pieces of it in new free programs; and that you know you can do these things.
    +
    +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
    +
    +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have.  You must make sure that they, too, receive or can get the source code.  And you must show them these terms so they know their rights.
    +
    +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
    +
    +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software.  If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
    +
    +Finally, any free program is threatened constantly by software patents.  We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary.  To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
    +
    +The precise terms and conditions for copying, distribution and modification follow.
    +
    +GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    +
    +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License.  The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language.  (Hereinafter, translation is included without limitation in the term "modification".)  Each licensee is addressed as "you".
    +
    +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope.  The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
    +
    +1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program.
    +
    +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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
    +
    +  b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
    +
    +  c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License.  (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
    +
    +These requirements apply to the modified work as a whole.  If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program.
    +
    +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
    +
    +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
    +
    +  a) 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; or,
    +
    +  b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    +
    +  c) Accompany it with the information you received as to the offer to distribute corresponding source code.  (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
    +
    +The source code for a work means the preferred form of the work for making modifications to it.  For an executable work, 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 executable.  However, as a special exception, the source code 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.
    +
    +If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
    +
    +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License.  Any attempt otherwise to copy, modify, sublicense or distribute the Program 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.
    +
    +5. 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 Program or its derivative works.  These actions are prohibited by law if you do not accept this License.  Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
    +
    +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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 to this License.
    +
    +7. 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 Program at all.  For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program.
    +
    +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.
    +
    +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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.
    +
    +9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
    +
    +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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
    +
    +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
    +
    +12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 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 Programs
    +
    +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
    +
    +To do so, attach the following notices to the program.  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 program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
    +
    +This program 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 General Public License for more details.
    +
    +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    +
    +Also add information on how to contact you by electronic and paper mail.
    +
    +If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
    +
    +Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
    +
    +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License.  Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
    +
    +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary.  Here is a sample; alter the names:
    +
    +Yoyodyne, Inc., hereby disclaims all copyright interest in the program   `Gnomovision' (which makes passes at compilers) written by James Hacker.
    +
    +, 1 April 1989   Ty Coon, President of Vice
    +
    +This General Public License does not permit incorporating your program into proprietary programs.  If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library.  If this is what you want to do, use the GNU Library General Public License instead of this License.
    +
    +		
    + + + + + +
    +

    GPL 2.0 with Autoconf exception

    +

    This product contains the following open source software packages licensed under the terms of the license: GPL 2.0 with Autoconf exception

    + +
    + + + + + + +
  • config.guess
  • + +
    Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    + + +
    + + + + +
  • config.rpath
  • + +
    Copyright 1996-2002 Free Software Foundation, Inc.
    + + +
    + + + + +
  • config.sub
  • + +
    Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    + + +
    +This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, 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 General Public License for more details.
    +
    +You should have received a copy of the GNU General Public License along with this library; see the file COPYING.  If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    +
    +As a special exception to the GNU General Public License, if you distribute this file as part of a program that contains a configuration script generated by Autoconf, you may include it under the same distribution terms that you use for the rest of that program.
    +		
    + + + + + +
    +

    Kaz Kylheku License

    +

    This product contains the following open source software packages licensed under the terms of the license: Kaz Kylheku License

    + +
    + + + + + + +
  • dict.c
  • + +
    Copyright (C) 1997 Kaz Kylheku 
    + + +
    + + + + +
  • dict.h
  • + +
    Copyright (C) 1997 Kaz Kylheku 
    + + +
    +Copyright (C) 1997 Kaz Kylheku 
    +
    +Free Software License:
    +
    +All rights are reserved by the author, with the following exceptions:
    +Permission is granted to freely reproduce and distribute this software,
    +possibly in exchange for a fee, provided that this copyright notice appears
    +intact. Permission is also granted to adapt this software to produce
    +derivative works, as long as the modified versions carry this copyright
    +notice and additional notices stating that the work has been modified.
    +This source code may be translated into executable form and incorporated
    +into proprietary software; there is no requirement for such software to
    +contain a copyright notice related to this source.
    +
    +
    +		
    + +
    + + + +
    +

    Kerberos License

    +

    This product contains the following open source software packages licensed under the terms of the license: Kerberos License

    + +
    + + + + + + +
  • et
  • + +
    Copyright 2003 by MIT Student Information Processing Board
    + + +
    + + + + +
  • ss
  • + +
    Copyright 2003 by MIT Student Information Processing Board
    + + +
    +Kerberos License 
    +
    +Copyright @copyright{} 1985-2002 by the Massachusetts Institute of Technology.
    +
    +Export of software employing encryption from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.
    +
    +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original MIT software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided ``as is'' without express or implied warranty.
    +
    +The following copyright and permission notice applies to the OpenVision Kerberos Administration system located in kadmin/create, kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions of lib/rpc:
    +
    +Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved
    +
    +WARNING: Retrieving the OpenVision Kerberos Administration system source code, as described below, indicates your acceptance of the following terms. If you do not agree to the following terms, do not retrieve the
    +
    +OpenVision Kerberos administration system.
    +
    +You may freely use and distribute the Source Code and Object Code compiled from it, with or without modification, but this Source Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED.	IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY OTHER REASON.
    +
    +OpenVision retains all copyrights in the donated Source Code. OpenVision also retains copyright to derivative works of the Source Code, whether created by OpenVision or by a third party. The OpenVision copyright notice must be preserved if derivative works are made based on the donated Source Code.
    +
    +OpenVision Technologies, Inc. has donated this Kerberos Administration system to MIT for inclusion in the standard Kerberos 5 distribution. This donation underscores our commitment to continuing
    +
    +Kerberos technology development and our gratitude for the valuable work which has been performed by MIT and the Kerberos community.
    +
    +The implementation of the Yarrow pseudo-random number generator in src/lib/crypto/yarrow has the following copyright:
    +
    +Copyright 2000 by Zero-Knowledge Systems, Inc.
    +
    +Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Zero-Knowledge Systems, Inc. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Zero-Knowledge Systems, Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
    +
    +ZERO-KNOWLEDGE SYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ZERO- KNOWLEDGE SYSTEMS, INC. BE LIABLE FOR 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 TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    +
    +The implementation of the AES encryption algorithm in src/lib/crypto/aes has the following copyright: Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. All rights reserved. LICENSE TERMS
    +
    +The free distribution and use of this software in both source and binary form is allowed (with or without changes) provided that:
    +
    +distributions of this source code include the above copyright notice, this list of conditions and the following disclaimer;
    +
    +distributions in binary form include the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other associated materials;
    +
    +the copyright holder's name is not used to endorse products built using this software without specific written permission.
    +
    +DISCLAIMER
    +
    +This software is provided 'as is' with no explcit or implied warranties in respect of any properties, including, but not limited to, correctness and fitness for purpose. University of California at Berkeley, which includes this copyright notice:
    +
    +Copyright @copyright{} 1983 Regents of the University of California.@* 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.
    +
    +All advertising materials mentioning features or use of this software must display the following acknowledgement:
    +
    +This product includes software developed by the University of California, Berkeley and its contributors.
    +
    +Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
    +
    +		
    + +
    + + + +
    +

    LGPL 2.0

    +

    This product contains the following open source software packages licensed under the terms of the license: LGPL 2.0

    + +
    + + + + + + +
  • mtrace.c
  • + +
    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
    +Written April 2, 1991 by John Gilmore of Cygnus Support.
    +Based on mcheck.c by Mike Haertel.
    + + +
    + + + + +
  • mtrace.h
  • + +
    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
    +Written May 1989 by Mike Haertel.
    + + +
    + + + + +
  • getopt.h
  • + +
    Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
    + + + + + + + +
  • intl
  • + +
    Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc.
    + + + + + + + +
  • e2p
  • + +
    Copyright (C) 1992, 1993, 1994  Remy Card
    +Copyright (c) 1999 Theodore Ts
    + + +
    +		  GNU LIBRARY GENERAL PUBLIC LICENSE
    +		       Version 2, June 1991
    +
    + Copyright (C) 1991 Free Software Foundation, Inc.
    + 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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 library GPL.  It is
    + numbered 2 because it goes with version 2 of the ordinary GPL.]
    +
    +			    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 Library General Public License, applies to some
    +specially designated Free Software Foundation software, and to any
    +other libraries whose authors decide to use it.  You can use it for
    +your libraries, too.
    +
    +  When we speak of free software, we are referring to freedom, 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 or use pieces of it
    +in new free programs; and that you know you can do these things.
    +
    +  To protect your rights, we need to make restrictions that forbid
    +anyone to deny you these rights or to ask you to surrender the 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 a program 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.
    +
    +  Our method of protecting your rights has two steps: (1) copyright
    +the library, and (2) offer you this license which gives you legal
    +permission to copy, distribute and/or modify the library.
    +
    +  Also, for each distributor's protection, we want to make certain
    +that everyone understands that there is no warranty for this free
    +library.  If the library is modified by someone else and passed on, we
    +want its recipients to know that what they have is not the original
    +version, so that any problems introduced by others will not reflect on
    +the original authors' reputations.
    +
    +  Finally, any free program is threatened constantly by software
    +patents.  We wish to avoid the danger that companies distributing free
    +software will individually obtain patent licenses, thus in effect
    +transforming the program into proprietary software.  To prevent this,
    +we have made it clear that any patent must be licensed for everyone's
    +free use or not licensed at all.
    +
    +  Most GNU software, including some libraries, is covered by the ordinary
    +GNU General Public License, which was designed for utility programs.  This
    +license, the GNU Library General Public License, applies to certain
    +designated libraries.  This license is quite different from the ordinary
    +one; be sure to read it in full, and don't assume that anything in it is
    +the same as in the ordinary license.
    +
    +  The reason we have a separate public license for some libraries is that
    +they blur the distinction we usually make between modifying or adding to a
    +program and simply using it.  Linking a program with a library, without
    +changing the library, is in some sense simply using the library, and is
    +analogous to running a utility program or application program.  However, in
    +a textual and legal sense, the linked executable is a combined work, a
    +derivative of the original library, and the ordinary General Public License
    +treats it as such.
    +
    +  Because of this blurred distinction, using the ordinary General
    +Public License for libraries did not effectively promote software
    +sharing, because most developers did not use the libraries.  We
    +concluded that weaker conditions might promote sharing better.
    +
    +  However, unrestricted linking of non-free programs would deprive the
    +users of those programs of all benefit from the free status of the
    +libraries themselves.  This Library General Public License is intended to
    +permit developers of non-free programs to use free libraries, while
    +preserving your freedom as a user of such programs to change the free
    +libraries that are incorporated in them.  (We have not seen how to achieve
    +this as regards changes in header files, but we have achieved it as regards
    +changes in the actual functions of the Library.)  The hope is that this
    +will lead to faster development of free libraries.
    +
    +  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, while the latter only
    +works together with the library.
    +
    +  Note that it is possible for a library to be covered by the ordinary
    +General Public License rather than by this special one.
    +
    +		  GNU LIBRARY GENERAL PUBLIC LICENSE
    +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    +
    +  0. This License Agreement applies to any software library which
    +contains a notice placed by the copyright holder or other authorized
    +party saying it may be distributed under the terms of this Library
    +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 compile 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) 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.
    +
    +    c) 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.
    +
    +    d) 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 source code 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 to
    +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 Library 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 Library General Public
    +    License as published by the Free Software Foundation; either
    +    version 2 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
    +    Library General Public License for more details.
    +
    +    You should have received a copy of the GNU Library General Public
    +    License along with this library; if not, write to the Free
    +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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!
    +
    +		
    + + + + + +
    +

    LGPL 2.1

    +

    This product contains the following open source software packages licensed under the terms of the license: LGPL 2.1

    + +
    + + + + + + +
  • blkid
  • + +
    Copyright (C) 2001 Andreas Dilger
    +Copyright (C) 2003 Theodore Ts'o
    +Copyright (C) 1999 by Andries Brouwer
    + + +
    + + + + +
  • blkid.c
  • + +
    Copyright (C) 2001 Andreas Dilger
    + + +
    +                  GNU LESSER GENERAL PUBLIC LICENSE
    +                       Version 2.1, February 1999
    +
    + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    + 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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, Fifth Floor, Boston, MA  02110-1301  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!
    +		
    + +
    + + + +
    +

    MIT Old Style legal 2

    +

    This product contains the following open source software packages licensed under the terms of the license: MIT Old Style legal 2

    + +
    + + + + + + +
  • argv_parse.c
  • + +
    Copyright 1999 by Theodore Ts'o
    + + +
    + + + + +
  • argv_parse.h
  • + +
    Copyright 1999 by Theodore Ts'o
    + + +
    +Copyright (c) {{year}} {{copyright holders}}
    +
    +Permission to use, copy, modify, and distribute this software for any
    +purpose with or without fee is hereby granted, provided that the above
    +copyright notice and this permission notice appear in all copies.
    +
    +The software is provided "as is" and the author disclaims all warranties
    +with regard to this software including all implied warranties of
    +merchantability and fitness. In no event shall the author be liable for
    +any special, direct, 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 this software.
    +		
    + +
    + + + +
    +

    Public Domain

    +

    This product contains the following open source software packages licensed under the terms of the license: Public Domain

    + +
    + + + + + + +
  • alocal.m4
  • + +
    Copyright (c) 1995-2003 Free Software Foundation, Inc.
    + + +
    + + + + +
  • mkinstalldirs
  • + + + + +
    + + + + +
  • convfstab
  • + + + + +
    +Public Domain
    +		
    + + + + + +
    +

    Ulrich Windl License

    +

    This product contains the following open source software packages licensed under the terms of the license: Ulrich Windl License

    + +
    + + + + + + +
  • dconf
  • + +
    Copyright (c) 1994 Ulrich Windl
    + + +
    +# Create Adobe-PostScript file that graphically displays the output of
    +# dumpe2fs(8). Use "dumpe2fs | dconf" to create a PostScript file on stdout.
    +# Developed and tested for Linux 1.0.
    +# Copyright (c) 1994
    +# Ulrich Windl
    +# ALte Regensburger Strasse 11a
    +# D-93149 Nittenau, Germany
    +# 
    +
    +		
    + +
    + +
    + +
    + +
    +

    End

    + + \ No newline at end of file diff --git a/setup.py b/setup.py index 712e0a37..8ffdb2d0 100644 --- a/setup.py +++ b/setup.py @@ -5,12 +5,12 @@ from setuptools import setup -from about_code_tool import about +import about_code_tool.help setup( name='about-code-tool', - version=about.__version__, + version=about_code_tool.help.__version__, description=('Document the provenance (origin and license) of ' 'third-party software. Collect inventories, generate ' 'attribution docs.'), @@ -51,4 +51,5 @@ 'Topic :: System :: Software Distribution', 'Topic :: Utilities', ], + install_requires=['jinja2 >= 2.7.3, < 3.0.0',] )