Skip to content

Commit 9301c95

Browse files
committed
Initial version. Still subject to change.
0 parents  commit 9301c95

9 files changed

Lines changed: 534 additions & 0 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__

CODE_OF_CONDUCT.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as
6+
contributors and maintainers pledge to making participation in our project and
7+
our community a harassment-free experience for everyone, regardless of age, body
8+
size, disability, ethnicity, gender identity and expression, level of experience,
9+
nationality, personal appearance, race, religion, or sexual identity and
10+
orientation.
11+
12+
## Our Standards
13+
14+
Examples of behavior that contributes to creating a positive environment
15+
include:
16+
17+
* Using welcoming and inclusive language
18+
* Being respectful of differing viewpoints and experiences
19+
* Gracefully accepting constructive criticism
20+
* Focusing on what is best for the community
21+
* Showing empathy towards other community members
22+
23+
Examples of unacceptable behavior by participants include:
24+
25+
* The use of sexualized language or imagery and unwelcome sexual attention or
26+
advances
27+
* Trolling, insulting/derogatory comments, and personal or political attacks
28+
* Public or private harassment
29+
* Publishing others' private information, such as a physical or electronic
30+
address, without explicit permission
31+
* Other conduct which could reasonably be considered inappropriate in a
32+
professional setting
33+
34+
## Our Responsibilities
35+
36+
Project maintainers are responsible for clarifying the standards of acceptable
37+
behavior and are expected to take appropriate and fair corrective action in
38+
response to any instances of unacceptable behavior.
39+
40+
Project maintainers have the right and responsibility to remove, edit, or
41+
reject comments, commits, code, wiki edits, issues, and other contributions
42+
that are not aligned to this Code of Conduct, or to ban temporarily or
43+
permanently any contributor for other behaviors that they deem inappropriate,
44+
threatening, offensive, or harmful.
45+
46+
## Scope
47+
48+
This Code of Conduct applies both within project spaces and in public spaces
49+
when an individual is representing the project or its community. Examples of
50+
representing a project or community include using an official project e-mail
51+
address, posting via an official social media account, or acting as an appointed
52+
representative at an online or offline event. Representation of a project may be
53+
further defined and clarified by project maintainers.
54+
55+
## Enforcement
56+
57+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
58+
reported by contacting the project team at support@adafruit.com. All
59+
complaints will be reviewed and investigated and will result in a response that
60+
is deemed necessary and appropriate to the circumstances. The project team is
61+
obligated to maintain confidentiality with regard to the reporter of an incident.
62+
Further details of specific enforcement policies may be posted separately.
63+
64+
Project maintainers who do not follow or enforce the Code of Conduct in good
65+
faith may face temporary or permanent repercussions as determined by other
66+
members of the project's leadership.
67+
68+
## Attribution
69+
70+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71+
available at [http://contributor-covenant.org/version/1/4][version]
72+
73+
[homepage]: http://contributor-covenant.org
74+
[version]: http://contributor-covenant.org/version/1/4/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Adafruit CircuitPython Build Tools
2+
3+
[![Discord](https://img.shields.io/discord/327254708534116352.svg)](https://discord.gg/nBQh6qu)
4+
5+
This repo contains build scripts used to build the
6+
[Adafruit CircuitPython bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle), [CircuitPython Community bundle](https://github.com/adafruit/CircuitPython_Community_Bundle)
7+
and individual library release zips.

circuitpython_build_tools.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env python3
2+
3+
# The MIT License (MIT)
4+
#
5+
# Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
# THE SOFTWARE.
24+
25+
import os
26+
import os.path
27+
import shutil
28+
import sys
29+
import subprocess
30+
31+
IGNORE_PY = ["setup.py", "conf.py"]
32+
33+
def build_mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
34+
if not quiet:
35+
title = "Building mpy-cross for circuitpython " + circuitpython_tag
36+
print()
37+
print(title)
38+
print("=" * len(title))
39+
40+
os.makedirs("build_deps/", exist_ok=True)
41+
if not os.path.isdir("build_deps/circuitpython"):
42+
clone = subprocess.run("git clone https://github.com/adafruit/circuitpython.git build_deps/circuitpython", shell=True)
43+
if clone.returncode != 0:
44+
sys.exit(clone.returncode)
45+
46+
current_dir = os.getcwd()
47+
os.chdir("build_deps/circuitpython/mpy-cross")
48+
make = subprocess.run("git fetch && git checkout {TAG} && git submodule update && make clean && make".format(TAG=circuitpython_tag), shell=True)
49+
os.chdir(current_dir)
50+
51+
shutil.copy("build_deps/circuitpython/mpy-cross/mpy-cross", mpy_cross_filename)
52+
53+
if make.returncode != 0:
54+
sys.exit(make.returncode)
55+
56+
57+
def build_library(library_path, output_directory, mpy_cross=None):
58+
py_files = []
59+
package_files = []
60+
total_size = 512
61+
for filename in os.listdir(library_path):
62+
full_path = os.path.join(library_path, filename)
63+
init_file = os.path.join(full_path, "__init__.py")
64+
if os.path.isdir(full_path) and os.path.isfile(init_file):
65+
files = os.listdir(full_path)
66+
files = filter(lambda x: x.endswith(".py"), files)
67+
files = map(lambda x: os.path.join(filename, x), files)
68+
package_files.extend(files)
69+
if filename.endswith(".py") and filename not in IGNORE_PY:
70+
py_files.append(filename)
71+
72+
if len(py_files) > 1:
73+
output_directory = os.path.join(output_directory, library)
74+
os.makedirs(output_directory)
75+
package_init = os.path.join(output_directory, "__init__.py")
76+
# Touch the __init__ file.
77+
with open(package_init, 'a'):
78+
pass
79+
80+
if len(package_files) > 1:
81+
for fn in package_files:
82+
base_dir = os.path.join(output_directory, os.path.dirname(fn))
83+
if not os.path.isdir(base_dir):
84+
os.makedirs(base_dir)
85+
total_size += 512
86+
87+
new_extension = ".py"
88+
if mpy_cross:
89+
new_extension = ".mpy"
90+
91+
for filename in py_files:
92+
full_path = os.path.join(library_path, filename)
93+
output_file = os.path.join(output_directory,
94+
filename.replace(".py", new_extension))
95+
if mpy_cross:
96+
mpy_success = subprocess.call([mpy_cross,
97+
"-o", output_file,
98+
full_path])
99+
if mpy_success != 0:
100+
raise RuntimeError("mpy-cross failed on", full_path)
101+
else:
102+
shutil.copyfile(full_path, output_file)
103+
104+
for filename in package_files:
105+
full_path = os.path.join(library_path, filename)
106+
output_file = os.path.join(output_directory,
107+
filename.replace(".py", new_extension))
108+
if (not mpy_cross or
109+
os.stat(full_path).st_size == 0 or
110+
filename.endswith("__init__.py")):
111+
shutil.copyfile(full_path, output_file)
112+
else:
113+
mpy_success = subprocess.call([mpy_cross,
114+
"-o", output_file,
115+
full_path])
116+
if mpy_success != 0:
117+
raise RuntimeError("mpy-cross failed on", full_path)

scripts/build_bundles.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python3
2+
3+
# The MIT License (MIT)
4+
#
5+
# Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
# THE SOFTWARE.
24+
25+
import os
26+
import os.path
27+
import shlex
28+
import shutil
29+
import sys
30+
import subprocess
31+
import zipfile
32+
33+
import circuitpython_build_tools
34+
35+
36+
def add_file(bundle, src_file, zip_name):
37+
bundle.write(src_file, zip_name)
38+
file_size = os.stat(src_file).st_size
39+
file_sector_size = file_size
40+
if file_size % 512 != 0:
41+
file_sector_size = (file_size // 512 + 1) * 512
42+
print(zip_name, file_size, file_sector_size)
43+
return file_sector_size
44+
45+
46+
def build_bundle(lib_location, bundle_version, output_filename,
47+
mpy_cross=None):
48+
build_dir = "build-" + output_filename
49+
build_lib_dir = os.path.join(build_dir, "lib")
50+
if os.path.isdir(build_dir):
51+
print("Deleting existing build.")
52+
shutil.rmtree(build_dir)
53+
os.mkdir(build_dir)
54+
os.mkdir(build_lib_dir)
55+
56+
success = True
57+
total_size = 512
58+
for subdirectory in os.listdir("libraries"):
59+
for library in os.listdir(os.path.join("libraries", subdirectory)):
60+
library_path = os.path.join("libraries", subdirectory, library)
61+
62+
circuitpython_build_tools.build_library(library_path,
63+
build_lib_dir,
64+
mpy_cross=mpy_cross)
65+
66+
with open(os.path.join(build_lib_dir, "VERSIONS.txt"), "w") as f:
67+
f.write(bundle_version + "\r\n")
68+
versions = subprocess.run('git submodule foreach \"git remote get-url origin && git describe --tags\"', shell=True, stdout=subprocess.PIPE)
69+
repo = None
70+
for line in versions.stdout.split(b"\n"):
71+
if line.startswith(b"Entering") or not line:
72+
continue
73+
if line.startswith(b"git@"):
74+
repo = b"https://github.com/" + line.split(b":")[1][:-len(".git")]
75+
elif line.startswith(b"https:"):
76+
repo = line.strip()[:-len(".git")]
77+
else:
78+
f.write(repo.decode("utf-8", "strict") + "/releases/tag/" + line.strip().decode("utf-8", "strict") + "\r\n")
79+
80+
with zipfile.ZipFile(output_filename, 'w') as bundle:
81+
total_size += add_file(bundle, "README.txt", "lib/README.txt")
82+
for filename in os.listdir("update_scripts"):
83+
src_file = os.path.join("update_scripts", filename)
84+
total_size += add_file(bundle, src_file, os.path.join("lib", filename))
85+
for root, dirs, files in os.walk(build_lib_dir):
86+
ziproot = root[len(build_dir + "/"):].replace("-", "_")
87+
for filename in files:
88+
total_size += add_file(bundle, os.path.join(root, filename),
89+
os.path.join(ziproot, filename.replace("-", "_")))
90+
91+
print()
92+
print(total_size, "B", total_size / 1024, "kiB", total_size / 1024 / 1024, "MiB")
93+
print("Bundled in", zip_filename)
94+
if not success:
95+
print("WARNING: some failures above")
96+
sys.exit(2)
97+
98+
99+
if __name__ == "__main__":
100+
from scripts import target_versions
101+
102+
tagged = input("Did you tag this release already ([y]/n)? ")
103+
if tagged and tagged.lower() != 'y':
104+
print("Go ahead and tag. I'll wait.")
105+
sys.exit(3)
106+
107+
bundle_lib_location = os.path.abspath(sys.argv[1])
108+
output_dir = os.path.abspath(sys.argv[2])
109+
os.chdir(bundle_lib_location)
110+
111+
bundle_version = None
112+
tag = subprocess.run('git describe --tags --exact-match', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
113+
if tag.returncode == 0:
114+
bundle_version = tag
115+
else:
116+
commitish = subprocess.run("git log --pretty=format:'%h' -n 1", shell=True, stdout=subprocess.PIPE)
117+
bundle_version = commitish
118+
bundle_version = bundle_version.stdout.strip().decode("utf-8", "strict")
119+
120+
zip_filename = os.path.join(output_dir,
121+
'adafruit-circuitpython-bundle-{VERSION}.zip'.format(
122+
VERSION=bundle_version))
123+
build_bundle(bundle_lib_location, bundle_version, zip_filename)
124+
os.makedirs("build_deps", exist_ok=True)
125+
for version in target_versions.VERSIONS:
126+
mpy_cross = "build_deps/mpy-cross-" + version["name"]
127+
circuitpython_build_tools.build_mpy_cross(mpy_cross, version["tag"])
128+
zip_filename = os.path.join(output_dir,
129+
'adafruit-circuitpython-bundle-{TAG}-{VERSION}.zip'.format(
130+
TAG=version["name"],
131+
VERSION=bundle_version))
132+
build_bundle(bundle_lib_location, bundle_version, zip_filename, mpy_cross=mpy_cross)

0 commit comments

Comments
 (0)