Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
99e7cfe
Correct documentation typo
pombredanne Dec 5, 2018
9d460a2
Add attrs to dependencies
pombredanne Dec 5, 2018
952e54e
Use attr for models #361
pombredanne Dec 10, 2018
9a41ed8
Abstract location details from tests
pombredanne Dec 10, 2018
a8b9108
Do not use UNC prefixes anymore #382
pombredanne Dec 10, 2018
f28c1bc
Streamline subcommand short help
pombredanne Dec 10, 2018
d30eb46
Do not use UNC anywhere #382
pombredanne Dec 10, 2018
2d4532c
Test longpaths only on Python3.6 for Windows #382
pombredanne Dec 10, 2018
eb7acf5
Remove failing IRC notification
pombredanne Dec 10, 2018
ac352e8
Bump version to v4.x
pombredanne Dec 11, 2018
05cd123
Do not fail if CSV contains non-UTF mojibake
pombredanne Dec 13, 2018
0a11887
Make fetching and saving license references work
pombredanne Dec 13, 2018
4eb5f65
Improve handling of fetched license with no texts
pombredanne Dec 14, 2018
dae1c6d
Reorder fields. Improve conversion on init
pombredanne Dec 14, 2018
cfc597f
Add option to check files existence
pombredanne Dec 14, 2018
a7cfcb4
Accept non-utf license and notice files
pombredanne Dec 14, 2018
ca8b906
Also support vartext in attrib templates
pombredanne Dec 14, 2018
1f017c2
Improve error handling
pombredanne Dec 15, 2018
4eafee8
Fix spacing
pombredanne Dec 15, 2018
f2f183f
Improve error handling
pombredanne Dec 15, 2018
572cbd8
Ensure About objects are sorted in attribution
pombredanne Dec 15, 2018
537f351
Ensure that attribution generation uses autoescape
pombredanne Dec 16, 2018
d967c0a
Add validation for API URLs
pombredanne Dec 16, 2018
e42b506
Update common licenses list
pombredanne Dec 16, 2018
452d57b
Update docstring
pombredanne Dec 16, 2018
8a01834
Update template with latest field names
pombredanne Dec 16, 2018
3d99667
Allw single space flag values and strip paths
pombredanne Dec 17, 2018
d7125f4
Update transform doc
pombredanne Dec 17, 2018
f5cc72b
Ensure vartext are not lists but single values
pombredanne Dec 17, 2018
e1a25cb
Align field names with ScanCode
pombredanne Dec 26, 2018
efe6ef7
Return an error if a file or dir is not readable #17
pombredanne Dec 27, 2018
affe69f
Allow to run about command from anywhere #205
pombredanne Dec 27, 2018
66297c8
Restore about_file_path field
pombredanne Dec 27, 2018
21b42ac
Rename attributecode module to aboutcode #347
pombredanne Dec 27, 2018
32d70df
Update spec to v4.x
pombredanne Dec 27, 2018
055b0e4
Fix merge conflicts
pombredanne Dec 27, 2018
24d52cc
Add hashable() method to get hashable object data
pombredanne Dec 28, 2018
8d6f0d2
Fix help text for fetch-licenses Cli command
pombredanne Dec 28, 2018
3d5c380
Do not recompute to_posix() in the loop
pombredanne Dec 28, 2018
3d39f76
Add unique_packages as data available to templates.
pombredanne Dec 28, 2018
583e855
Do not keep backward compatibility for module name
pombredanne Dec 28, 2018
b3d7640
Rename "abouts" to "packages"
pombredanne Dec 28, 2018
b08556b
Rename about to package
pombredanne Dec 28, 2018
de866f1
Ensure License.key is required
pombredanne Dec 29, 2018
a19e6e7
Clarify default Package sort order
pombredanne Dec 29, 2018
0ba795f
Rename Package.location to about_file_location
pombredanne Dec 29, 2018
c0bd968
Improve repr of Errors
pombredanne Dec 31, 2018
a55b178
Allow to generate ABOUT files without about_file_path
pombredanne Jan 1, 2019
8ac7532
Allow to generate ABOUT files without about_file_path
pombredanne Jan 1, 2019
c26eb8d
Remove --quiet option from command line
pombredanne Jan 1, 2019
7b4491f
Convert dump(location) to POSIX
pombredanne Jan 1, 2019
f11c125
Refine path handling for Windows
pombredanne Jan 1, 2019
2683256
Handle paths with leading/trailing spaces in segment
pombredanne Jan 2, 2019
41fe472
Format code
pombredanne Jan 2, 2019
ae465a1
Use simpler constructor for Transformer
pombredanne Jan 2, 2019
9387971
Add tests for required_columns in transform #388
pombredanne Jan 2, 2019
950df78
Format code
pombredanne Jan 2, 2019
c85f93e
Sort error message data for stable results
pombredanne Jan 2, 2019
59c9626
Add support for older ABOUT gen format
pombredanne Jan 2, 2019
c8bbf67
Make custom fields available as direct instance attributes.
pombredanne Jan 2, 2019
959a998
Add unique_licenses to available data in template
pombredanne Jan 2, 2019
de62441
Add new attrib option to compute unique ABOUT entries
pombredanne Jan 2, 2019
aeb34e1
Report proper error message with license key
pombredanne Jan 3, 2019
01a0694
Use licenses as name of data passed to attrib template
pombredanne Jan 3, 2019
a48f377
Update help text
pombredanne Jan 3, 2019
7b52ed8
Add new custom Jinja template filters (sort and unique)
pombredanne Jan 3, 2019
d18495a
Add attrib CLI option for template creation help
pombredanne Jan 3, 2019
a48154a
Move extr filters to attrib_util.py
pombredanne Jan 3, 2019
00b21ca
Move get_template() to attrib_util.py
pombredanne Jan 3, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
385 changes: 152 additions & 233 deletions SPECIFICATION.rst

