Skip to content

Commit 6ce84be

Browse files
authored
Merge pull request #45 from fosslight/develop
Support swift package manager
2 parents ffea908 + 3ae6c1a commit 6ce84be

File tree

6 files changed

+171
-5
lines changed

6 files changed

+171
-5
lines changed

.github/workflows/pull-request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
fosslight_dependency -p tests/test_gradle/jib -o tests/result/gradle
7676
fosslight_dependency -p tests/test_pub -o tests/result/pub
7777
fosslight_dependency -p tests/test_cocoapods/cocoapods-tips/JWSCocoapodsTips -o tests/result/Cocoapods
78-
fosslight_dependency -p tests/test_swift -o tests/result/swift
78+
fosslight_dependency -p tests/test_swift -o tests/result/swift -t ${{ secrets.TOKEN }}
7979
reuse:
8080
runs-on: ubuntu-latest
8181
steps:

.reuse/dep5

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,7 @@ License: Apache-2.0
7373
Files: .bumpversion.cfg
7474
Copyright: 2021 LG Electronics
7575
License: Apache-2.0
76+
77+
Files: tests/test_swift/*
78+
Copyright: 2021 LG Electronics
79+
License: Apache-2.0

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Currently, it supports the following package managers.
1919
- [PIP](https://pip.pypa.io/) (Python)
2020
- [Pub](https://pub.dev/) (Dart with flutter)
2121
- [Cocoapods](https://cocoapods.org/) (Swift/Obj-C)
22+
- [Swift](https://swift.org/package-manager/) (Swift)
2223

2324
## 🧐 How to analyze the dependencies
2425

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ virtualenv
55
pyyaml
66
lastversion
77
fosslight_util>=1.1.0
8+
PyGithub

src/fosslight_dependency/analyze_dependency.py

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,21 @@
2121
from fosslight_util.set_log import init_log
2222
from fosslight_util.write_excel import write_excel_and_csv
2323
from fosslight_dependency._help import print_help_msg
24+
import base64
25+
26+
try:
27+
from github import Github
28+
except:
29+
pass
2430

2531
# Package Name
2632
_PKG_NAME = "fosslight_dependency"
2733

2834
# Check the manifest file
29-
SUPPORT_PACKAE = ["pip", "npm", "maven", "gradle", "pub", "cocoapods", "android"]
35+
SUPPORT_PACKAE = ["pip", "npm", "maven", "gradle", "pub", "cocoapods", "android", "swift"]
3036
manifest_array = [[SUPPORT_PACKAE[0], "requirements.txt"], [SUPPORT_PACKAE[1], "package.json"], [SUPPORT_PACKAE[2], "pom.xml"],
31-
[SUPPORT_PACKAE[3], "build.gradle"], [SUPPORT_PACKAE[4], "pubspec.yaml"], [SUPPORT_PACKAE[5], "Podfile.lock"]]
37+
[SUPPORT_PACKAE[3], "build.gradle"], [SUPPORT_PACKAE[4], "pubspec.yaml"], [SUPPORT_PACKAE[5], "Podfile.lock"],
38+
[SUPPORT_PACKAE[7], "Package.resolved"]]
3239

3340
# binary url to check license text
3441
license_scanner_url_linux = "third_party/nomos/nomossa"
@@ -61,7 +68,8 @@ def check_valid_manifest_file():
6168

6269

6370
def parse_option():
64-
global MANUAL_DETECT, PIP_ACTIVATE, PIP_DEACTIVATE, PACKAGE, OUTPUT_CUSTOM_DIR, CUR_PATH, OUTPUT_RESULT_DIR, APPNAME
71+
global MANUAL_DETECT, PIP_ACTIVATE, PIP_DEACTIVATE, PACKAGE, OUTPUT_CUSTOM_DIR, CUR_PATH, OUTPUT_RESULT_DIR, \
72+
APPNAME, GITHUB_TOKEN
6573

6674
default_unspecified = "UNSPECIFIED"
6775

@@ -75,6 +83,7 @@ def parse_option():
7583
parser.add_argument('-v', '--version', action='store_true', required=False)
7684
parser.add_argument('-o', '--output', nargs=1, type=str, required=False)
7785
parser.add_argument('-n', '--appname', nargs=1, type=str, required=False)
86+
parser.add_argument('-t', '--token', nargs=1, type=str, required=False)
7887

7988
args = parser.parse_args()
8089

@@ -147,6 +156,12 @@ def parse_option():
147156
else:
148157
APPNAME = "app"
149158

159+
# -t option
160+
if args.token:
161+
GITHUB_TOKEN = "".join(args.token)
162+
else:
163+
GITHUB_TOKEN = ""
164+
150165

151166
def configure_package():
152167
if MANUAL_DETECT == 0:
@@ -332,6 +347,17 @@ def open_input_file():
332347
if os.path.isfile(input_file_name) != 1:
333348
logger.warning(input_file_name + " doesn't exist in this directory.")
334349

350+
if PACKAGE == "swift":
351+
for file_in_swift in os.listdir("."):
352+
if file_in_swift.endswith(".xcodeproj"):
353+
input_file_name_in_xcodeproj = os.path.join(file_in_swift,
354+
"project.xcworkspace/xcshareddata/swiftpm",
355+
input_file_name)
356+
if input_file_name_in_xcodeproj != input_file_name:
357+
if os.path.isfile(input_file_name_in_xcodeproj):
358+
input_file_name = input_file_name_in_xcodeproj
359+
return open_input_file()
360+
335361
if PACKAGE == "gradle" and MANUAL_DETECT == 0:
336362
return False
337363

@@ -785,7 +811,6 @@ def parse_and_generate_output_pub(tmp_file_name):
785811

786812
tmp_license_txt = open(tmp_license_txt_file_name, 'w', encoding='utf-8')
787813
tmp_license_txt.write(license_txt)
788-
# tmp_license_txt.write(license_txt.encode().decode('utf-8'))
789814
tmp_license_txt.close()
790815

791816
license_name_with_license_scanner = check_and_run_license_scanner(tmp_license_txt_file_name, os_name)
@@ -923,6 +948,71 @@ def parse_and_generate_output_android(input_fp):
923948
return sheet_list
924949

925950

951+
def parse_and_generate_output_swift(input_fp):
952+
global GITHUB_TOKEN
953+
954+
sheet_list = {}
955+
sheet_list["SRC"] = []
956+
957+
json_raw = json.load(input_fp)
958+
json_data = json_raw["object"]["pins"]
959+
960+
os_name = check_os()
961+
check_license_scanner(os_name)
962+
963+
if GITHUB_TOKEN is not None:
964+
g = Github(GITHUB_TOKEN)
965+
else:
966+
g = Github()
967+
968+
for key in json_data:
969+
oss_origin_name = key['package']
970+
oss_name = "swift:" + oss_origin_name
971+
972+
revision = key['state']['revision']
973+
version = key['state']['version']
974+
if version is None:
975+
oss_version = revision
976+
else:
977+
oss_version = version
978+
979+
homepage = key['repositoryURL']
980+
dn_loc = homepage
981+
license_name = ''
982+
983+
github_repo = "/".join(homepage.split('/')[-2:])
984+
try:
985+
repository = g.get_repo(github_repo)
986+
except Exception:
987+
logger.error("It cannot find the license name. Please use '-t' option with github token.")
988+
logger.error("{0}{1}".format("refer:https://docs.github.com/en/github/authenticating-to-github/",
989+
"keeping-your-account-and-data-secure/creating-a-personal-access-token"))
990+
repository = ''
991+
992+
if repository is not None:
993+
try:
994+
license_name = repository.get_license().license.spdx_id
995+
except Exception:
996+
logger.info("Cannot find the license name with github api.")
997+
998+
if license_name == "":
999+
try:
1000+
license_txt_data = base64.b64decode(repository.get_license().content).decode('utf-8')
1001+
tmp_license_txt = open(tmp_license_txt_file_name, 'w', encoding='utf-8')
1002+
tmp_license_txt.write(license_txt_data)
1003+
tmp_license_txt.close()
1004+
license_name = check_and_run_license_scanner(tmp_license_txt_file_name, os_name)
1005+
except Exception:
1006+
logger.info("Cannot find the license name with license scanner binary.")
1007+
1008+
if os.path.isfile(tmp_license_txt_file_name):
1009+
os.remove(tmp_license_txt_file_name)
1010+
1011+
sheet_list["SRC"].append(['Package.resolved', oss_name, oss_version, license_name, dn_loc, homepage, '', '', ''])
1012+
1013+
return sheet_list
1014+
1015+
9261016
###########################################
9271017
# Main functions for each package manager #
9281018
###########################################
@@ -1040,6 +1130,17 @@ def main_android():
10401130
return sheet_list
10411131

10421132

1133+
def main_swift():
1134+
1135+
input_fp = open_input_file()
1136+
1137+
sheet_list = parse_and_generate_output_swift(input_fp)
1138+
1139+
close_input_file(input_fp)
1140+
1141+
return sheet_list
1142+
1143+
10431144
def set_package_variables(package):
10441145
global PACKAGE, dn_url, output_file_name, input_file_name, venv_tmp_dir, pom_backup, is_maven_first_try, \
10451146
tmp_license_txt_file_name, source_type
@@ -1083,6 +1184,11 @@ def set_package_variables(package):
10831184
input_file_name = os.path.join(APPNAME, "android_dependency_output.txt")
10841185
output_file_name = "android_dependency_output"
10851186

1187+
elif PACKAGE == "swift":
1188+
input_file_name = "Package.resolved"
1189+
output_file_name = "swift_dependency_output"
1190+
tmp_license_txt_file_name = "tmp_license.txt"
1191+
10861192
else:
10871193
logger.error("### Error Message ###")
10881194
logger.error("You enter the wrong first argument.")
@@ -1128,6 +1234,8 @@ def main():
11281234
sheet_list = main_cocoapods()
11291235
elif PACKAGE == "android":
11301236
sheet_list = main_android()
1237+
elif PACKAGE == "swift":
1238+
sheet_list = main_swift()
11311239
else:
11321240
logger.error("### Error Message ###")
11331241
logger.error("Please enter the supported package manager. (Check the help message with (-h) option.)")

tests/test_swift/Package.resolved

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)