Skip to content

Commit b6e387d

Browse files
Major build improvements (#1668)
* Major build improvements * Cleanup and fix path * chore: apply suggestions from code review Co-authored-by: Jørgen Kalsnes Hagen <43886029+Snailedlt@users.noreply.github.com> * Remove `selenium` from the NPM dependencies * Revert `nano` icon changes * Use quote notes * Update * chore: apply suggestions from code review Co-authored-by: Jørgen Kalsnes Hagen <43886029+Snailedlt@users.noreply.github.com> * Snailedlt/improve build changes (#187) * Make README more readable * move logic from index.html to script.js * fix devicon min css in head * Fix build script missing token error * Add more print statements to local build script * Change from ng-href to href in code view * Minor readme improvements --------- Co-authored-by: David Leal <halfpacho@gmail.com> --------- Co-authored-by: Jørgen Kalsnes Hagen <43886029+Snailedlt@users.noreply.github.com>
1 parent c97a0bb commit b6e387d

21 files changed

Lines changed: 2403 additions & 2093 deletions

.github/scripts/build_assets/arg_getters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from build_assets.PathResolverAction import PathResolverAction
33

44

5-
def get_selenium_runner_args(peek_mode=False):
5+
def get_selenium_runner_args(has_token=True, peek_mode=False):
66
"""
77
Get the commandline arguments for the icomoon_peek.py and
88
icomoon_build.py.
@@ -36,7 +36,7 @@ def get_selenium_runner_args(peek_mode=False):
3636
if peek_mode:
3737
parser.add_argument("pr_title",
3838
help="The title of the PR that we are peeking at")
39-
else:
39+
if has_token != False:
4040
parser.add_argument("token",
4141
help="The GitHub token to access the GitHub REST API.")
4242

Binary file not shown.

.github/scripts/build_assets/geckodriver-v0.30.0-win64/README.md renamed to .github/scripts/build_assets/geckodriver-v0.32.2-win64/README.md

File renamed without changes.
Binary file not shown.
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
from pathlib import Path
2+
import sys
3+
from selenium.common.exceptions import TimeoutException
4+
import re
5+
import subprocess
6+
import json
7+
from typing import List, Dict
8+
from io import FileIO
9+
10+
# pycharm complains that build_assets is an unresolved ref
11+
# don't worry about it, the script still runs
12+
from build_assets.selenium_runner.BuildSeleniumRunner import BuildSeleniumRunner
13+
from build_assets import filehandler, arg_getters, util, api_handler
14+
15+
def main():
16+
"""
17+
Build the icons using Icomoon. Also optimize the svgs.
18+
"""
19+
runner = None
20+
logfile = open("log.txt", "w")
21+
try:
22+
args = arg_getters.get_selenium_runner_args(has_token=False)
23+
new_icons = get_icons_for_building(args.icomoon_json_path, args.devicon_json_path, logfile)
24+
if len(new_icons) == 0:
25+
sys.exit("No files need to be uploaded. Ending script...")
26+
27+
print(f"There are {len(new_icons)} icons to be build. Here are they:", *new_icons, sep = "\n", file=logfile)
28+
29+
print("Begin optimizing files...", file=logfile)
30+
optimize_svgs(new_icons, args.icons_folder_path, logfile=logfile)
31+
32+
print("Updating the icomoon json...", file=logfile)
33+
update_icomoon_json(new_icons, args.icomoon_json_path, logfile)
34+
35+
print("Start the building icons process...", file=logfile)
36+
icon_svgs = filehandler.get_svgs_paths(
37+
new_icons, args.icons_folder_path, icon_versions_only=True)
38+
zip_name = "devicon-v1.0.zip"
39+
zip_path = Path(args.download_path, zip_name)
40+
screenshot_folder = filehandler.create_screenshot_folder("./")
41+
42+
runner = BuildSeleniumRunner(args.download_path,
43+
args.geckodriver_path, args.headless, log_output=logfile)
44+
print("Building icons...", file=logfile)
45+
runner.build_icons(args.icomoon_json_path, zip_path,
46+
icon_svgs, screenshot_folder)
47+
48+
print("Extracting files...", file=logfile)
49+
filehandler.extract_files(str(zip_path), args.download_path, logfile)
50+
print("Renaming extracted files...", file=logfile)
51+
filehandler.rename_extracted_files(args.download_path, logfile)
52+
53+
print("Task completed!", file=logfile)
54+
except TimeoutException as e:
55+
util.exit_with_err(Exception("Selenium Time Out Error: \n" + str(e)), logfile)
56+
except Exception as e:
57+
util.exit_with_err(e, logfile)
58+
finally:
59+
print("Exiting", file=logfile)
60+
if runner is not None:
61+
runner.close()
62+
logfile.close()
63+
64+
65+
def get_icons_for_building(icomoon_json_path: str, devicon_json_path: str, logfile: FileIO):
66+
"""
67+
Get the icons for building.
68+
:param icomoon_json_path - the path to the `icomoon.json`.
69+
:param devicon_json_path - the path to the `devicon.json`.
70+
:param logfile.
71+
:return a list of dict containing info on the icons. These are
72+
from the `devicon.json`.
73+
"""
74+
75+
new_icons = []
76+
77+
# get any icons that might not have been found by the API
78+
# sometimes happen due to the PR being opened before the latest build release
79+
new_icons_from_devicon_json = filehandler.find_new_icons_in_devicon_json(
80+
devicon_json_path, icomoon_json_path)
81+
82+
for icon in new_icons_from_devicon_json:
83+
if icon not in new_icons:
84+
new_icons.append(icon)
85+
86+
return new_icons
87+
88+
89+
def optimize_svgs(new_icons: List[str], icons_folder_path: str, logfile: FileIO):
90+
"""
91+
Optimize the newly added svgs. This is done in batches
92+
since the command line has a limit on characters allowed.
93+
:param new_icons - the new icons that need to be optimized.
94+
:param icons_folder_path - the path to the /icons folder.
95+
:param logfile - the file obj to store logging info in.
96+
"""
97+
svgs = filehandler.get_svgs_paths(new_icons, icons_folder_path, icon_versions_only=False)
98+
start = 0
99+
step = 10
100+
for i in range(start, len(svgs), step):
101+
batch = svgs[i:i + step]
102+
print(f"Optimizing these files\n{batch}", file=logfile)
103+
subprocess.run(["npm", "run", "optimize-svg", "--", f"--svgFiles={json.dumps(batch)}"], shell=True)
104+
105+
106+
def update_icomoon_json(new_icons: List[str], icomoon_json_path: str, logfile: FileIO):
107+
"""
108+
Update the `icomoon.json` if it contains any icons
109+
that needed to be updated. This will remove the icons
110+
from the `icomoon.json` so the build script will reupload
111+
it later.
112+
"""
113+
icomoon_json = filehandler.get_json_file_content(icomoon_json_path)
114+
cur_len = len(icomoon_json["icons"])
115+
messages = []
116+
117+
wrapper_function = lambda icomoon_icon : find_icomoon_icon_not_in_new_icons(
118+
icomoon_icon, new_icons, messages)
119+
icons_to_keep = filter(wrapper_function, icomoon_json["icons"])
120+
icomoon_json["icons"] = list(icons_to_keep)
121+
122+
new_len = len(icomoon_json["icons"])
123+
print(f"Update completed. Removed {cur_len - new_len} icons:", *messages, sep='\n', file=logfile)
124+
filehandler.write_to_file(icomoon_json_path, json.dumps(icomoon_json))
125+
126+
127+
def find_icomoon_icon_not_in_new_icons(icomoon_icon: Dict, new_icons: List, messages: List):
128+
"""
129+
Find all the icomoon icons that are not listed in the new icons.
130+
This also add logging for which icons were removed.
131+
:param icomoon_icon - a dict object from the icomoon.json's `icons` attribute.
132+
:param new_icons - a list of new icons. Each element is an object from the `devicon.json`.
133+
:param messages - an empty list where the function can attach logging on which
134+
icon were removed.
135+
"""
136+
for new_icon in new_icons:
137+
pattern = re.compile(f"^{new_icon['name']}-")
138+
if pattern.search(icomoon_icon["properties"]["name"]):
139+
message = f"-'{icomoon_icon['properties']['name']}' cause it matches '{new_icon['name']}'"
140+
messages.append(message)
141+
return False
142+
return True
143+
144+
if __name__ == "__main__":
145+
main()

.github/workflows/peek_icons.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
shell: cmd
4242
run: >
4343
python ./.github/scripts/icomoon_peek.py
44-
./.github/scripts/build_assets/geckodriver-v0.30.0-win64/geckodriver.exe ./icomoon.json
44+
./.github/scripts/build_assets/geckodriver-v0.32.2-win64/geckodriver.exe ./icomoon.json
4545
./devicon.json ./icons ./ --headless "%PR_TITLE%"
4646
4747
- name: Upload the err messages (created by icomoon_peek.py)

.gitpod.dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM gitpod/workspace-full-vnc
2+
3+
RUN sudo apt-get update \
4+
&& sudo apt-get install -y \
5+
firefox \
6+
gulp \
7+
&& python -m pip install --upgrade pip \
8+
&& pip install selenium==4.1.0 requests==2.25.1

.gitpod.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
image:
2+
file: .gitpod.dockerfile
3+
4+
tasks:
5+
- name: Setup & build
6+
init: chmod +x ./.github/scripts/build_assets/geckodriver-v0.32.2-linux64/geckodriver
7+
command: npm install && npm run build-icons
8+
- name: Build CSS & run web server
9+
init: npm run build-css && npm run dev
10+
11+
github:
12+
prebuilds:
13+
addBadge: true
14+
addComment: false
15+
addCheck: true
16+
master: true
17+
branches: true
18+
pullRequestsFromForks: true
19+
20+
ports:
21+
- port: 8000
22+
onOpen: open-preview

0 commit comments

Comments
 (0)