Skip to content

Commit af5d35f

Browse files
authored
Merge pull request #39 from pimoroni/patch-update-packaging
Update packaging/CI
2 parents da98fca + b96dcdb commit af5d35f

File tree

14 files changed

+585
-291
lines changed

14 files changed

+585
-291
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
python: [2.7, 3.4, 3.5, 3.7, 3.8]
14+
python: [2.7, 3.5, 3.7, 3.9]
1515

1616
steps:
1717
- uses: actions/checkout@v2
@@ -32,6 +32,6 @@ jobs:
3232
working-directory: library
3333
run: |
3434
python -m pip install coveralls
35-
coveralls
36-
if: ${{ matrix.python == '3.8' }}
35+
coveralls --service github
36+
if: ${{ matrix.python == '3.9' }}
3737

Makefile

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,49 @@
1+
LIBRARY_VERSION=$(shell grep version library/setup.cfg | awk -F" = " '{print $$2}')
2+
LIBRARY_NAME=$(shell grep name library/setup.cfg | awk -F" = " '{print $$2}')
3+
14
.PHONY: usage install uninstall
25
usage:
6+
@echo "Library: ${LIBRARY_NAME}"
7+
@echo "Version: ${LIBRARY_VERSION}\n"
38
@echo "Usage: make <target>, where target is one of:\n"
49
@echo "install: install the library locally from source"
510
@echo "uninstall: uninstall the local library"
6-
@echo "python-readme: generate library/README.rst from README.md"
11+
@echo "check: peform basic integrity checks on the codebase"
12+
@echo "python-readme: generate library/README.md from README.md + library/CHANGELOG.txt"
713
@echo "python-wheels: build python .whl files for distribution"
814
@echo "python-sdist: build python source distribution"
915
@echo "python-clean: clean python build and dist directories"
10-
@echo "python-dist: build all python distribution files"
16+
@echo "python-dist: build all python distribution files"
17+
@echo "python-testdeploy: build all and deploy to test PyPi"
18+
@echo "tag: tag the repository with the current version"
1119

1220
install:
1321
./install.sh
1422

1523
uninstall:
1624
./uninstall.sh
1725

18-
python-readme: library/README.rst
26+
check:
27+
@echo "Checking for trailing whitespace"
28+
@! grep -IUrn --color "[[:blank:]]$$" --exclude-dir=packaging --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO
29+
@echo "Checking for DOS line-endings"
30+
@! grep -IlUrn --color "" --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile
31+
@echo "Checking library/CHANGELOG.txt"
32+
@cat library/CHANGELOG.txt | grep ^${LIBRARY_VERSION}
33+
@echo "Checking library/${LIBRARY_NAME}/__init__.py"
34+
@cat library/${LIBRARY_NAME}/__init__.py | grep "^__version__ = '${LIBRARY_VERSION}'"
35+
36+
tag:
37+
git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}"
38+
39+
python-readme: library/README.md
1940

2041
python-license: library/LICENSE.txt
2142

22-
library/README.rst: README.md
23-
pandoc --from=markdown --to=rst -o library/README.rst README.md
43+
library/README.md: README.md library/CHANGELOG.txt
44+
cp README.md library/README.md
45+
printf "\n# Changelog\n" >> library/README.md
46+
cat library/CHANGELOG.txt >> library/README.md
2447

2548
library/LICENSE.txt: LICENSE
2649
cp LICENSE library/LICENSE.txt
@@ -40,5 +63,8 @@ python-clean:
4063
python-dist: python-clean python-wheels python-sdist
4164
ls library/dist
4265

