diff --git a/src/formattedcode/output_csv.py b/src/formattedcode/output_csv.py index 2dc111f2323..d5473f1cbb4 100644 --- a/src/formattedcode/output_csv.py +++ b/src/formattedcode/output_csv.py @@ -243,6 +243,7 @@ def get_package_columns(_columns=set()): # some extra columns for components extra_columns = [ + 'purl', 'components', 'owner_name', 'reference_notes', diff --git a/src/packagedcode/cocoapods.py b/src/packagedcode/cocoapods.py index ba510e31bac..6eff6b1216e 100644 --- a/src/packagedcode/cocoapods.py +++ b/src/packagedcode/cocoapods.py @@ -7,18 +7,26 @@ # See https://aboutcode.org for more information about nexB OSS projects. # +import hashlib +import json import logging import re import attr +import saneyaml from commoncode import filetype from packagedcode import models +from packagedcode.licensing import get_license_matches +from packagedcode.licensing import get_license_expression_from_matches from packagedcode.spec import Spec +from packageurl import PackageURL + """ Handle cocoapods packages manifests for macOS and iOS -including .podspec, Podfile and Podfile.lock files. +and from Xcode projects, including .podspec, Podfile and Podfile.lock files, +and .podspec.json files from https://github.com/CocoaPods/Specs. See https://cocoapods.org """ @@ -36,23 +44,89 @@ @attr.s() class CocoapodsPackage(models.Package): - metafiles = ('*.podspec',) - extensions = ('.podspec',) + metafiles = ( + '*.podspec', + '*podfile.lock', + '*.podspec.json', + ) + extensions = ( + '.podspec', + '.lock', + ) default_type = 'pods' default_primary_language = 'Objective-C' default_web_baseurl = 'https://cocoapods.org' - default_download_baseurl = None - default_api_baseurl = None + github_specs_repo_baseurl = 'https://raw.githubusercontent.com/CocoaPods/Specs/blob/master/Specs' + default_cdn_baseurl='https://cdn.cocoapods.org/Specs' @classmethod def recognize(cls, location): yield parse(location) def repository_homepage_url(self, baseurl=default_web_baseurl): - return '{}/pods/{}'.format(baseurl, self.name) + return f'{baseurl}/pods/{self.name}' def repository_download_url(self): - return '{}/archive/{}.zip'.format(self.homepage_url, self.version) + if self.homepage_url: + return f'{self.homepage_url}/archive/{self.version}.zip' + elif self.reponame: + return f'{self.reponame}/archive/refs/tags/{self.version}.zip' + + def get_api_data_url(self): + return self.specs_json_github_url + + def get_code_view_url(self): + if isinstance(self.reponame, str): + return self.reponame+'/tree/'+self.version + + def get_bug_tracking_url(self): + if isinstance(self.reponame, str): + return self.reponame+'/issues/' + + def specs_json_cdn_url(self, baseurl=default_cdn_baseurl): + return f'{baseurl}/{self.hashed_path}/{self.name}/{self.version}/{self.name}.podspec.json' + + def specs_json_github_url(self, baseurl=github_specs_repo_baseurl): + return f'{baseurl}/{self.hashed_path}/{self.name}/{self.version}/{self.name}.podspec.json' + + @property + def reponame(self): + if isinstance(self.vcs_url, str): + if self.vcs_url[-4:] == '.git': + return self.vcs_url[:-4] + + @property + def hashed_path(self): + """ + Returns a string with a part of the file path derived from the md5 hash. + + From https://github.com/CocoaPods/cdn.cocoapods.org: + "There are a set of known prefixes for all Podspec paths, you take the name of the pod, + create a SHA (using md5) of it and take the first three characters." + """ + podname = self.get_podname_proper(self.name) + if self.name != podname: + name_to_hash = podname + else: + name_to_hash = self.name + + hash_init = self.get_first_3_mdf_hash_characters(name_to_hash) + hashed_path = '/'.join(list(hash_init)) + return hashed_path + + @staticmethod + def get_first_3_mdf_hash_characters(podname): + return hashlib.md5(podname.encode('utf-8')).hexdigest()[0:3] + + @staticmethod + def get_podname_proper(podname): + """ + Podnames in cocoapods sometimes are files inside a pods package (like 'OHHTTPStubs/Default') + This returns proper podname in those cases. + """ + if '/' in podname: + return podname.split('/')[0] + return podname def is_podspec(location): @@ -62,21 +136,64 @@ def is_podspec(location): return (filetype.is_file(location) and location.endswith('.podspec')) +def is_podfile_lock(location): + """ + Checks if the file is actually a podfile.lock file + """ + return (filetype.is_file(location) and location.endswith(('podfile.lock', 'Podfile.lock'))) + +def is_podspec_json(location): + """ + Checks if the file is actually a podspec.json metadata file + """ + return (filetype.is_file(location) and location.endswith('.podspec.json')) + + +def read_podspec_json(location): + """ + Reads from podspec.json file at location as JSON. + """ + with open(location, "r") as file: + data = json.load(file) + + return data + + +def read_podfile_lock(location): + """ + Reads from podfile.lock file at location as YML. + """ + with open(location, 'r') as file: + data = saneyaml.load(file) + + return data + + def parse(location): """ - Return a Package object from a .podspec file or None. + Return a Package object from: + 1. `.podspec` files + 2. `.podspec.json` files + 3. `podfile.lock` files + or returns None otherwise. """ - if not is_podspec(location): - return + if is_podspec(location): + podspec_object = Spec() + podspec_data = podspec_object.parse_spec(location) + return build_package(podspec_data) + + if is_podspec_json(location): + podspec_json_data = read_podspec_json(location) + return build_xcode_package(podspec_json_data) - podspec_object = Spec() - podspec_data = podspec_object.parse_spec(location) - return build_package(podspec_data) + if is_podfile_lock(location): + podfile_lock_data = read_podfile_lock(location) + return build_xcode_package_from_lockfile(podfile_lock_data) def build_package(podspec_data): """ - Return a Package object from a package data mapping or None. + Return a Package object from a podspec.json package data mapping. """ name = podspec_data.get('name') version = podspec_data.get('version') @@ -170,3 +287,173 @@ def parse_person(person): email = parsed.group('email') return name, email + + +def get_sha1_file(location): + """ + Get sha1 hash for a file at location. + """ + with open(location, "rb") as f: + return hashlib.sha1(f.read()).hexdigest() + + +def build_xcode_package(podspec_json_data): + """ + Return a Package object from a podspec.json package data mapping. + """ + name = podspec_json_data.get('name') + version = podspec_json_data.get('version') + summary = podspec_json_data.get('summary', '') + description = podspec_json_data.get('description', '') + homepage_url = podspec_json_data.get('homepage') + + license = podspec_json_data.get('license') + if isinstance(license, dict): + declared_license = ' '.join(list(license.values())) + else: + declared_license = license + + source = podspec_json_data.get('source') + vcs_url = None + download_url = None + + if isinstance(source, dict): + git_url = source.get('git', '') + http_url = source.get('http', '') + if git_url: + vcs_url = git_url + elif http_url: + download_url = http_url + + if not vcs_url: + vcs_url = source + + authors = podspec_json_data.get('authors') or {} + + license_matches = get_license_matches(query_string=declared_license) + if not license_matches: + license_expression = 'unknown' + else: + license_expression = get_license_expression_from_matches(license_matches) + + if summary and not description.startswith(summary): + desc = [summary] + if description: + desc += [description] + description = '. '.join(desc) + + parties = [] + if authors: + if isinstance(authors, dict): + for key, value in authors.items(): + party = models.Party( + type=models.party_org, + name=key, + url=value+'.com', + role='owner' + ) + parties.append(party) + else: + party = models.Party( + type=models.party_org, + name=authors, + role='owner' + ) + parties.append(party) + + extra_data = {} + extra_data['source'] = podspec_json_data['source'] + dependencies = podspec_json_data.get('dependencies', '') + if dependencies: + extra_data['dependencies'] = dependencies + extra_data['podspec.json'] = podspec_json_data + + package = CocoapodsPackage( + name=name, + version=version, + vcs_url=vcs_url, + description=description, + declared_license=declared_license, + license_expression=license_expression, + homepage_url=homepage_url, + download_url=download_url, + parties=parties, + ) + + package.api_data_url = package.get_api_data_url() + + return package + + +def get_data_from_pods(dep_pod_version): + + if '(' in dep_pod_version: + podname, _, version = dep_pod_version.strip(')').partition(' (') + else: + version = None + podname = dep_pod_version + + if '/' in podname: + namespace, _, podname = podname.partition('/') + else: + namespace = None + + return podname, namespace, version + + +def build_xcode_package_from_lockfile(podfile_lock_data): + """ + Return a Package object from a data mapping obtained from a podfile.lock + """ + pods = podfile_lock_data['PODS'] + pod_deps = [] + + for pod in pods: + + if isinstance(pod, dict): + for main_pod, _dep_pods in pod.items(): + + podname, namespace, version = get_data_from_pods(main_pod) + + purl = PackageURL( + type='pods', + namespace=namespace, + name=podname, + version=version, + ).to_string() + + pod_deps.append( + models.DependentPackage( + purl=purl, + scope='requires-dev', + requirement=version, + is_runtime=False, + is_optional=True, + is_resolved=True, + ) + ) + + elif isinstance(pod, str): + podname, namespace, version = get_data_from_pods(pod) + purl = PackageURL( + type='pods', + namespace=namespace, + name=podname, + version=version, + ).to_string() + + pod_deps.append( + models.DependentPackage( + purl=purl, + scope='requires-dev', + requirement=version, + is_runtime=False, + is_optional=True, + is_resolved=True, + ) + ) + + yield CocoapodsPackage( + dependencies=pod_deps, + declared_license=None, + ) diff --git a/src/packagedcode/debian_copyright.py b/src/packagedcode/debian_copyright.py index d25d5fc1c52..151d755e0ef 100644 --- a/src/packagedcode/debian_copyright.py +++ b/src/packagedcode/debian_copyright.py @@ -27,6 +27,8 @@ from licensedcode.cache import get_index from licensedcode.match import set_lines from packagedcode.utils import combine_expressions +from packagedcode.licensing import get_license_matches +from packagedcode.licensing import get_license_expression_from_matches from textcode.analysis import unicode_text """ @@ -1129,19 +1131,6 @@ def copyright_detector(location): return copyrights -def get_license_matches(location=None, query_string=None): - """ - Returns a sequence of LicenseMatch objects wit license detections for the - `query_string` or the file at `location`. - """ - if not query_string: - return [] - from licensedcode import cache - - idx = cache.get_index() - return idx.match(location=location, query_string=query_string) - - def filter_duplicate_strings(strings): """ Given a list of strings, return only the unique strings, preserving order. @@ -1253,14 +1242,6 @@ def clean_expression(text): return cleaned_text -def get_license_expression_from_matches(license_matches): - """ - Craft a license expression from a list of LicenseMatch objects. - """ - license_expressions = [match.rule.license_expression for match in license_matches] - return combine_expressions(license_expressions, unique=False) - - def remove_known_license_intros(license_matches): """ Returns a list of LicenseMatch objects after removing unknown license intros diff --git a/src/packagedcode/licensing.py b/src/packagedcode/licensing.py index 5c7d7f7ca98..317af32415e 100644 --- a/src/packagedcode/licensing.py +++ b/src/packagedcode/licensing.py @@ -36,6 +36,29 @@ def logger_debug(*args): for a in args)) +def get_license_matches(location=None, query_string=None): + """ + Returns a sequence of LicenseMatch objects wit license detections for the + `query_string` or the file at `location`. + """ + if not query_string: + return [] + from licensedcode import cache + + idx = cache.get_index() + return idx.match(location=location, query_string=query_string) + + +def get_license_expression_from_matches(license_matches): + """ + Craft a license expression from a list of LicenseMatch objects. + """ + from packagedcode.utils import combine_expressions + + license_expressions = [match.rule.license_expression for match in license_matches] + return combine_expressions(license_expressions, unique=False) + + def matches_have_unknown(matches, licensing): """ Return True if any of the LicenseMatch in `matches` has an unknown license. diff --git a/tests/formattedcode/data/csv/livescan/expected.csv b/tests/formattedcode/data/csv/livescan/expected.csv index 81052be5b8b..6774bf35b45 100644 --- a/tests/formattedcode/data/csv/livescan/expected.csv +++ b/tests/formattedcode/data/csv/livescan/expected.csv @@ -1,23 +1,23 @@ -Resource,type,name,base_name,extension,size,date,sha1,md5,sha256,mime_type,file_type,programming_language,is_binary,is_text,is_archive,is_media,is_source,is_script,percentage_of_license_text,files_count,dirs_count,size_count,scan_errors,license_expression,license__key,license__score,license__name,license__short_name,license__category,license__is_exception,license__is_unknown,license__owner,license__homepage_url,license__text_url,license__reference_url,license__scancode_text_url,license__scancode_data_url,license__spdx_license_key,license__spdx_url,start_line,end_line,matched_rule__identifier,matched_rule__license_expression,matched_rule__licenses,matched_rule__referenced_filenames,matched_rule__is_license_text,matched_rule__is_license_notice,matched_rule__is_license_reference,matched_rule__is_license_tag,matched_rule__is_license_intro,matched_rule__has_unknown,matched_rule__matcher,matched_rule__rule_length,matched_rule__matched_length,matched_rule__match_coverage,matched_rule__rule_relevance,copyright,copyright_holder,email,url,package__type,package__namespace,package__name,package__version,package__qualifiers,package__subpath,package__primary_language,package__description,package__release_date,package__homepage_url,package__download_url,package__size,package__sha1,package__md5,package__sha256,package__sha512,package__bug_tracking_url,package__code_view_url,package__vcs_url,package__copyright,package__license_expression,package__declared_license,package__notice_text,package__root_path,package__contains_source_code,package__extra_data -json2csv.rb,file,json2csv.rb,json2csv,.rb,912,2021-03-31,1236469a06a2bacbdd8e172ad718482af5b0a936,1307c281e0b153202e291b217eab85d5,12ba215313981dbe810d9ed696b7cc753d97adfcc26eba1e13f941dc7506aa4e,text/x-script.python,"Python script, ASCII text executable",Ruby,False,True,False,False,True,True,62.04,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,apache-2.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,apache-2.0,100.00,Apache License 2.0,Apache 2.0,Permissive,False,False,Apache Software Foundation,http://www.apache.org/licenses/,http://www.apache.org/licenses/LICENSE-2.0,https://scancode-licensedb.aboutcode.org/apache-2.0,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.yml,Apache-2.0,https://spdx.org/licenses/Apache-2.0,5,13,apache-2.0_7.RULE,apache-2.0,apache-2.0,,,True,,,,,2-aho,85,85,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3,,,,,,,,,,,,,,,,Copyright (c) 2017 nexB Inc. and others,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3,,,,,,,,,,,,,,,,,nexB Inc. and others,,,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,4,,,,,,,,,,,,,,,,,,,http://nexb.com/,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,4,,,,,,,,,,,,,,,,,,,https://github.com/nexB/scancode-toolkit/,,,,,,,,,,,,,,,,,,,,,,,,,, -json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,8,,,,,,,,,,,,,,,,,,,http://www.apache.org/licenses/LICENSE-2.0,,,,,,,,,,,,,,,,,,,,,,,,,, -license,file,license,license,,679,2021-03-31,75c5490a718ddd45e40e0cc7ce0c756abc373123,b965a762efb9421cf1bf4405f336e278,a34098a43e5677495f59dff825a3f9bc0f2b0261d75feb2356919f4c3ce049ab,text/plain,ASCII text,,False,True,False,False,False,False,100.0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -license,,,,,,,,,,,,,,,,,,,,,,,,gpl-2.0-plus,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -license,,,,,,,,,,,,,,,,,,,,,,,,,gpl-2.0-plus,100.00,GNU General Public License 2.0 or later,GPL 2.0 or later,Copyleft,False,False,Free Software Foundation (FSF),http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html,http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html,https://scancode-licensedb.aboutcode.org/gpl-2.0-plus,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/gpl-2.0-plus.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/gpl-2.0-plus.yml,GPL-2.0-or-later,https://spdx.org/licenses/GPL-2.0-or-later,1,12,gpl-2.0-plus_420.RULE,gpl-2.0-plus,gpl-2.0-plus,,,True,,,,,1-hash,113,113,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,file,package.json,package,.json,2200,2021-03-31,918376afce796ef90eeda1d6695f2289c90491ac,1f66239a9b850c5e60a9382dbe2162d2,29f6068a1b6c7d06f115a5edc4ed8558edde42c6bbf0145ed77cf1108a0dd529,application/json,JSON data,,False,True,False,False,False,False,58.1,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,mit,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,mit,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,mit,100.00,MIT License,MIT License,Permissive,False,False,MIT,http://opensource.org/licenses/mit-license.php,http://opensource.org/licenses/mit-license.php,https://scancode-licensedb.aboutcode.org/mit,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml,MIT,https://spdx.org/licenses/MIT,24,24,mit_649.RULE,mit,mit,,,True,,,,,2-aho,4,4,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,mit,100.00,MIT License,MIT License,Permissive,False,False,MIT,http://opensource.org/licenses/mit-license.php,http://opensource.org/licenses/mit-license.php,https://scancode-licensedb.aboutcode.org/mit,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml,MIT,https://spdx.org/licenses/MIT,24,24,mit.LICENSE,mit,mit,,True,,,,,,2-aho,161,161,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,24,,,,,,,,,,,,,,,,Copyright (c) 2012 LearnBoost ,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,24,,,,,,,,,,,,,,,,,LearnBoost,,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,12,,,,,,,,,,,,,,,,,,tj@learnboost.com,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,16,,,,,,,,,,,,,,,,,,,https://github.com/visionmedia/node-cookie-signature.git,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27,27,,,,,,,,,,,,,,,,,,,https://github.com/visionmedia/node-cookie-signature/issues,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,npm,,cookie-signature,v 1.0.3,,,JavaScript,Sign and unsign cookies,,,https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz,,,,,,https://github.com/visionmedia/node-cookie-signature/issues,,git+https://github.com/visionmedia/node-cookie-signature.git,,,,,,, +Resource,type,name,base_name,extension,size,date,sha1,md5,sha256,mime_type,file_type,programming_language,is_binary,is_text,is_archive,is_media,is_source,is_script,percentage_of_license_text,files_count,dirs_count,size_count,scan_errors,license_expression,license__key,license__score,license__name,license__short_name,license__category,license__is_exception,license__is_unknown,license__owner,license__homepage_url,license__text_url,license__reference_url,license__scancode_text_url,license__scancode_data_url,license__spdx_license_key,license__spdx_url,start_line,end_line,matched_rule__identifier,matched_rule__license_expression,matched_rule__licenses,matched_rule__referenced_filenames,matched_rule__is_license_text,matched_rule__is_license_notice,matched_rule__is_license_reference,matched_rule__is_license_tag,matched_rule__is_license_intro,matched_rule__has_unknown,matched_rule__matcher,matched_rule__rule_length,matched_rule__matched_length,matched_rule__match_coverage,matched_rule__rule_relevance,copyright,copyright_holder,email,url,package__type,package__namespace,package__name,package__version,package__qualifiers,package__subpath,package__primary_language,package__description,package__release_date,package__homepage_url,package__download_url,package__size,package__sha1,package__md5,package__sha256,package__sha512,package__bug_tracking_url,package__code_view_url,package__vcs_url,package__copyright,package__license_expression,package__declared_license,package__notice_text,package__root_path,package__contains_source_code,package__extra_data,package__purl +json2csv.rb,file,json2csv.rb,json2csv,.rb,912,2020-04-27,1236469a06a2bacbdd8e172ad718482af5b0a936,1307c281e0b153202e291b217eab85d5,12ba215313981dbe810d9ed696b7cc753d97adfcc26eba1e13f941dc7506aa4e,text/x-script.python,"Python script, ASCII text executable",Ruby,False,True,False,False,True,True,62.04,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,apache-2.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,apache-2.0,100.00,Apache License 2.0,Apache 2.0,Permissive,False,False,Apache Software Foundation,http://www.apache.org/licenses/,http://www.apache.org/licenses/LICENSE-2.0,https://scancode-licensedb.aboutcode.org/apache-2.0,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.yml,Apache-2.0,https://spdx.org/licenses/Apache-2.0,5,13,apache-2.0_7.RULE,apache-2.0,apache-2.0,,,True,,,,,2-aho,85,85,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3,,,,,,,,,,,,,,,,Copyright (c) 2017 nexB Inc. and others,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3,,,,,,,,,,,,,,,,,nexB Inc. and others,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,4,,,,,,,,,,,,,,,,,,,http://nexb.com/,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,4,,,,,,,,,,,,,,,,,,,https://github.com/nexB/scancode-toolkit/,,,,,,,,,,,,,,,,,,,,,,,,,,, +json2csv.rb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,8,,,,,,,,,,,,,,,,,,,http://www.apache.org/licenses/LICENSE-2.0,,,,,,,,,,,,,,,,,,,,,,,,,,, +license,file,license,license,,679,2019-11-03,75c5490a718ddd45e40e0cc7ce0c756abc373123,b965a762efb9421cf1bf4405f336e278,a34098a43e5677495f59dff825a3f9bc0f2b0261d75feb2356919f4c3ce049ab,text/plain,ASCII text,,False,True,False,False,False,False,100.0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +license,,,,,,,,,,,,,,,,,,,,,,,,gpl-2.0-plus,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +license,,,,,,,,,,,,,,,,,,,,,,,,,gpl-2.0-plus,100.00,GNU General Public License 2.0 or later,GPL 2.0 or later,Copyleft,False,False,Free Software Foundation (FSF),http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html,http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html,https://scancode-licensedb.aboutcode.org/gpl-2.0-plus,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/gpl-2.0-plus.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/gpl-2.0-plus.yml,GPL-2.0-or-later,https://spdx.org/licenses/GPL-2.0-or-later,1,12,gpl-2.0-plus_420.RULE,gpl-2.0-plus,gpl-2.0-plus,,,True,,,,,1-hash,113,113,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,file,package.json,package,.json,2200,2019-11-03,918376afce796ef90eeda1d6695f2289c90491ac,1f66239a9b850c5e60a9382dbe2162d2,29f6068a1b6c7d06f115a5edc4ed8558edde42c6bbf0145ed77cf1108a0dd529,application/json,JSON data,,False,True,False,False,False,False,58.1,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,mit,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,mit,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,mit,100.00,MIT License,MIT License,Permissive,False,False,MIT,http://opensource.org/licenses/mit-license.php,http://opensource.org/licenses/mit-license.php,https://scancode-licensedb.aboutcode.org/mit,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml,MIT,https://spdx.org/licenses/MIT,24,24,mit_649.RULE,mit,mit,,,True,,,,,2-aho,4,4,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,mit,100.00,MIT License,MIT License,Permissive,False,False,MIT,http://opensource.org/licenses/mit-license.php,http://opensource.org/licenses/mit-license.php,https://scancode-licensedb.aboutcode.org/mit,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE,https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml,MIT,https://spdx.org/licenses/MIT,24,24,mit.LICENSE,mit,mit,,True,,,,,,2-aho,161,161,100.00,100.00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,24,,,,,,,,,,,,,,,,Copyright (c) 2012 LearnBoost ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,24,,,,,,,,,,,,,,,,,LearnBoost,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,12,,,,,,,,,,,,,,,,,,tj@learnboost.com,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16,16,,,,,,,,,,,,,,,,,,,https://github.com/visionmedia/node-cookie-signature.git,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27,27,,,,,,,,,,,,,,,,,,,https://github.com/visionmedia/node-cookie-signature/issues,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,npm,,cookie-signature,v 1.0.3,,,JavaScript,Sign and unsign cookies,,,https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz,,,,,,https://github.com/visionmedia/node-cookie-signature/issues,,git+https://github.com/visionmedia/node-cookie-signature.git,,,,,,,,pkg:npm/cookie-signature@1.0.3 diff --git a/tests/formattedcode/data/csv/packages/expected-no-root.csv b/tests/formattedcode/data/csv/packages/expected-no-root.csv index 22d509def54..8855502042a 100644 --- a/tests/formattedcode/data/csv/packages/expected-no-root.csv +++ b/tests/formattedcode/data/csv/packages/expected-no-root.csv @@ -1,3 +1,3 @@ -Resource,type,scan_errors,package__type,package__namespace,package__name,package__version,package__qualifiers,package__subpath,package__primary_language,package__description,package__release_date,package__homepage_url,package__download_url,package__size,package__sha1,package__md5,package__sha256,package__sha512,package__bug_tracking_url,package__code_view_url,package__vcs_url,package__copyright,package__license_expression,package__declared_license,package__notice_text,package__root_path,package__contains_source_code,package__extra_data -package.json,file,,,,,,,,,,,,,,,,,,,,,,,,,,, -package.json,,,npm,,npm,v 2.13.5,,,JavaScript,a package manager for JavaScript,,https://docs.npmjs.com/,https://registry.npmjs.org/npm/-/npm-2.13.5.tgz,,a124386bce4a90506f28ad4b1d1a804a17baaf32,,,,http://github.com/npm/npm/issues,,git+https://github.com/npm/npm.git@fc7bbf03e39cc48a8924b90696d28345a6a90f3c,,artistic-2.0,Artistic-2.0,,,, +Resource,type,scan_errors,package__type,package__namespace,package__name,package__version,package__qualifiers,package__subpath,package__primary_language,package__description,package__release_date,package__homepage_url,package__download_url,package__size,package__sha1,package__md5,package__sha256,package__sha512,package__bug_tracking_url,package__code_view_url,package__vcs_url,package__copyright,package__license_expression,package__declared_license,package__notice_text,package__root_path,package__contains_source_code,package__extra_data,package__purl +package.json,file,,,,,,,,,,,,,,,,,,,,,,,,,,,, +package.json,,,npm,,npm,v 2.13.5,,,JavaScript,a package manager for JavaScript,,https://docs.npmjs.com/,https://registry.npmjs.org/npm/-/npm-2.13.5.tgz,,a124386bce4a90506f28ad4b1d1a804a17baaf32,,,,http://github.com/npm/npm/issues,,git+https://github.com/npm/npm.git@fc7bbf03e39cc48a8924b90696d28345a6a90f3c,,artistic-2.0,Artistic-2.0,,,,,pkg:npm/npm@2.13.5 diff --git a/tests/formattedcode/data/csv/packages/expected.csv b/tests/formattedcode/data/csv/packages/expected.csv index 8b9d818f181..d1b733ddf43 100644 --- a/tests/formattedcode/data/csv/packages/expected.csv +++ b/tests/formattedcode/data/csv/packages/expected.csv @@ -1,4 +1,4 @@ -Resource,type,scan_errors,package__type,package__namespace,package__name,package__version,package__qualifiers,package__subpath,package__primary_language,package__description,package__release_date,package__homepage_url,package__download_url,package__size,package__sha1,package__md5,package__sha256,package__sha512,package__bug_tracking_url,package__code_view_url,package__vcs_url,package__copyright,package__license_expression,package__declared_license,package__notice_text,package__root_path,package__contains_source_code,package__extra_data -scan/,directory,,,,,,,,,,,,,,,,,,,,,,,,,,, -scan/package.json,file,,,,,,,,,,,,,,,,,,,,,,,,,,, -scan/package.json,,,npm,,npm,v 2.13.5,,,JavaScript,a package manager for JavaScript,,https://docs.npmjs.com/,https://registry.npmjs.org/npm/-/npm-2.13.5.tgz,,a124386bce4a90506f28ad4b1d1a804a17baaf32,,,,http://github.com/npm/npm/issues,,git+https://github.com/npm/npm.git@fc7bbf03e39cc48a8924b90696d28345a6a90f3c,,artistic-2.0,Artistic-2.0,,scan,, +Resource,type,scan_errors,package__type,package__namespace,package__name,package__version,package__qualifiers,package__subpath,package__primary_language,package__description,package__release_date,package__homepage_url,package__download_url,package__size,package__sha1,package__md5,package__sha256,package__sha512,package__bug_tracking_url,package__code_view_url,package__vcs_url,package__copyright,package__license_expression,package__declared_license,package__notice_text,package__root_path,package__contains_source_code,package__extra_data,package__purl +scan/,directory,,,,,,,,,,,,,,,,,,,,,,,,,,,, +scan/package.json,file,,,,,,,,,,,,,,,,,,,,,,,,,,,, +scan/package.json,,,npm,,npm,v 2.13.5,,,JavaScript,a package manager for JavaScript,,https://docs.npmjs.com/,https://registry.npmjs.org/npm/-/npm-2.13.5.tgz,,a124386bce4a90506f28ad4b1d1a804a17baaf32,,,,http://github.com/npm/npm/issues,,git+https://github.com/npm/npm.git@fc7bbf03e39cc48a8924b90696d28345a6a90f3c,,artistic-2.0,Artistic-2.0,,scan,,,pkg:npm/npm@2.13.5 diff --git a/tests/packagedcode/data/cocoapods/podfle.lock/braintree_ios_Podfile.lock b/tests/packagedcode/data/cocoapods/podfle.lock/braintree_ios_Podfile.lock new file mode 100644 index 00000000000..82bf136c196 --- /dev/null +++ b/tests/packagedcode/data/cocoapods/podfle.lock/braintree_ios_Podfile.lock @@ -0,0 +1,48 @@ +PODS: + - Expecta (1.0.6) + - InAppSettingsKit (3.1.4) + - OCMock (3.7.1) + - OHHTTPStubs (9.0.0): + - OHHTTPStubs/Default (= 9.0.0) + - OHHTTPStubs/Core (9.0.0) + - OHHTTPStubs/Default (9.0.0): + - OHHTTPStubs/Core + - OHHTTPStubs/JSON + - OHHTTPStubs/NSURLSession + - OHHTTPStubs/OHPathHelpers + - OHHTTPStubs/JSON (9.0.0): + - OHHTTPStubs/Core + - OHHTTPStubs/NSURLSession (9.0.0): + - OHHTTPStubs/Core + - OHHTTPStubs/OHPathHelpers (9.0.0) + - Specta (1.0.7) + - xcbeautify (0.8.1) + +DEPENDENCIES: + - Expecta + - InAppSettingsKit + - OCMock + - OHHTTPStubs + - Specta + - xcbeautify + +SPEC REPOS: + trunk: + - Expecta + - InAppSettingsKit + - OCMock + - OHHTTPStubs + - Specta + - xcbeautify + +SPEC CHECKSUMS: + Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 + InAppSettingsKit: 01fb9774c74a11fefc521f29cb2338909e1c2b61 + OCMock: 75fbeaa46a9b11f8c182bbb1d1f7e9a35ccc9955 + OHHTTPStubs: cb29d2a9d09a828ecb93349a2b0c64f99e0db89f + Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 + xcbeautify: a3b03e4a38eb1a5766a83a7a3c53915a233572e3 + +PODFILE CHECKSUM: 75163f16229528991a9364c7c1a44cd57a30cac6 + +COCOAPODS: 1.10.1 diff --git a/tests/packagedcode/data/cocoapods/podfle.lock/braintree_ios_Podfile.lock.expected.json b/tests/packagedcode/data/cocoapods/podfle.lock/braintree_ios_Podfile.lock.expected.json new file mode 100644 index 00000000000..f96cff6cb1f --- /dev/null +++ b/tests/packagedcode/data/cocoapods/podfle.lock/braintree_ios_Podfile.lock.expected.json @@ -0,0 +1,127 @@ +[ + { + "type": "pods", + "namespace": null, + "name": null, + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Objective-C", + "description": null, + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": null, + "declared_license": null, + "notice_text": null, + "root_path": null, + "dependencies": [ + { + "purl": "pkg:pods/Expecta@1.0.6", + "requirement": "1.0.6", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/InAppSettingsKit@3.1.4", + "requirement": "3.1.4", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OCMock@3.7.1", + "requirement": "3.7.1", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OHHTTPStubs@9.0.0", + "requirement": "9.0.0", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OHHTTPStubs/Core@9.0.0", + "requirement": "9.0.0", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OHHTTPStubs/Default@9.0.0", + "requirement": "9.0.0", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OHHTTPStubs/JSON@9.0.0", + "requirement": "9.0.0", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OHHTTPStubs/NSURLSession@9.0.0", + "requirement": "9.0.0", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/OHHTTPStubs/OHPathHelpers@9.0.0", + "requirement": "9.0.0", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/Specta@1.0.7", + "requirement": "1.0.7", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + }, + { + "purl": "pkg:pods/xcbeautify@0.8.1", + "requirement": "0.8.1", + "scope": "requires-dev", + "is_runtime": false, + "is_optional": true, + "is_resolved": true + } + ], + "contains_source_code": null, + "source_packages": [], + "extra_data": {}, + "purl": null, + "repository_homepage_url": "https://cocoapods.org/pods/None", + "repository_download_url": null, + "api_data_url": null + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/cocoapods/podspec.json/FirebaseAnalytics.podspec.json b/tests/packagedcode/data/cocoapods/podspec.json/FirebaseAnalytics.podspec.json new file mode 100644 index 00000000000..1feccd75232 --- /dev/null +++ b/tests/packagedcode/data/cocoapods/podspec.json/FirebaseAnalytics.podspec.json @@ -0,0 +1,59 @@ +{ + "authors": "Google, Inc.", + "cocoapods_version": ">= 1.10.0", + "default_subspecs": "AdIdSupport", + "dependencies": { + "FirebaseCore": "~> 8.0", + "FirebaseInstallations": "~> 8.0", + "GoogleUtilities/AppDelegateSwizzler": "~> 7.4", + "GoogleUtilities/MethodSwizzler": "~> 7.4", + "GoogleUtilities/NSData+zlib": "~> 7.4", + "GoogleUtilities/Network": "~> 7.4", + "nanopb": "~> 2.30908.0" + }, + "description": "Firebase Analytics is a free, out-of-the-box analytics solution that inspires actionable insights based on app usage and user engagement.", + "frameworks": [ + "StoreKit" + ], + "homepage": "https://firebase.google.com/features/analytics/", + "libraries": [ + "c++", + "sqlite3", + "z" + ], + "license": { + "text": "Copyright 2021 Google", + "type": "Copyright" + }, + "name": "FirebaseAnalytics", + "platforms": { + "ios": "9.0" + }, + "source": { + "http": "https://dl.google.com/firebase/ios/analytics/19ed8dba01e90708/FirebaseAnalytics-8.1.1.tar.gz" + }, + "summary": "Firebase Analytics for iOS", + "version": "8.1.1", + "subspecs": [ + { + "name": "AdIdSupport", + "dependencies": { + "FirebaseAnalytics/Base": "8.1.1", + "GoogleAppMeasurement": "8.1.1" + } + }, + { + "name": "WithoutAdIdSupport", + "dependencies": { + "FirebaseAnalytics/Base": "8.1.1", + "GoogleAppMeasurement/WithoutAdIdSupport": "8.1.1" + } + }, + { + "name": "Base", + "vendored_frameworks": [ + "Frameworks/FirebaseAnalytics.xcframework" + ] + } + ] +} diff --git a/tests/packagedcode/data/cocoapods/podspec.json/FirebaseAnalytics.podspec.json.expected.json b/tests/packagedcode/data/cocoapods/podspec.json/FirebaseAnalytics.podspec.json.expected.json new file mode 100644 index 00000000000..8b4c345fb64 --- /dev/null +++ b/tests/packagedcode/data/cocoapods/podspec.json/FirebaseAnalytics.podspec.json.expected.json @@ -0,0 +1,46 @@ +{ + "type": "pods", + "namespace": null, + "name": "FirebaseAnalytics", + "version": "8.1.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Objective-C", + "description": "Firebase Analytics for iOS. Firebase Analytics is a free, out-of-the-box analytics solution that inspires actionable insights based on app usage and user engagement.", + "release_date": null, + "parties": [ + { + "type": "organization", + "role": "owner", + "name": "Google, Inc.", + "email": null, + "url": null + } + ], + "keywords": [], + "homepage_url": "https://firebase.google.com/features/analytics/", + "download_url": "https://dl.google.com/firebase/ios/analytics/19ed8dba01e90708/FirebaseAnalytics-8.1.1.tar.gz", + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": { + "http": "https://dl.google.com/firebase/ios/analytics/19ed8dba01e90708/FirebaseAnalytics-8.1.1.tar.gz" + }, + "copyright": null, + "license_expression": "unknown", + "declared_license": "Copyright 2021 Google Copyright", + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "extra_data": {}, + "purl": "pkg:pods/FirebaseAnalytics@8.1.1", + "repository_homepage_url": "https://cocoapods.org/pods/FirebaseAnalytics", + "repository_download_url": "https://firebase.google.com/features/analytics//archive/8.1.1.zip", + "api_data_url": "https://raw.githubusercontent.com/CocoaPods/Specs/blob/master/Specs/e/2/1/FirebaseAnalytics/8.1.1/FirebaseAnalytics.podspec.json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/plugin/help.txt b/tests/packagedcode/data/plugin/help.txt index 2925e36fe60..56596240262 100644 --- a/tests/packagedcode/data/plugin/help.txt +++ b/tests/packagedcode/data/plugin/help.txt @@ -219,8 +219,8 @@ Package: opam -------------------------------------------- Package: pods class: packagedcode.cocoapods:CocoapodsPackage - metafiles: *.podspec - extensions: .podspec + metafiles: *.podspec, *podfile.lock, *.podspec.json + extensions: .podspec, .lock -------------------------------------------- Package: pubspec diff --git a/tests/packagedcode/test_cocoapods.py b/tests/packagedcode/test_cocoapods.py index 63c5f1afddc..f3cfbeeeceb 100644 --- a/tests/packagedcode/test_cocoapods.py +++ b/tests/packagedcode/test_cocoapods.py @@ -45,3 +45,23 @@ def test_cocoapods_can_parse_SwiftLib(self): expected_loc = self.get_test_loc('cocoapods/podspec/SwiftLib.podspec.expected.json') packages = cocoapods.parse(test_file) self.check_package(packages, expected_loc, regen=False) + + +class TestCocoaPodspecJson(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + def test_cocoapods_can_parse_FirebaseAnalytics(self): + test_file = self.get_test_loc('cocoapods/podspec.json/FirebaseAnalytics.podspec.json') + expected_loc = self.get_test_loc('cocoapods/podspec.json/FirebaseAnalytics.podspec.json.expected.json') + packages = cocoapods.parse(test_file) + self.check_package(packages, expected_loc, regen=False) + + +class TestCocoaPodfileLock(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + def test_cocoapods_can_parse_braintree_ios(self): + test_file = self.get_test_loc('cocoapods/podfle.lock/braintree_ios_Podfile.lock') + expected_loc = self.get_test_loc('cocoapods/podfle.lock/braintree_ios_Podfile.lock.expected.json') + packages = cocoapods.parse(test_file) + self.check_packages(packages, expected_loc, regen=False)