Skip to content

Commit 6da0108

Browse files
committed
Merge pull request #6 from pombredanne/issue_4_extract_is_exclusive
Reject running scancode --extract with other options.
2 parents ab51c73 + 2b282b8 commit 6da0108

File tree

6 files changed

+164
-8
lines changed

6 files changed

+164
-8
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ install:
77
- source configure
88

99
script:
10-
- py.test -n 2 -vs src tests/commoncode tests/extractcode tests/textcode tests/typecode tests/cluecode tests/licensedcode/test_detect.py tests/licensedcode/test_index.py tests/licensedcode/test_legal.py tests/licensedcode/test_models.py
10+
- py.test -n 2 -vs src tests/commoncode tests/extractcode tests/textcode tests/typecode tests/cluecode tests/scancode tests/licensedcode/test_detect.py tests/licensedcode/test_index.py tests/licensedcode/test_legal.py tests/licensedcode/test_models.py
1111

src/scancode/cli.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
from scancode.api import get_licenses
4040
from scancode.api import HtmlAppAssetCopyWarning
4141
from scancode.api import HtmlAppAssetCopyError
42-
import textwrap
4342

4443

4544
info_text = '''
@@ -187,19 +186,23 @@ def print_version(ctx, param, value):
187186
'''
188187

189188

189+
short_help = '''Usage: scancode [OPTIONS] <input> <output_file>
190+
Try 'scancode --help' for more information.'''
191+
192+
190193
formats = ['json', 'html', 'html-app']
191194

195+
192196
class ScanCommand(click.Command):
193197
"""
194198
Workaround click 4.0 bug https://github.com/mitsuhiko/click/issues/365
195199
"""
196200
def get_usage(self, ctx):
197-
formatted = '''Usage: scancode [OPTIONS] <input> <output_file>
198-
Try 'scancode --help' for more information'''
199-
return formatted
201+
return short_help
200202

201203

202204
@click.command(name='scancode', epilog=epilog_text, cls=ScanCommand)
205+
@click.pass_context
203206
@click.argument('input', metavar='<input>', type=click.Path(exists=True, readable=True))
204207
@click.argument('output_file', default='-', metavar='<output_file>', type=click.File('wb'))
205208
@click.option('-c', '--copyright', is_flag=True, default=False, help='Scan <input> for copyrights. [default]')
@@ -218,23 +221,30 @@ def get_usage(self, ctx):
218221
@click.option('--verbose', is_flag=True, default=False, help='Show verbose scan progress messages.')
219222
@click.option('--version', is_flag=True, is_eager=True, callback=print_version,
220223
help=('Show the version and exit.'))
221-
def scancode(input, output_file, extract, copyright, license, format, verbose, *args, **kwargs):
224+
def scancode(ctx, input, output_file, extract, copyright, license, format, verbose, *args, **kwargs):
222225
"""scan the <input> file or directory for origin and license and save results to the <output_file>.
223226
224227
The scan results are printed on terminal if <output_file> is not provided.
225228
"""
229+
scans = [copyright, license]
226230
if extract:
231+
if any(scans):
232+
# exclusive, ignoring other options.
233+
# FIXME: this should turned into a sub-command
234+
ctx.fail('''The '--extract' option cannot be combined with other scanning options.
235+
Use '--extract' alone to extract <input>, then run a scan on the extracted files.''')
236+
ctx.exit(1)
237+
227238
click.secho('Extracting archives...', fg='green')
228239
extract_errors = get_extract(input)
229240
if extract_errors:
230241
# FIXME: Provide a better way to report errors and we need to report progress
231242
click.secho('\n'.join(extract_errors), fg='red')
232243
click.secho('Extracting done.', fg='green')
233-
# exclusive, ignoring other options.
234244
return
235245