Large diffs are not rendered by default.

118 changes: 107 additions & 11 deletions about
Original file line number Diff line number Diff line change
@@ -1,19 +1,115 @@
#!/bin/bash
#
# Copyright (c) 2015 nexB Inc. http://www.nexb.com/ - All rights reserved.
# Copyright (c) 2018 nexB Inc. http://www.nexb.com/ - All rights reserved.
#

# cd to the root directory
ABOUT_ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$ABOUT_ROOT_DIR"
# A minimal shell wrapper to the CLI entry point of AboutCode

CONFIGURED_PYTHON=$ABOUT_ROOT_DIR/bin/python

if [ ! -f "$CONFIGURED_PYTHON" ]; then
echo "* Configuring AboutCode ..."
source $ABOUT_ROOT_DIR/configure
fi
###################################################################################
# from https://raw.githubusercontent.com/mkropat/sh-realpath/58c03982cfd8accbcf0c4426a4adf0f120a8b2bb/realpath.sh
# realpath emulation for portability on *nix
# this allow running scancode from aribtrary locations and from symlinks
#
# Copyright (c) 2014 Michael Kropat
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

realpath() {
canonicalize_path "$(resolve_symlinks "$1")"
}

resolve_symlinks() {
_resolve_symlinks "$1"
}

_resolve_symlinks() {
_assert_no_path_cycles "$@" || return

local dir_context path
path=$(readlink -- "$1")
if [ $? -eq 0 ]; then
dir_context=$(dirname -- "$1")
_resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@"
else
printf '%s\n' "$1"
fi
}

_prepend_dir_context_if_necessary() {
if [ "$1" = . ]; then
printf '%s\n' "$2"
else
_prepend_path_if_relative "$1" "$2"
fi
}

