Compare commits

...

43 commits

Author SHA1 Message Date
35880f474b update tag for 7.x 2021-10-08 21:55:52 -05:00
Scott Shawcroft
cde80f6c85
Merge pull request #73 from lesamouraipourpre/github-actions
Convert from Travis to Github Actions
2021-09-14 11:22:21 -07:00
James Carr
734890c799
Merge branch 'main' of github.com:adafruit/circuitpython-build-tools into github-actions 2021-09-13 20:29:48 +01:00
Scott Shawcroft
1b3ea7d630
Merge pull request #77 from FoamyGuy/circuitpython_org_pypi_name
fix pypi names for circuitpython org libraries
2021-09-13 12:10:33 -07:00
foamyguy
3845cee485 fix pypi names for circuitpython org libraries 2021-09-11 11:43:09 -05:00
Scott Shawcroft
bdcdafdb90
Merge pull request #76 from lesamouraipourpre/patch-1
Update target_versions.py to the latest versions
2021-06-08 13:58:42 -07:00
James Carr
baec9067b8
Update target_versions.py to the latest versions 2021-06-07 23:59:03 +01:00
Jeff Epler
4d055bb535
Merge pull request #72 from lesamouraipourpre/aws-mpy-cross
Use mpy-cross from S3 if possible
2021-05-30 12:19:00 -06:00
James Carr
eadbc29632
Add 'if not quiet' to the print statements 2021-05-30 15:45:33 +01:00
James Carr
853dc57e87
Update Python in Travis to 3.7 2021-05-30 13:05:45 +01:00
James Carr
743c550128
Convert from Travis to Github Actions (Closes #59)
BREAKING CHANGES
This REQUIRES releases to generate the artifacts not just tags.
This DOES NOT generate the data directory containing mpy-cross versions.
2021-05-30 12:50:51 +01:00
James Carr
385cbc607d
Add author info 2021-05-30 12:42:37 +01:00
James Carr
98b12389a8
Replace tab with spaces 2021-05-30 11:27:09 +01:00
James Carr
f69bc7b660
Add basic exception handling around the S3 request 2021-05-30 11:24:43 +01:00
James Carr
39b1fe192f
Add Linux/x86_64 to mpy-cross S3 check 2021-05-30 00:28:56 +01:00
James Carr
c9a7d6323e
Update Python requirement to 3.7 2021-05-30 00:27:06 +01:00
James Carr
385b448490
Merge branch 'aws-mpy-cross' of github.com:lesamouraipourpre/circuitpython-build-tools into aws-mpy-cross 2021-05-29 20:10:39 +01:00
James Carr
f4532c667c
Add macos support to S3 mpy-cross 2021-05-29 20:08:03 +01:00
James Carr
1b45018a49
Update setup.py to install requests 2021-05-29 20:08:03 +01:00
James Carr
4c8cf86ebb
Pull mpy-cross from AWS S3 instead of building. (Closes #55)
Fall back to building if fetching fails.
2021-05-29 20:07:11 +01:00
James Carr
4aafea594f
Update setup.py to install requests 2021-05-29 18:35:56 +01:00
James Carr
03fd236dd4
Pull mpy-cross from AWS S3 instead of building.
Fall back to building if fetching fails.
2021-05-29 18:25:49 +01:00
Jeff Epler
716a38c713
Merge pull request #71 from adafruit/tannewt-patch-7
Update 7.x tag for the (hopefully) final MPY version
2021-05-10 17:43:00 -05:00
Scott Shawcroft
59651e993f
Update 7.x tag for the (hopefully) final MPY version 2021-05-10 15:13:02 -07:00
Melissa LeBlanc-Williams
f8bbac8d81
Merge pull request #69 from makermelissa/master
Fix PyPI names in json when .git is missing
2021-04-07 13:46:16 -07:00
Melissa LeBlanc-Williams
e9ba66eb93 Fix PyPI names in json when .git is missing 2021-04-07 13:41:15 -07:00
Kattni
9a523be681
Merge pull request #68 from kattni/update-versions
Update to 6.2.0 and add 7.
2021-04-07 16:14:47 -04:00
Kattni Rembor
28072e3995 Update to 6.2.0 and add 7. 2021-04-07 16:04:41 -04:00
Dan Halbert
7b0b16d2be
Merge pull request #66 from makermelissa/master
Bundle JSON improvements
2021-03-31 13:07:13 -04:00
Melissa LeBlanc-Williams
336d6b9a53 Changed LINUX LIBS to BLINKA LIBS and added a couple more 2021-03-31 09:59:15 -07:00
Melissa LeBlanc-Williams
243a717ff4 Added PyPI Name for external package matching 2021-03-31 09:31:16 -07:00
Melissa LeBlanc-Williams
3bb57a8c58 Remove quotes used for testing 2021-03-31 09:27:59 -07:00
Melissa LeBlanc-Williams
6866d2609a Bundle JSON improvements 2021-03-31 09:23:13 -07:00
Melissa LeBlanc-Williams
248bc56a4a
Merge pull request #65 from makermelissa/master
Add library versions to JSON
2021-03-24 16:24:32 -07:00
Melissa LeBlanc-Williams
ffa8fe9324 Add library versions to JSON 2021-03-24 16:17:53 -07:00
Melissa LeBlanc-Williams
3b529b4dfb
Merge pull request #64 from makermelissa/master 2021-03-23 20:22:42 -07:00
Melissa LeBlanc-Williams
e457d835c0 Fix some packages were incorrectly detected 2021-03-23 15:43:29 -07:00
Melissa LeBlanc-Williams
9d9d4ef222
Merge pull request #63 from makermelissa/master
Added JSON generator for bundle
2021-03-23 12:01:42 -07:00
Melissa LeBlanc-Williams
85a47fc9c1 Added JSON generator for bundle 2021-03-23 11:53:31 -07:00
Jeff Epler
91a63134a4
Merge pull request #62 from Neradoc/fix-missing-requirements
Fix requirements missing for single file modules
2021-03-05 12:58:06 -06:00
Neradoc
ddbd38f9a3 fix requirements for single file modules (fixes identifying single file modules) 2021-03-05 06:33:57 +01:00
Jeff Epler
00468b1fc3
Merge pull request #60 from jepler/include-requirements-in-bundle
library: Include requirements.txt metadata
2021-02-11 08:17:30 -06:00
Jeff Epler
d34e5226e7 library: Include requirements.txt metadata
It is hoped that this data will be useful to circup, enabling it to find
dependency information without phoning out to github.
2021-02-09 11:58:33 -06:00
9 changed files with 283 additions and 56 deletions

52
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,52 @@
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: 2021 James Carr
#
# SPDX-License-Identifier: MIT
name: Build CI
on: [pull_request, push]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Versions
run: |
python3 --version
- name: Checkout Current Repo
uses: actions/checkout@v2
- name: Install requirements
run: |
sudo apt-get update
sudo apt-get install libudev-dev libusb-1.0
sudo apt-get install -y gettext
pip install -r requirements.txt
- name: Library version
run: git describe --dirty --always --tags
- name: Install package locally
run: pip install -e .
- name: Test building single package
run: |
git clone https://github.com/adafruit/Adafruit_CircuitPython_FeatherWing.git
cd Adafruit_CircuitPython_FeatherWing
circuitpython-build-bundles --filename_prefix test-single --library_location .
- name: Test building bundle
run: |
# Use the community bundle because it's smaller and faster
git clone --recurse-submodules https://github.com/adafruit/CircuitPython_Community_Bundle.git
cd CircuitPython_Community_Bundle
circuitpython-build-bundles --filename_prefix test-bundle --library_location libraries --library_depth 2
- name: Build Python package
run: |
pip install --upgrade setuptools wheel twine readme_renderer testresources
python setup.py sdist
twine check dist/*

31
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: 2021 James Carr
#
# SPDX-License-Identifier: MIT
name: Release Actions
on:
release:
types: [published]
jobs:
upload-pypi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.7'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.pypi_username }}
TWINE_PASSWORD: ${{ secrets.pypi_password }}
run: |
python setup.py sdist
twine upload dist/*

2
.gitignore vendored
View file

@ -8,3 +8,5 @@ circuitpython_build_tools/data/
.eggs .eggs
version.py version.py
.env/* .env/*
.DS_Store
.idea/*

View file

@ -1,50 +0,0 @@
dist: xenial
language: python
python:
- '3.6'
stages:
- name: Tests
if: type = pull_request
- name: deploy
if: tag IS present
jobs:
include:
- stage: Tests
name: "Test CircuitPython Bundle"
python: "3.6"
script:
- echo "Building mpy-cross" && echo "travis_fold:start:mpy-cross"
- python3 -u -m circuitpython_build_tools.scripts.build_mpy_cross circuitpython_build_tools/data/
- echo "travis_fold:end:mpy-cross"
- pip install -e .
- echo "Cloning Adafruit_CircuitPython_Bundle" && echo "travis_fold:start:clone"
- git clone --recurse-submodules https://github.com/adafruit/Adafruit_CircuitPython_Bundle.git
- echo "travis_fold:end:clone"
- cd Adafruit_CircuitPython_Bundle
- circuitpython-build-bundles --filename_prefix test-bundle --library_location libraries --library_depth 2
- stage: Tests
name: "Test Single Library Bundle"
script:
- echo "Building mpy-cross" && echo "travis_fold:start:mpy-cross"
- python3 -u -m circuitpython_build_tools.scripts.build_mpy_cross circuitpython_build_tools/data/
- echo "travis_fold:end:mpy-cross"
- pip install -e .
- git clone https://github.com/adafruit/Adafruit_CircuitPython_FeatherWing.git
- cd Adafruit_CircuitPython_FeatherWing
- circuitpython-build-bundles --filename_prefix test-single --library_location .
- stage: deploy
script:
- python3 -u -m circuitpython_build_tools.scripts.build_mpy_cross circuitpython_build_tools/data/
deploy:
provider: pypi
user: "adafruit-travis"
password:
secure: tCjXwD8YeitG0HZLxW1D1QlVv4Xbj8mfRoqW0CM9ikPp3KY1PCz6Axj0PiOcyVwKdnxcUQ0EGRl16wEqwkObrmo9MboYrPuPqN00ULmyCQCRvJa2abIN6jDoLtBuf6bcze88t0XY2LdMOcj2Udv5Iijgf95zUgE+Z6BqT9Rgche78JEOeANJ7BlAJ6nRCA4whDdG7J9s7SmFtIjKWtMxig2J3X+Qy0bZ+Armtfp9/CRvjLJ8juDrcCBSysWLnAYLS4u8e/rbSTh8YwFeoeJ1pp9qSmME5NuwScY18QmfESNSqz8wVVXtAFKdoMOCoN+/CodTxp9aB0QsXX6yOYg74ahDIaci239wgnuUqxSaeLxeSwWkkVCXWdQVuP4vgq3GZwm2yNOQ1ZjfFbXF156yv0uSVw5nuaxv0YblQTinJtL4x9hwOdPDJio3b6UT3H1ue9l1qK0LT2OSkzDgn12WmTnTfRUH3BkU6onsYsdP33PK1YhepeQnfbT1P3ikrRHIwGYb7XqcjOtJh413kid6YezCXRqccl8kAxegnqX+cQG7K9ilpZtWaVYLu4RRBJ37H4vpuOb3SV686Y62sWPUXEbI3MR1OxU+RrRr/9DCH1EFXnlYT9LF986wXFJtWuSc+pbXuxY7qduai0hn5Pft6XH31exyiOwAHBIFeYebnVM=
skip_cleanup: true
on:
tags: true

View file

@ -4,6 +4,7 @@
# #
# Copyright (c) 2016 Scott Shawcroft for Adafruit Industries # Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
# 2018, 2019 Michael Schroeder # 2018, 2019 Michael Schroeder
# 2021 James Carr
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
@ -26,14 +27,17 @@
import os import os
import os.path import os.path
import pathlib import pathlib
import requests
import semver import semver
import shutil import shutil
import stat
import sys import sys
import subprocess import subprocess
import tempfile import tempfile
IGNORE_PY = ["setup.py", "conf.py", "__init__.py"] IGNORE_PY = ["setup.py", "conf.py", "__init__.py"]
GLOB_PATTERNS = ["*.py", "font5x8.bin"] GLOB_PATTERNS = ["*.py", "font5x8.bin"]
S3_MPY_PREFIX = "https://adafruit-circuit-python.s3.amazonaws.com/bin/mpy-cross/"
def version_string(path=None, *, valid_semver=False): def version_string(path=None, *, valid_semver=False):
version = None version = None
@ -64,6 +68,38 @@ def version_string(path=None, *, valid_semver=False):
def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False): def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
if os.path.isfile(mpy_cross_filename): if os.path.isfile(mpy_cross_filename):
return return
# Try to pull from S3
uname = os.uname()
s3_url = None
if uname[0] == 'Linux' and uname[4] in ('amd64', 'x86_64'):
s3_url = f"{S3_MPY_PREFIX}mpy-cross.static-amd64-linux-{circuitpython_tag}"
elif uname[0] == 'Linux' and uname[4] == 'armv7l':
s3_url = f"{S3_MPY_PREFIX}mpy-cross.static-raspbian-{circuitpython_tag}"
elif uname[0] == 'Darwin' and uname[4] == 'x86_64':
s3_url = f"{S3_MPY_PREFIX}mpy-cross-macos-catalina-{circuitpython_tag}"
elif not quiet:
print(f"Pre-built mpy-cross not available for sysname='{uname[0]}' release='{uname[2]}' machine='{uname[4]}'.")
if s3_url is not None:
if not quiet:
print(f"Checking S3 for {s3_url}")
try:
r = requests.get(s3_url)
if r.status_code == 200:
with open(mpy_cross_filename, "wb") as f:
f.write(r.content)
# Set the User Execute bit
os.chmod(mpy_cross_filename, os.stat(mpy_cross_filename)[0] | stat.S_IXUSR)
if not quiet:
print(" FOUND")
return
except Exception as e:
if not quiet:
print(f" exception fetching from S3: {e}")
if not quiet:
print(" NOT FOUND")
if not quiet: if not quiet:
title = "Building mpy-cross for circuitpython " + circuitpython_tag title = "Building mpy-cross for circuitpython " + circuitpython_tag
print() print()
@ -103,6 +139,46 @@ def _munge_to_temp(original_path, temp_file, library_version):
temp_file.write(line.encode("utf-8") + b"\r\n") temp_file.write(line.encode("utf-8") + b"\r\n")
temp_file.flush() temp_file.flush()
def get_package_info(library_path, package_folder_prefix):
lib_path = pathlib.Path(library_path)
parent_idx = len(lib_path.parts)
py_files = []
package_files = []
package_info = {}
glob_search = []
for pattern in GLOB_PATTERNS:
glob_search.extend(list(lib_path.rglob(pattern)))
package_info["is_package"] = False
for file in glob_search:
if file.parts[parent_idx] != "examples":
if len(file.parts) > parent_idx + 1:
for prefix in package_folder_prefix:
if file.parts[parent_idx].startswith(prefix):
package_info["is_package"] = True
if package_info["is_package"]:
package_files.append(file)
else:
if file.name in IGNORE_PY:
#print("Ignoring:", file.resolve())
continue
if file.parent == lib_path:
py_files.append(file)
if package_files:
package_info["module_name"] = package_files[0].relative_to(library_path).parent.name
elif py_files:
package_info["module_name"] = py_files[0].relative_to(library_path).name[:-3]
else:
package_info["module_name"] = None
try:
package_info["version"] = version_string(library_path, valid_semver=True)
except ValueError as e:
package_info["version"] = version_string(library_path)
return package_info
def library(library_path, output_directory, package_folder_prefix, def library(library_path, output_directory, package_folder_prefix,
mpy_cross=None, example_bundle=False): mpy_cross=None, example_bundle=False):
py_files = [] py_files = []
@ -122,9 +198,10 @@ def library(library_path, output_directory, package_folder_prefix,
else: else:
if not example_bundle: if not example_bundle:
is_package = False is_package = False
for prefix in package_folder_prefix: if len(file.parts) > parent_idx + 1:
if file.parts[parent_idx].startswith(prefix): for prefix in package_folder_prefix:
is_package = True if file.parts[parent_idx].startswith(prefix):
is_package = True
if is_package: if is_package:
package_files.append(file) package_files.append(file)
@ -139,6 +216,13 @@ def library(library_path, output_directory, package_folder_prefix,
raise ValueError("Multiple top level py files not allowed. Please put " raise ValueError("Multiple top level py files not allowed. Please put "
"them in a package or combine them into a single file.") "them in a package or combine them into a single file.")
if package_files:
module_name = package_files[0].relative_to(library_path).parent.name
elif py_files:
module_name = py_files[0].relative_to(library_path).name[:-3]
else:
module_name = None
for fn in example_files: for fn in example_files:
base_dir = os.path.join(output_directory.replace("/lib", "/"), base_dir = os.path.join(output_directory.replace("/lib", "/"),
fn.relative_to(library_path).parent) fn.relative_to(library_path).parent)
@ -208,6 +292,22 @@ def library(library_path, output_directory, package_folder_prefix,
if mpy_success != 0: if mpy_success != 0:
raise RuntimeError("mpy-cross failed on", full_path) raise RuntimeError("mpy-cross failed on", full_path)
requirements_files = lib_path.glob("requirements.txt*")
requirements_files = [f for f in requirements_files if f.stat().st_size > 0]
if module_name and requirements_files and not example_bundle:
requirements_dir = pathlib.Path(output_directory).parent / "requirements"
if not os.path.isdir(requirements_dir):
os.makedirs(requirements_dir, exist_ok=True)
total_size += 512
requirements_subdir = f"{requirements_dir}/{module_name}"
if not os.path.isdir(requirements_subdir):
os.makedirs(requirements_subdir, exist_ok=True)
total_size += 512
for filename in requirements_files:
full_path = os.path.join(library_path, filename)
output_file = os.path.join(requirements_subdir, "requirements.txt")
shutil.copyfile(full_path, output_file)
for filename in example_files: for filename in example_files:
full_path = os.path.join(library_path, filename) full_path = os.path.join(library_path, filename)
output_file = os.path.join(output_directory.replace("/lib", "/"), output_file = os.path.join(output_directory.replace("/lib", "/"),

View file

@ -25,6 +25,7 @@
import json import json
import os import os
import os.path import os.path
import re
import shlex import shlex
import shutil import shutil
import subprocess import subprocess
@ -38,6 +39,15 @@ from circuitpython_build_tools import target_versions
import pkg_resources import pkg_resources
BLINKA_LIBRARIES = [
"adafruit-blinka",
"adafruit-blinka-bleio",
"adafruit-blinka-displayio",
"adafruit-blinka-pyportal",
"adafruit-python-extended-bus",
"pyserial",
]
def add_file(bundle, src_file, zip_name): def add_file(bundle, src_file, zip_name):
bundle.write(src_file, zip_name) bundle.write(src_file, zip_name)
file_size = os.stat(src_file).st_size file_size = os.stat(src_file).st_size
@ -47,6 +57,80 @@ def add_file(bundle, src_file, zip_name):
print(zip_name, file_size, file_sector_size) print(zip_name, file_size, file_sector_size)
return file_sector_size return file_sector_size
def get_module_name(library_path):
"""Figure out the module or package name and return it"""
repo = subprocess.run('git remote get-url origin', shell=True, stdout=subprocess.PIPE, cwd=library_path)
repo = repo.stdout.decode("utf-8", errors="ignore").strip().lower()
if repo[-4:] == ".git":
repo = repo[:-4]
module_name = repo.split("/")[-1].replace("_", "-")
# circuitpython org repos are deployed to pypi without "org" in the pypi name
module_name = re.sub(r"^circuitpython-org-", "circuitpython-", module_name)
return module_name, repo
def get_bundle_requirements(directory, package_list):
"""
Open the requirements.txt if it exists
Remove anything that shouldn't be a requirement like Adafruit_Blinka
Return the list
"""
pypi_reqs = [] # For multiple bundle dependency
dependencies = [] # For intra-bundle dependency
path = directory + "/requirements.txt"
if os.path.exists(path):
with open(path, "r") as file:
requirements = file.read()
file.close()
for line in requirements.split("\n"):
line = line.lower().strip()
if line.startswith("#") or line == "":
# skip comments
pass
else:
if any(operators in line for operators in [">", "<", "="]):
# Remove everything after any pip style version specifiers
line = re.split("[<|>|=|]", line)[0]
if line not in dependencies and line in package_list:
dependencies.append(package_list[line]["module_name"])
elif line not in pypi_reqs and line not in BLINKA_LIBRARIES:
pypi_reqs.append(line)
return dependencies, pypi_reqs
def build_bundle_json(libs, bundle_version, output_filename, package_folder_prefix):
"""
Generate a JSON file of all the libraries in libs
"""
packages = {}
for library_path in libs:
package = {}
package_info = build.get_package_info(library_path, package_folder_prefix)
module_name, repo = get_module_name(library_path)
if package_info["module_name"] is not None:
package["module_name"] = package_info["module_name"]
package["pypi_name"] = module_name
package["repo"] = repo
package["is_folder"] = package_info["is_package"]
package["version"] = package_info["version"]
package["path"] = "lib/" + package_info["module_name"]
package["library_path"] = library_path
packages[module_name] = package
library_submodules = {}
for id in packages:
library = {}
library["package"] = packages[id]["is_folder"]
library["pypi_name"] = packages[id]["pypi_name"]
library["version"] = packages[id]["version"]
library["repo"] = packages[id]["repo"]
library["path"] = packages[id]["path"]
library["dependencies"], library["external_dependencies"] = get_bundle_requirements(packages[id]["library_path"], packages)
library_submodules[packages[id]["module_name"]] = library
out_file = open(output_filename, "w")
json.dump(library_submodules, out_file)
out_file.close()
def build_bundle(libs, bundle_version, output_filename, package_folder_prefix, def build_bundle(libs, bundle_version, output_filename, package_folder_prefix,
build_tools_version="devel", mpy_cross=None, example_bundle=False): build_tools_version="devel", mpy_cross=None, example_bundle=False):
@ -188,3 +272,9 @@ def build_bundles(filename_prefix, output_directory, library_location, library_d
VERSION=bundle_version)) VERSION=bundle_version))
build_bundle(libs, bundle_version, zip_filename, package_folder_prefix, build_bundle(libs, bundle_version, zip_filename, package_folder_prefix,
build_tools_version=build_tools_version, example_bundle=True) build_tools_version=build_tools_version, example_bundle=True)
# Build Bundle JSON
json_filename = os.path.join(output_directory,
filename_prefix + '-{VERSION}.json'.format(
VERSION=bundle_version))
build_bundle_json(libs, bundle_version, json_filename, package_folder_prefix)

View file

@ -25,5 +25,6 @@
# The tag specifies which version of CircuitPython to use for mpy-cross. # The tag specifies which version of CircuitPython to use for mpy-cross.
# The name is used when constructing the zip file names. # The name is used when constructing the zip file names.
VERSIONS = [ VERSIONS = [
{"tag": "6.1.0", "name": "6.x"}, {"tag": "6.3.0", "name": "6.x"},
{"tag": "7.0.0", "name": "7.x"},
] ]

View file

@ -1,3 +1,4 @@
Click Click
requests
semver semver
wheel wheel

View file

@ -13,8 +13,8 @@ setup(name='circuitpython-build-tools',
'circuitpython_build_tools.scripts'], 'circuitpython_build_tools.scripts'],
package_data={'circuitpython_build_tools': ['data/mpy-cross-*']}, package_data={'circuitpython_build_tools': ['data/mpy-cross-*']},
zip_safe=False, zip_safe=False,
python_requires='>=3.4', python_requires='>=3.7',
install_requires=['Click', 'semver'], install_requires=['Click', 'requests', 'semver'],
entry_points=''' entry_points='''
[console_scripts] [console_scripts]
circuitpython-build-bundles=circuitpython_build_tools.scripts.build_bundles:build_bundles circuitpython-build-bundles=circuitpython_build_tools.scripts.build_bundles:build_bundles