43-
python-deploy: python-dist
66+
python-testdeploy: python-dist
67+
twine upload --repository-url https://test.pypi.org/legacy/ library/dist/*
68+
69+
python-deploy: check python-dist
4470
twine upload library/dist/*

install.sh

Lines changed: 241 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,254 @@
11
#!/bin/bash
22

3-
printf "BME680 Python Library: Installer\n\n"
3+
CONFIG=/boot/config.txt
4+
DATESTAMP=`date "+%Y-%M-%d-%H-%M-%S"`
5+
CONFIG_BACKUP=false
6+
APT_HAS_UPDATED=false
7+
USER_HOME=/home/$SUDO_USER
8+
RESOURCES_TOP_DIR=$USER_HOME/Pimoroni
9+
WD=`pwd`
10+
USAGE="sudo ./install.sh (--unstable)"
11+
POSITIONAL_ARGS=()
12+
UNSTABLE=false
13+
PYTHON3=`which python3`
414

5-
if [ $(id -u) -ne 0 ]; then
6-
printf "Script must be run as root. Try 'sudo ./install.sh'\n"
15+
user_check() {
16+
if [ $(id -u) -ne 0 ]; then
17+
printf "Script must be run as root. Try 'sudo ./install.sh'\n"
18+
exit 1
19+
fi
20+
}
21+
22+
confirm() {
23+
if [ "$FORCE" == '-y' ]; then
24+
true
25+
else
26+
read -r -p "$1 [y/N] " response < /dev/tty
27+
if [[ $response =~ ^(yes|y|Y)$ ]]; then
28+
true
29+
else
30+
false
31+
fi
32+
fi
33+
}
34+
35+
prompt() {
36+
read -r -p "$1 [y/N] " response < /dev/tty
37+
if [[ $response =~ ^(yes|y|Y)$ ]]; then
38+
true
39+
else
40+
false
41+
fi
42+
}
43+
44+
success() {
45+
echo -e "$(tput setaf 2)$1$(tput sgr0)"
46+
}
47+
48+
inform() {
49+
echo -e "$(tput setaf 6)$1$(tput sgr0)"
50+
}
51+
52+
warning() {
53+
echo -e "$(tput setaf 1)$1$(tput sgr0)"
54+
}
55+
56+
function do_config_backup {
57+
if [ ! $CONFIG_BACKUP == true ]; then
58+
CONFIG_BACKUP=true
59+
FILENAME="config.preinstall-$LIBRARY_NAME-$DATESTAMP.txt"
60+
inform "Backing up $CONFIG to /boot/$FILENAME\n"
61+
cp $CONFIG /boot/$FILENAME
62+
mkdir -p $RESOURCES_TOP_DIR/config-backups/
63+
cp $CONFIG $RESOURCES_TOP_DIR/config-backups/$FILENAME
64+
if [ -f "$UNINSTALLER" ]; then
65+
echo "cp $RESOURCES_TOP_DIR/config-backups/$FILENAME $CONFIG" >> $UNINSTALLER
66+
fi
67+
fi
68+
}
69+
70+
function apt_pkg_install {
71+
PACKAGES=()
72+
PACKAGES_IN=("$@")
73+
for ((i = 0; i < ${#PACKAGES_IN[@]}; i++)); do
74+
PACKAGE="${PACKAGES_IN[$i]}"
75+
if [ "$PACKAGE" == "" ]; then continue; fi
76+
printf "Checking for $PACKAGE\n"
77+
dpkg -L $PACKAGE > /dev/null 2>&1
78+
if [ "$?" == "1" ]; then
79+
PACKAGES+=("$PACKAGE")
80+
fi
81+
done
82+
PACKAGES="${PACKAGES[@]}"
83+
if ! [ "$PACKAGES" == "" ]; then
84+
echo "Installing missing packages: $PACKAGES"
85+
if [ ! $APT_HAS_UPDATED ]; then
86+
apt update
87+
APT_HAS_UPDATED=true
88+
fi
89+
apt install -y $PACKAGES
90+
if [ -f "$UNINSTALLER" ]; then
91+
echo "apt uninstall -y $PACKAGES"
92+
fi
93+
fi
94+
}
95+
96+
while [[ $# -gt 0 ]]; do
97+
K="$1"
98+
case $K in
99+
-u|--unstable)
100+
UNSTABLE=true
101+
shift
102+
;;
103+
*)
104+
if [[ $1 == -* ]]; then
105+
printf "Unrecognised option: $1\n";
106+
printf "Usage: $USAGE\n";
107+
exit 1
108+
fi
109+
POSITIONAL_ARGS+=("$1")
110+
shift
111+
esac
112+
done
113+
114+
user_check
115+
116+
apt_pkg_install python-configparser
117+
118+
CONFIG_VARS=`python - <<EOF
119+
from configparser import ConfigParser
120+
c = ConfigParser()
121+
c.read('library/setup.cfg')
122+
p = dict(c['pimoroni'])
123+
# Convert multi-line config entries into bash arrays
124+
for k in p.keys():
125+
fmt = '"{}"'
126+
if '\n' in p[k]:
127+
p[k] = "'\n\t'".join(p[k].split('\n')[1:])
128+
fmt = "('{}')"
129+
p[k] = fmt.format(p[k])
130+
print("""
131+
LIBRARY_NAME="{name}"
132+
LIBRARY_VERSION="{version}"
133+
""".format(**c['metadata']))
134+
print("""
135+
PY3_DEPS={py3deps}
136+
PY2_DEPS={py2deps}
137+
SETUP_CMDS={commands}
138+
CONFIG_TXT={configtxt}
139+
PY3_ONLY={py3only}
140+
""".format(**p))
141+
EOF`
142+
143+
if [ $? -ne 0 ]; then
144+
warning "Error parsing configuration...\n"
7145
exit 1
8146
fi
9147
148+
eval $CONFIG_VARS
149+
150+
RESOURCES_DIR=$RESOURCES_TOP_DIR/$LIBRARY_NAME
151+
UNINSTALLER=$RESOURCES_DIR/uninstall.sh
152+
153+
mkdir -p $RESOURCES_DIR
154+
155+
cat << EOF > $UNINSTALLER
156+
printf "It's recommended you run these steps manually.\n"
157+
printf "If you want to run the full script, open it in\n"
158+
printf "an editor and remove 'exit 1' from below.\n"
159+
exit 1
160+
EOF
161+
162+
printf "$LIBRARY_NAME $LIBRARY_VERSION Python Library: Installer\n\n"
163+
164+
if $UNSTABLE; then
165+
warning "Installing unstable library from source.\n\n"
166+
else
167+
printf "Installing stable library from pypi.\n\n"
168+
fi
169+
10170
cd library
11171
12-
printf "Installing for Python 2..\n"
13-
python setup.py install
172+
if ! $PY3_ONLY; then
173+
printf "Installing for Python 2..\n"
174+
apt_pkg_install "${PY2_DEPS[@]}"
175+
if $UNSTABLE; then
176+
python setup.py install > /dev/null
177+
else
178+
pip install --upgrade $LIBRARY_NAME
179+
fi
180+
if [ $? -eq 0 ]; then
181+
success "Done!\n"
182+
echo "pip uninstall $LIBRARY_NAME" >> $UNINSTALLER
183+
fi
184+
fi
14185
15-
if [ -f "/usr/bin/python3" ]; then
186+
if [ -f "$PYTHON3" ]; then
16187
printf "Installing for Python 3..\n"
17-
python3 setup.py install
188+
apt_pkg_install "${PY3_DEPS[@]}"
189+
if $UNSTABLE; then
190+
python3 setup.py install > /dev/null
191+
else
192+
pip3 install --upgrade $LIBRARY_NAME
193+
fi
194+
if [ $? -eq 0 ]; then
195+
success "Done!\n"
196+
echo "pip3 uninstall $LIBRARY_NAME" >> $UNINSTALLER
197+
fi
198+
else
199+
if $PY3_ONLY; then
200+
warning "Python 3 is required to install this library...\n"
201+
exit 1
202+
fi
18203
fi
19204
20-
cd ..
205+
cd $WD
206+
207+
for ((i = 0; i < ${#SETUP_CMDS[@]}; i++)); do
208+
CMD="${SETUP_CMDS[$i]}"
209+
# Attempt to catch anything that touches /boot/config.txt and trigger a backup
210+
if [[ "$CMD" == *"raspi-config"* ]] || [[ "$CMD" == *"$CONFIG"* ]] || [[ "$CMD" == *"\$CONFIG"* ]]; then
211+
do_config_backup
212+
fi
213+
eval $CMD
214+
done
215+
216+
for ((i = 0; i < ${#CONFIG_TXT[@]}; i++)); do
217+
CONFIG_LINE="${CONFIG_TXT[$i]}"
218+
if ! [ "$CONFIG_LINE" == "" ]; then
219+
do_config_backup
220+
inform "Adding $CONFIG_LINE to $CONFIG\n"
221+
sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG
222+
if ! grep -q "^$CONFIG_LINE" $CONFIG; then
223+
printf "$CONFIG_LINE\n" >> $CONFIG
224+
fi
225+
fi
226+
done
227+
228+
if [ -d "examples" ]; then
229+
if confirm "Would you like to copy examples to $RESOURCES_DIR?"; then
230+
inform "Copying examples to $RESOURCES_DIR"
231+
cp -r examples/ $RESOURCES_DIR
232+
echo "rm -r $RESOURCES_DIR" >> $UNINSTALLER
233+
success "Done!"
234+
fi
235+
fi
236+
237+
printf "\n"
238+
239+
if [ -f "/usr/bin/pydoc" ]; then
240+
printf "Generating documentation.\n"
241+
pydoc -w $LIBRARY_NAME > /dev/null
242+
if [ -f "$LIBRARY_NAME.html" ]; then
243+
cp $LIBRARY_NAME.html $RESOURCES_DIR/docs.html
244+
rm -f $LIBRARY_NAME.html
245+
inform "Documentation saved to $RESOURCES_DIR/docs.html"
246+
success "Done!"
247+
else
248+
warning "Error: Failed to generate documentation."
249+
fi
250+
fi
21251
22-
printf "Done!\n"
252+
success "\nAll done!"
253+
inform "If this is your first time installing you should reboot for hardware changes to take effect.\n"
254+
inform "Find uninstall steps in $UNINSTALLER\n"

library/MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
include CHANGELOG.txt
22
include LICENSE.txt
3-
include README.rst
3+
include README.md
44
include setup.py
55
recursive-include bme680 *.py

0 commit comments

Comments
 (0)