_prepend_path_if_relative() {
case "$2" in
/* ) printf '%s\n' "$2" ;;
* ) printf '%s\n' "$1/$2" ;;
esac
}

source $ABOUT_ROOT_DIR/bin/activate
_assert_no_path_cycles() {
local target path

target=$1
shift

for path in "$@"; do
if [ "$path" = "$target" ]; then
return 1
fi
done
}

canonicalize_path() {
if [ -d "$1" ]; then
_canonicalize_dir_path "$1"
else
_canonicalize_file_path "$1"
fi
}

_canonicalize_dir_path() {
(cd "$1" 2>/dev/null && pwd -P)
}

_canonicalize_file_path() {
local dir file
dir=$(dirname -- "$1")
file=$(basename -- "$1")
(cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file")
}

###################################################################################
# Now run AboutCode "about" proper

ABOUTCODE_BIN="$( realpath "${BASH_SOURCE[0]}" )"
ABOUTCODE_ROOT_DIR="$( cd "$( dirname "${ABOUTCODE_BIN}" )" && pwd )"


ABOUTCODE_CONFIGURED_PYTHON="$ABOUTCODE_ROOT_DIR/bin/python"
if [ ! -f "$ABOUTCODE_CONFIGURED_PYTHON" ]; then
echo "* Configuring AboutCode for first use..."
CONFIGURE_QUIET=1 "$ABOUTCODE_ROOT_DIR/configure" etc/conf
fi

$ABOUT_ROOT_DIR/bin/about "$@"
"$ABOUTCODE_ROOT_DIR/bin/about" "$@"
11 changes: 6 additions & 5 deletions about.ABOUT
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ about_resource: .
name: AboutCode-toolkit
about_resource_path: .

version: 3.0.0.dev6

description: |
AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file
provides a simple way to document the provenance (origin and license)
Expand All @@ -12,9 +10,12 @@ description: |

homepage_url: http://www.nexb.com/community.html

license: apache-2.0
license_name: Apache 2.0
license_file: apache-2.0.LICENSE
license_expression: apache-2.0
licenses:
- key: apache-2.0
name: Apache 2.0
file: apache-2.0.LICENSE

copyright: Copyright (c) 2013-2017 nexB Inc.

notice_file: NOTICE
Expand Down
6 changes: 0 additions & 6 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,3 @@ build: off
test_script:
- set
- py.test -vvs tests

on_success:
- "python etc/scripts/irc-notify.py aboutcode [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_green}Succeeded,Details: {build_url},Commit: {commit_url}"

on_failure:
- "python etc/scripts/irc-notify.py aboutcode [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}"
4 changes: 4 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ if [[ "$PYTHON_EXE" == "" ]]; then
PYTHON_EXE=python
fi


$PYTHON_EXE "$CONFIGURE_ROOT_DIR/etc/configure.py" $CFG_CMD_LINE_ARGS
if [ -f "$CONFIGURE_ROOT_DIR/bin/activate" ]; then
source $CONFIGURE_ROOT_DIR/bin/activate
fi
3 changes: 1 addition & 2 deletions configure.bat
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ set ABOUT_ROOT_DIR=%~dp0
@rem there is a space at the end of the set SCANCODE_CLI_ARGS= line ...
@rem NEVER remove this!
@rem otherwise, this script and scancode do not work.

set ABOUT_CLI_ARGS=
@rem Collect/Slurp all command line arguments in a variable
:collectarg
Expand All @@ -42,7 +41,7 @@ if not exist "c:\python27\python.exe" (
echo(
echo On Windows, AboutCode requires Python 2.7.x 32 bits to be installed first.
echo(
echo Please download and install Python 2.7 ^(Windows x86 MSI installer^) version 2.7.10.
echo Please download and install Python 2.7 ^(Windows x86 MSI installer^) version 2.7.15.
echo Install Python on the c: drive and use all default installer options.
echo Do NOT install Python v3 or any 64 bits edition.
echo Instead download Python from this url and see the README.rst file for more details:
Expand Down
24 changes: 16 additions & 8 deletions etc/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,22 @@ 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()

cleanable = '''
__pycache__
.pytest_cache
build
bin
lib
Lib
include
Include
Scripts
local
.eggs
.cache
pip-selfcheck.json
src/aboutcode_toolkit.egg-info
'''.split()
# also clean __pycache__ if any
cleanable.extend(find_pycache(root_dir))

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ universal = 1
license_file = NOTICE

[aliases]
release = clean --all sdist --formats=bztar,zip bdist_wheel
release = clean --all sdist bdist_wheel

[tool:pytest]
norecursedirs =
Expand Down
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ def read(*names, **kwargs):

setup(
name='aboutcode-toolkit',
version='3.4.0.pre1',
version='4.0.0.pre1',
license='Apache-2.0',
description=(
'AboutCode-toolkit is a tool to document the provenance (origin and license) of '
'third-party software using small text files. '
'Collect inventories, generate attribution documentation.'
),
long_description=(
'AttributeCode provides a simple way to document the'
'AboutCode toolkit provides a simple way to document the'
'provenance (i.e. origin and license) of software components that'
'you use in your project. This documentation is stored in *.ABOUT'
'files, side-by-side with the documented code.'
Expand Down Expand Up @@ -79,13 +79,15 @@ def read(*names, **kwargs):

'boolean.py >= 3.5, < 4.0',
'license_expression >= 0.94, < 1.0',

'attrs',
],
extras_require={
":python_version < '3.6'": ['backports.csv'],
},
entry_points={
'console_scripts': [
'about=attributecode.cmd:about',
'about=aboutcode.cmd:about',
]
},
)
96 changes: 48 additions & 48 deletions src/attributecode/__init__.py → src/aboutcode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@
from __future__ import print_function
from __future__ import unicode_literals

from collections import namedtuple
import logging
from collections import OrderedDict
import os

import attr
import saneyaml

try:
# Python 2
unicode # NOQA
except NameError: # pragma: nocover
# Python 3
unicode = str # NOQA

import saneyaml

__version__ = '3.4.0.pre1'
__version__ = '4.0.0.pre1'

__about_spec_version__ = '3.1'
__about_spec_version__ = '4.0'

__copyright__ = """
Copyright (c) 2013-2018 nexB Inc. All rights reserved. http://dejacode.org
Expand All @@ -49,63 +50,62 @@
"""


class Error(namedtuple('Error', ['severity', 'message'])):
"""
An Error data with a severity and message.
"""
def __new__(self, severity, message):
if message:
if isinstance(message, unicode):
message = self._clean_string(message)
else:
message = self._clean_string(unicode(repr(message), encoding='utf-8'))
message = message.strip('"')

return super(Error, self).__new__(
Error, severity, message)
def message_converter(value):
if value:
if isinstance(value, unicode):
value = clean_string(value)
else:
value = clean_string(unicode(repr(value), encoding='utf-8'))
value = value.strip('"')
return value

def __repr__(self, *args, **kwargs):
sev, msg = self._get_values()
return 'Error(%(sev)s, %(msg)s)' % locals()

def __eq__(self, other):
return repr(self) == repr(other)
@attr.attributes(repr=False)
class Error(object):
"""
An Error data with a severity and message and an optional path attribute.
"""
severity = attr.attrib()
message = attr.attrib(converter=message_converter)
# relative POSIX path of the ABOUT file
path = attr.attrib(default=None) # , repr=False)

def _get_values(self):
def __repr__(self):
sev = severities[self.severity]
msg = self._clean_string(repr(self.message))
return sev, msg
msg = clean_string(repr(self.message))
return 'Error(%(sev)s, %(msg)s)' % locals()

def render(self):
sev, msg = self._get_values()
sev = severities[self.severity]
msg = clean_string(repr(self.message))
return '%(sev)s: %(msg)s' % locals()

def to_dict(self, *args, **kwargs):
"""
Return an ordered dict of self.
"""
return self._asdict()
return attr.asdict(self, dict_factory=OrderedDict)

@staticmethod
def _clean_string(s):
"""
Return a cleaned string for `s`, stripping eventual "u" prefixes
from unicode representations.
"""
if not s:
return s
if s.startswith(('u"', "u'")):
s = s.lstrip('u')
s = s.replace('[u"', '["')
s = s.replace("[u'", "['")
s = s.replace("(u'", "('")
s = s.replace("(u'", "('")
s = s.replace("{u'", "{'")
s = s.replace("{u'", "{'")
s = s.replace(" u'", " '")
s = s.replace(" u'", " '")
s = s.replace("\\\\", "\\")

def clean_string(s):
"""
Return a cleaned string for `s`, stripping eventual "u" prefixes
from unicode representations.
"""
if not s:
return s
if s.startswith(('u"', "u'")):
s = s.lstrip('u')
s = s.replace('[u"', '["')
s = s.replace("[u'", "['")
s = s.replace("(u'", "('")
s = s.replace("(u'", "('")
s = s.replace("{u'", "{'")
s = s.replace("{u'", "{'")
s = s.replace(" u'", " '")
s = s.replace(" u'", " '")
s = s.replace("\\\\", "\\")
return s


# modeled after the logging levels
Expand Down
Loading