236246
# Default scan when no options is provided
237-
if not any((copyright, license)):
247+
if not any(scans):
238248
copyright = True
239249
license = True
240250

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* Copyright © 2000 ACME, Inc., All Rights Reserved */
596 Bytes
Binary file not shown.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
====================================================================
2+
Copyright (c) <year> The Apache Group. All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions
6+
are met:
7+
8+
1. Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright
12+
notice, this list of conditions and the following disclaimer in
13+
the documentation and/or other materials provided with the
14+
distribution.
15+
16+
3. All advertising materials mentioning features or use of this
17+
software must display the following acknowledgment:
18+
"This product includes software developed by the Apache Group
19+
for use in the Apache HTTP server project (http://www.apache.org/)."
20+
21+
4. The names "Apache Server" and "Apache Group" must not be used to
22+
endorse or promote products derived from this software without
23+
prior written permission. For written permission, please contact
24+
25+
26+
5. Products derived from this software may not be called "Apache"
27+
nor may "Apache" appear in their names without prior written
28+
permission of the Apache Group.
29+
30+
6. Redistributions of any form whatsoever must retain the following
31+
acknowledgment:
32+
"This product includes software developed by the Apache Group
33+
for use in the Apache HTTP server project (http://www.apache.org/)."
34+
35+
THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
36+
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
39+
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46+
OF THE POSSIBILITY OF SUCH DAMAGE.
47+
====================================================================
48+
49+
This software consists of voluntary contributions made by many
50+
individuals on behalf of the Apache Group and was originally based
51+
on public domain software written at the National Center for
52+
Supercomputing Applications, University of Illinois, Urbana-Champaign.
53+
For more information on the Apache Group and the Apache HTTP server
54+
project, please see <http://www.apache.org/>.
55+

tests/scancode/test_cli.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#
2+
# Copyright (c) 2015 nexB Inc. and others. All rights reserved.
3+
# http://nexb.com and https://github.com/nexB/scancode-toolkit/
4+
# The ScanCode software is licensed under the Apache License version 2.0.
5+
# Data generated with ScanCode require an acknowledgment.
6+
# ScanCode is a trademark of nexB Inc.
7+
#
8+
# You may not use this software except in compliance with the License.
9+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
10+
# Unless required by applicable law or agreed to in writing, software distributed
11+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
13+
# specific language governing permissions and limitations under the License.
14+
#
15+
# When you publish or redistribute any data created with ScanCode or any ScanCode
16+
# derivative work, you must accompany this data with the following acknowledgment:
17+
#
18+
# Generated with ScanCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
19+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
20+
# ScanCode should be considered or used as legal advice. Consult an Attorney
21+
# for any legal advice.
22+
# ScanCode is a free software code scanning tool from nexB Inc. and others.
23+
# Visit https://github.com/nexB/scancode-toolkit/ for support and download.
24+
25+
from __future__ import absolute_import, print_function
26+
27+
import os
28+
29+
from click.testing import CliRunner
30+
31+
from commoncode.testcase import FileBasedTesting
32+
from scancode import cli
33+
34+
35+
class TestCommandLine(FileBasedTesting):
36+
test_data_dir = os.path.join(os.path.dirname(__file__), 'data')
37+
38+
def test_extract_option_is_exclusive_of_other_options(self):
39+
test_dir = self.get_temp_dir()
40+
runner = CliRunner()
41+
result = runner.invoke(cli.scancode, ['--extract', '--copyright', test_dir])
42+
assert result.exit_code == 2
43+
assert 'option cannot be combined with other scanning options' in result.output
44+
45+
result = runner.invoke(cli.scancode, ['--copyright', '--extract', test_dir])
46+
assert result.exit_code == 2
47+
assert 'option cannot be combined with other scanning options' in result.output
48+
49+
result = runner.invoke(cli.scancode, ['--extract', '--license', test_dir])
50+
assert result.exit_code == 2
51+
assert 'option cannot be combined with other scanning options' in result.output
52+
53+
result = runner.invoke(cli.scancode, ['--extract', '--license', '--copyright', test_dir])
54+
assert result.exit_code == 2
55+
assert 'option cannot be combined with other scanning options' in result.output
56+
57+
def test_extract_option_can_take_an_empty_directory(self):
58+
test_dir = self.get_temp_dir()
59+
runner = CliRunner()
60+
result = runner.invoke(cli.scancode, ['--extract', test_dir])
61+
assert result.exit_code == 0
62+
assert 'Extracting done' in result.output
63+
64+
def test_extract_option_does_extract(self):
65+
test_dir = self.get_test_loc('extract', copy=True)
66+
runner = CliRunner()
67+
result = runner.invoke(cli.scancode, ['--extract', test_dir])
68+
assert result.exit_code == 0
69+
assert 'Extracting done' in result.output
70+
assert os.path.exists(os.path.join(test_dir, 'some.tar.gz-extract'))
71+
72+
def test_copyright_option_detects_copyrights(self):
73+
test_dir = self.get_test_loc('copyright', copy=True)
74+
runner = CliRunner()
75+
output_json = self.get_temp_file('json')
76+
result = runner.invoke(cli.scancode, ['--copyright', test_dir, output_json])
77+
assert result.exit_code == 0
78+
assert 'Scanning done' in result.output
79+
assert os.path.exists(output_json)
80+
assert len(open(output_json).read()) > 10
81+
82+
def test_license_option_detects_licenses(self):
83+
test_dir = self.get_test_loc('license', copy=True)
84+
runner = CliRunner()
85+
output_json = self.get_temp_file('json')
86+
result = runner.invoke(cli.scancode, ['--license', test_dir, output_json])
87+
assert result.exit_code == 0
88+
assert 'Scanning done' in result.output
89+
assert os.path.exists(output_json)
90+
assert len(open(output_json).read()) > 10

0 commit comments

Comments
 (0)