1
0
mirror of https://github.com/konpa/devicon.git synced 2025-08-09 08:06:32 +02:00

Script upgrades and updated CONTRIBUTING.md and README.md (#576)

* Updated README and CONTRIBUTING

* Added check for devicon object when peeking

* Added PR template

* Added a script to create release messages

* Updated CONTRIBUTING about new script

* Update .github/PULL_REQUEST_TEMPLATE/new_icon.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/scripts/build_assets/arg_getters.py

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/workflows/get_release_message.yml

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update gulpfile.js

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/PULL_REQUEST_TEMPLATE/new_feature.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/PULL_REQUEST_TEMPLATE/new_feature.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Added a way for peek bot to comment error

* Update CONTRIBUTING.md

Co-authored-by: Clemens Bastian <8781699+amacado@users.noreply.github.com>

* Update .github/scripts/get_release_message.py

Co-authored-by: Malte Jürgens <maltejur@web.de>

* Update .github/scripts/get_release_message.py

Co-authored-by: Malte Jürgens <maltejur@web.de>

* Update .github/PULL_REQUEST_TEMPLATE/new_feature.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Clean up and updated CONTRIBUTING

* Updated CONTRIBUTING

* Add set up steps for release message workflow

* Refactored peek workflow

* Added requests library

* Reformat devicon object error messages

Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: Clemens Bastian <8781699+amacado@users.noreply.github.com>
Co-authored-by: Malte Jürgens <maltejur@web.de>
This commit is contained in:
Thomas Bui
2021-04-29 01:04:32 -07:00
committed by GitHub
parent be0f01754d
commit 41790e615b
14 changed files with 267 additions and 83 deletions

View File

@@ -0,0 +1,9 @@
## This PR adds...
*List your features here and their reasons for creation.*
## Notes
*List anything note-worthy here (potential issues, this needs merge to `master` before working, etc....).*
*Don't forget to link any issues that this PR will solved.*

View File

@@ -0,0 +1,9 @@
**Double check these details before you open a PR**
- [] PR does not match another non-stale PR currently opened
- [] PR name matches the format *new icon: <i>Icon name</i> (<i>versions separated by comma</i>)* as seen [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#overview)
- [] Your icons are put in a folder as seen [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#organizational-guidelines)
- [] SVG matches the standards laid out [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#svgStandards)
- [] A new object is added in the `devicon.json` file as seen [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#-updating-the-deviconjson-)
Refer to the [`CONTRIBUTING.md`](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#contributing-to-devicon) for more details.

View File

@@ -1,37 +0,0 @@
from typing import List
# abandoned since it's not too hard to check devicon objects using our eyes
# however, still keep in case we need it in the future
def check_devicon_objects(icons: List[dict]):
"""
Check that the devicon objects added is up to standard.
"""
err_msgs = []
for icon in icons:
if type(icon["name"]) != str:
err_msgs.append("'name' must be a string, not: " + str(icon["name"]))
try:
for tag in icon["tags"]:
if type(tag) != str:
raise TypeError()
except TypeError:
err_msgs.append("'tags' must be an array of strings, not: " + str(icon["tags"]))
break
if type(icon["versions"]["svg"]) != list or len(icon["versions"]["svg"]) == 0:
err_msgs.append("Icon name must be a string")
if type(icon["versions"]["font"]) != list or len(icon["versions"]["svg"]) == 0:
err_msgs.append("Icon name must be a string")
if type(icon["color"]) != str or "#" not in icon["color"]:
err_msgs.append("'color' must be a string in the format '#abcdef'")
if type(icon["aliases"]) != list:
err_msgs.append("'aliases' must be an array of dicts")
if len(err_msgs) > 0:
raise Exception("Error found in devicon.json: \n" + "\n".join(err_msgs))

View File

@@ -68,3 +68,14 @@ def get_check_svgs_monthly_args():
help="The path to the icons folder",
action=PathResolverAction)
return parser.parse_args()
def get_release_message_args():
"""
Get the commandline arguments for get_release_message.py.
"""
parser = ArgumentParser(description="Create a text containing the icons and features added since last release.")
parser.add_argument("token",
help="The GitHub token to access the GitHub REST API.",
type=str)
return parser.parse_args()

75
.github/scripts/get_release_message.py vendored Normal file
View File

@@ -0,0 +1,75 @@
import requests
from build_assets import arg_getters
import re
def main():
print("Please wait a few seconds...")
args = arg_getters.get_release_message_args()
queryPath = "https://api.github.com/repos/devicons/devicon/pulls?accept=application/vnd.github.v3+json&state=closed&per_page=100"
stopPattern = r"^(r|R)elease v"
headers = {
"Authorization": f"token {args.token}"
}
response = requests.get(queryPath, headers=headers)
if not response:
print(f"Can't query the GitHub API. Status code is {response.status_code}. Message is {response.text}")
return
data = response.json()
newIcons = []
features = []
for pullData in data:
if re.search(stopPattern, pullData["title"]):
break
authors = findAllAuthors(pullData, headers)
markdown = f"- [{pullData['title']}]({pullData['html_url']}) by {authors}."
if isFeatureIcon(pullData):
newIcons.append(markdown)
else:
features.append(markdown)
thankYou = "A huge thanks to all our maintainers and contributors for making this release possible!"
iconTitle = "**{} New Icons**\n".format(len(newIcons))
featureTitle = "**{} New Features**\n".format(len(features))
finalString = "{0}\n\n {1}{2}\n\n {3}{4}".format(thankYou,
iconTitle, "\n".join(newIcons), featureTitle, "\n".join(features))
print("--------------Here is the build message--------------\n", finalString)
"""
Check whether the pullData is a feature:icon PR.
:param pullData
:return true if the pullData has a label named "feature:icon"
"""
def isFeatureIcon(pullData):
for label in pullData["labels"]:
if label["name"] == "feature:icon":
return True
return False
"""
Find all the authors of a PR based on its commits.
:param pullData - the data of a pull request.
"""
def findAllAuthors(pullData, authHeader):
response = requests.get(pullData["commits_url"], headers=authHeader)
if not response:
print(f"Can't query the GitHub API. Status code is {response.status_code}")
print("Response is: ", response.text)
return
commits = response.json()
authors = set() # want unique authors only
for commit in commits:
authors.add("@" + commit["author"]["login"])
return ", ".join(list(authors))
if __name__ == "__main__":
main()

View File

@@ -2,7 +2,6 @@ from typing import List
import re
import sys
from selenium.common.exceptions import TimeoutException
import xml.etree.ElementTree as et
# pycharm complains that build_assets is an unresolved ref
# don't worry about it, the script still runs
@@ -12,36 +11,28 @@ from build_assets import util
def main():
runner = None
try:
args = arg_getters.get_selenium_runner_args(True)
new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path)
# get only the icon object that has the name matching the pr title
filtered_icons = find_object_added_in_this_pr(new_icons, args.pr_title)
if len(new_icons) == 0:
sys.exit("No files need to be uploaded. Ending script...")
raise Exception("No files need to be uploaded. Ending script...")
if len(filtered_icons) == 0:
message = "No icons found matching the icon name in the PR's title.\n" \
"Ensure that a new icon entry is added in the devicon.json and the PR title matches the convention here: \n" \
"https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#overview\n" \
"Ending script...\n"
sys.exit(message)
# get only the icon object that has the name matching the pr title
filtered_icon = find_object_added_in_this_pr(new_icons, args.pr_title)
print("Icon being checked:", filtered_icon, sep = "\n", end='\n\n')
# print list of new icons
print("List of new icons:", *new_icons, sep = "\n")
print("Icons being uploaded:", *filtered_icons, sep = "\n", end='\n\n')
runner = None
try:
runner = SeleniumRunner(args.download_path, args.geckodriver_path, args.headless)
svgs = filehandler.get_svgs_paths(filtered_icons, args.icons_folder_path, True)
svgs = filehandler.get_svgs_paths([filtered_icon], args.icons_folder_path, True)
screenshot_folder = filehandler.create_screenshot_folder("./")
runner.upload_svgs(svgs, screenshot_folder)
print("Task completed.")
except TimeoutException as e:
util.exit_with_err("Selenium Time Out Error: \n" + str(e))
# no errors, do this so upload-artifact won't fail
filehandler.write_to_file("./err_messages.txt", "0")
except Exception as e:
filehandler.write_to_file("./err_messages.txt", str(e))
util.exit_with_err(e)
finally:
runner.close()
@@ -52,19 +43,77 @@ def find_object_added_in_this_pr(icons: List[dict], pr_title: str):
Find the icon name from the PR title.
:param icons, a list of the font objects found in the devicon.json.
:pr_title, the title of the PR that this workflow was called on.
:return a list containing the dictionary with the "name"
:return a dictionary with the "name"
entry's value matching the name in the pr_title.
If none can be found, return an empty list.
:raise If no object can be found, raise an Exception.
"""
try:
pattern = re.compile(r"(?<=^new icon: )\w+ (?=\(.+\))", re.I)
icon_name = pattern.findall(pr_title)[0].lower().strip() # should only have one match
return [icon for icon in icons if icon["name"] == icon_name]
icon = [icon for icon in icons if icon["name"] == icon_name][0]
check_devicon_object(icon, icon_name)
return icon
except IndexError: # there are no match in the findall()
return []
raise Exception("Couldn't find an icon matching the name in the PR title.")
except ValueError as e:
raise Exception(str(e))
def check_devicon_object(icon: dict, icon_name: str):
"""
Check that the devicon object added is up to standard.
:return a string containing the error messages if any.
"""
err_msgs = []
try:
if icon["name"] != icon_name:
err_msgs.append("- 'name' value is not: " + icon_name)
except KeyError:
err_msgs.append("- missing key: 'name'.")
try:
for tag in icon["tags"]:
if type(tag) != str:
raise TypeError()
except TypeError:
err_msgs.append("- 'tags' must be an array of strings, not: " + str(icon["tags"]))
except KeyError:
err_msgs.append("- missing key: 'tags'.")
try:
if type(icon["versions"]) != dict:
err_msgs.append("- 'versions' must be an object.")
except KeyError:
err_msgs.append("- missing key: 'versions'.")
try:
if type(icon["versions"]["svg"]) != list or len(icon["versions"]["svg"]) == 0:
err_msgs.append("- must contain at least 1 svg version in a list.")
except KeyError:
err_msgs.append("- missing key: 'svg' in 'versions'.")
try:
if type(icon["versions"]["font"]) != list or len(icon["versions"]["svg"]) == 0:
err_msgs.append("- must contain at least 1 font version in a list.")
except KeyError:
err_msgs.append("- missing key: 'font' in 'versions'.")
try:
if type(icon["color"]) != str or "#" not in icon["color"]:
err_msgs.append("- 'color' must be a string in the format '#abcdef'")
except KeyError:
err_msgs.append("- missing key: 'color'.")
try:
if type(icon["aliases"]) != list:
err_msgs.append("- 'aliases' must be an array.")
except KeyError:
err_msgs.append("- missing key: 'aliases'.")
if len(err_msgs) > 0:
message = "Error found in 'devicon.json' for '{}' entry: \n{}".format(icon_name, "\n".join(err_msgs))
raise ValueError(message)
return ""
if __name__ == "__main__":
main()

View File

@@ -1 +1,2 @@
selenium==3.141.0
requests==2.25.1

View File

@@ -0,0 +1,23 @@
name: Get Release Message
on: workflow_dispatch
jobs:
build:
name: Get Fonts From Icomoon
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup Python v3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r ./.github/scripts/requirements.txt
- name: Run the get_release_message.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python ./.github/scripts/get_release_message.py $GITHUB_TOKEN

View File

@@ -44,6 +44,13 @@ jobs:
./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json
./devicon.json ./icons ./ --headless --pr_title "%PR_TITLE%"
- name: Upload the err messages (created by icomoon_peek.py)
uses: actions/upload-artifact@v2
if: always()
with:
name: err_messages
path: ./err_messages.txt
- name: Upload screenshots for comments
uses: actions/upload-artifact@v2
if: success()

View File

@@ -32,6 +32,14 @@ jobs:
with:
path: ./pr_num/pr_num.txt
- name: Read the err message file
if: success()
id: err_message_reader
uses: juliangruber/read-file-action@v1.0.0
with:
path: ./err_messages/err_messages.txt
- name: Upload screenshot of the newly made icons gotten from the artifacts
id: icons_overview_img_step
if: env.PEEK_STATUS == 'success' && success()
@@ -87,15 +95,19 @@ jobs:
MESSAGE: |
Hi there,
I'm Devicons' Peek Bot and it seems we've ran into a problem (sorry!).
I'm Devicons' Peek Bot and it seems we've ran into a problem.
Please double check and fix the possible issues below:
```
{0}
```
Make sure that:
- Your svgs are named and added correctly to the /icons folder as seen [here](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#orgGuidelines).
- Your icon information has been added to the `devicon.json` as seen [here](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#updateDevicon)
- Your PR title follows the format seen [here](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#overview)
I will retry once everything is fixed. If I still fail (sorry!) or there are other erros, the maintainers will investigate.
I will retry once everything is fixed. If I still fail or there are other error, the maintainers will investigate.
Best of luck,
Peek Bot :relaxed:
@@ -103,4 +115,4 @@ jobs:
type: create
issue_number: ${{ steps.pr_num_reader.outputs.content }}
token: ${{ secrets.GITHUB_TOKEN }}
body: ${{ env.MESSAGE }}
body: ${{ format(env.MESSAGE, steps.err_message_reader.outputs.content) }}

View File

@@ -40,6 +40,7 @@ First of all, thanks for taking the time to contribute! This project can only gr
<li>Include the name of the Icon in the pull request title in this format: <code>new icon: <i>Icon name</i> (<i>versions</i>)</code> </li>
<li><i>Optional</i>: Add images of the new svg(s) to the description of the pull request. This would help speed up the review process </li>
<li><i>Optional</i>: Reference the issues regarding the new icon. </li>
<li>A bot will check your SVGs. If there are any errors, please fix them as instructed.</li>
<li>Wait for a maintainer to review your changes. They will run a script to check your icons.</li>
<li>If there are no issues, they will accept your pull request and merge it using <a href="https://github.com/devicons/devicon/discussions/470">squash merging</a>. If there are any problems, they will let you know and give you a chance to fix it.</li>
</ol>
@@ -91,7 +92,6 @@ First of all, thanks for taking the time to contribute! This project can only gr
<li>Each <code>.svg</code> file contains one version of an icon in a <code>0 0 128 128</code> viewbox. You can use a service like <a href="https://www.iloveimg.com/resize-image/resize-svg">resize-image</a> for scaling the svg.</li>
<li>The <code>svg</code> element does not need the <code>height</code> and <code>width</code> attributes. However, if you do use it, ensure their values are either <code>"128"</code> or <code>"128px"</code>. Ex: <code>height="128"</code></li>
<li>Each <code>.svg</code> must use the <code>fill</code> attribute instead of using <code>classes</code> for colors. See <a href="https://github.com/devicons/devicon/issues/407">here</a> for more details.</li>
<li>The naming convention for the svg file is the following: <code>(Technology name)-(original|plain|line)(-wordmark?).</code></li>
</ul>
<hr>
@@ -310,19 +310,20 @@ As an example, let's assume you have created the svgs for Redhat and Amazon Web
<hr>
<h2 id='buildScript'>The Build Script: how it works and its quirks</h2>
<p>To make adding icons easier for repo maintainers, we rely on GitHub Actions, Python, Selenium, and Gulp to automate our tasks.</p>
<p>We rely on GitHub Actions, Python, Selenium, Imgur, and Gulp to automate our tasks. Please feel free to take a look at the workflow files. The codes should be clear enough to follow along.</p>
<p>So far, the tasks in the build script are:</p>
<ul>
<li>Upload svgs to <a href="https://icomoon.io/app/#/select">icomoon.io</a> and get the icons back. For details, see <a href="https://github.com/devicons/devicon/issues/252"> the original disscussion</a>, <a href="https://github.com/devicons/devicon/pull/268">this PR that introduce the feature</a> and <a href="https://github.com/devicons/devicon/issues/300">the final changes to it.</a></li>
<li>Preview what an svg would look like as an icon using the upload svgs script (see <a href="https://github.com/devicons/devicon/pull/412">this</a></li>
<li>Build, combine, and minify CSS files. For details, see <a href="https://github.com/devicons/devicon/pull/290">this</a></li>
<li>Send screenshots to Imgur and upload it to a PR. See <a href="https://github.com/devicons/devicon/pull/398">the PR for the Imgur action</a> and <a href="https://github.com/devicons/devicon/pull/481"> the PR for uploading the pictures to a PR</a>
<li>Upload svgs to <a href="https://icomoon.io/app/#/select">icomoon.io</a> and get the icons back. For details, see <a href="https://github.com/devicons/devicon/issues/252"> the original disscussion</a>, <a href="https://github.com/devicons/devicon/pull/268">this PR that introduce the feature</a> and <a href="https://github.com/devicons/devicon/issues/300">the final changes to it.</a> Used by <b>peek-bot</b> and <b>build-bot</b>.</li>
<li>Preview what an svg would look like as an icon using the upload svgs script (see <a href="https://github.com/devicons/devicon/pull/412">this</a>). Used by <b>peek-bot</b>.</li>
<li>Build, combine, and minify CSS files. For details, see <a href="https://github.com/devicons/devicon/pull/290">this</a>. Used by <b>build-bot</b>.</li>
<li>Send screenshots to Imgur and upload it to a PR. See <a href="https://github.com/devicons/devicon/pull/398">the PR for the Imgur action</a> and <a href="https://github.com/devicons/devicon/pull/481"> the PR for uploading the pictures to a PR. Used by <b>peek-bot</b> and <b>build-bot</b>.</a>
<li>Ensure code quality is up to standard</li>
<li>Comment on the PR so maintainers don't have to manually upload icon result.</li>
<li>Comment on the PR so maintainers don't have to manually upload icon result. Used by <b>peek-bot</b> and <b>build-bot</b>.</li>
<li>Publishing a new release to <a href="https://www.npmjs.com/package/devicon">npm</a>; See <a href="https://github.com/devicons/devicon/issues/288">#288</a></li>
<li>Creating a list of features that was added since last release. See <a href="https://github.com/devicons/devicon/discussions/574">this discussion</a> for inception and limitations. </li>
</ul>
<p>There are some quirks and bugs that the build scripts might run into. Listed below are the common ones and their solution</p>
<p>There are some bugs that the build scripts might run into. Listed below are the common ones and their solutions</p>
<ol>
<li><b>No connection could be made because the target machine actively refused it. (os error 10061)</b>
<ul>
@@ -351,6 +352,13 @@ As an example, let's assume you have created the svgs for Redhat and Amazon Web
<li>Solution: Follow the steps laid out <a href="https://github.com/devicons/devicon/pull/554#issuecomment-816860577">here</a></li>
</ul>
</li>
<li><b>Icon created by Icomoon contains strange lines that aren't in the SVG</b>
<ul>
<li>See <a href="https://github.com/devicons/devicon/pull/532">this PR</a>'s peek result.</li>
<li>This is caused by a bug in Icomoon's parser (see <a href="https://github.com/devicons/devicon/pull/532#issuecomment-827180766">this</a>).</li>
<li>Solution: Luckily this is an extremely rare case. Try remake the svg in a different way (using different paths/shapes) and test using Icomoon.</li>
</ul>
</li>
</ol>
<h2 id="discordServer">Discord server</h2>
@@ -379,7 +387,19 @@ We are running a Discord server. You can go here to talk, discuss, and more with
<li>Push the branch <code>draft-release</code></li>
<li>Manually trigger the workflow <code><a href="https://github.com/devicons/devicon/actions/workflows/build_icons.yml">build_icons.yml</a></code> (which has a <code>workflow_dispatch</code> event trigger) and select the branch <code>draft-release</code> as target branch. This will build a font version of all icons using icomoon and automatically creates a pull request to merge the build result back into <code>draft-release</code></li>
<li>Review and approve the auto-create pull request created by the action of the step above</li>
<li>Create a pull request towards <code>development</code>. Mention the release number in the pull request title (like "Build preparation for release v<i>MAJOR</i>.<i>MINOR</i>.<i>PATCH</i>) and add information about all new icons, fixes, features and enhancements in the description of the pull request. Take the commits as a guideline. It's also a good idea to mention and thank all contributions who participated in the release (take description of <code><a href="https://github.com/devicons/devicon/pull/504">#504</a></code> as an example).</li>
<li>Create a pull request towards <code>development</code>. Mention the release number in the pull request title (like "Build preparation for release v<i>MAJOR</i>.<i>MINOR</i>.<i>PATCH</i>).
<ul>
<li>
Add information about all new icons, fixes, features and enhancements in the description of the pull request.
</li>
<li>
Take the PRs/commits as a guideline. It's also a good idea to mention and thank all contributions who participated in the release (take description of <code><a href="https://github.com/devicons/devicon/pull/504">#504</a></code> as an example).
</li>
<li>
Rather than doing it manually, you can instead run <code>python ./.github/scripts/get_release_message.py $GITHUB_TOKEN</code> locally. Pass in your GitHub Personal Access Token for <code>$GITHUB_TOKEN</code> and you should see the messages. You can also use the `workflow_dispatch` trigger in the GitHub Actions tab.
</li>
</ul>
</li>
<li>Wait for review and approval of the pull request (you can perform a squash-merge)</li>
<li>Once merged create a pull request with BASE <code>master</code> and HEAD <code>development</code>. Copy the description of the earlier pull request.</li>
<li>Since it was already approved in the 'development' stage a maintainer is allowed to merge it (<b>DON'T</b> perform a squash-merge).</li>

View File

@@ -68,8 +68,11 @@
<sub>
All product names, logos, and brands are property of their respective owners. All company, product and service
names used in this website are for identification purposes only. Use of these names, logos, and brands does not
imply endorsement.
imply endorsement. Usage of these logos should be done according to the company/brand/service's brand policy.
</sub>
<p>
Thank you to our contributors and the <a href="https://icomoon.io/#home">IcoMoon app</a>. Devicon would not be possible without you.
</p>
<h2 id="getting-started">Getting started</h2>

View File

@@ -10,6 +10,7 @@ const aliasSCSSName = "devicon-alias.scss";
const colorsCSSName = "devicon-colors.css";
const finalMinSCSSName = "devicon.min.scss";
//////// CSS Tasks ////////
/**
* Create the devicon.min.css by creating needed

View File

@@ -6,7 +6,7 @@
"scripts": {
"build-css": "gulp updateCss && gulp clean",
"peek-test": "python ./.github/scripts/icomoon_peek.py ./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json ./devicon.json ./icons ./ --pr_title \"%PR_TITLE%\"",
"build-test": "python ./.github/scripts/icomoon_build.py ./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json ./devicon.json ./icons ./"
"build-test": "python ./.github/scripts/icomoon_build.py ./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json ./devicon.json ./icons ./",
},
"repository": {
"type": "git",
@@ -28,5 +28,6 @@
"gulp": "^4.0.0",
"gulp-sass": "^4.1.0",
"sass": "^1.26.10"
}
},
"dependencies": {}
}