1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# Copyright 2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v3
EAPI=8
PYTHON_COMPAT=( python3_{13..14} )
inherit python-single-r1 desktop xdg-utils udev
DESCRIPTION="Visual scope for coffee roasters — record, analyze, and control roast profiles"
HOMEPAGE="https://github.com/artisan-roaster-scope/artisan https://artisan-scope.org/"
SRC_URI="https://github.com/artisan-roaster-scope/artisan/archive/refs/tags/v${PV}.tar.gz -> ${P}.tar.gz"
LICENSE="GPL-3"
SLOT="0"
KEYWORDS="~amd64"
# pip needs network for deps not in portage
RESTRICT="network-sandbox test"
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
# System-level dependencies (C libs, Qt6).
# Subslot operators (:=) on Qt6/xcb force artisan rebuild on subslot bumps,
# so the bundled PyQt6 venv is regenerated and doesn't strand preserved-libs.
RDEPEND="
${PYTHON_DEPS}
dev-libs/libusb:1
$(python_gen_cond_dep '
dev-python/contourpy[${PYTHON_USEDEP}]
dev-python/cycler[${PYTHON_USEDEP}]
dev-python/fonttools[${PYTHON_USEDEP}]
dev-python/kiwisolver[${PYTHON_USEDEP}]
')
dev-qt/qtbase:6=[gui,network,widgets]
dev-qt/qtdeclarative:6=
dev-qt/qtsvg:6=
dev-qt/qtwayland:6=
dev-qt/qtwebengine:6=
gnome-base/gnome-keyring
x11-libs/xcb-util:=
x11-libs/xcb-util-image:=
x11-libs/xcb-util-keysyms:=
x11-libs/xcb-util-renderutil:=
x11-libs/xcb-util-wm:=
x11-libs/xcb-util-cursor:=
"
DEPEND="${RDEPEND}"
BDEPEND="
${PYTHON_DEPS}
$(python_gen_cond_dep 'dev-python/pip[${PYTHON_USEDEP}]')
"
S="${WORKDIR}/${P}"
src_prepare() {
default
# Suppress the recurring donation dialog at startup.
sed -i -e '/QTimer\.singleShot.*self\.donate/d' \
src/artisanlib/main.py || die "failed to disable donation popup"
}
src_compile() {
# Build a venv and install all Python deps via pip
local venv="${S}/.venv"
"${PYTHON}" -m venv --system-site-packages "${venv}" || die "venv creation failed"
# Activate venv for pip installs
local pip="${venv}/bin/pip"
# Install Python dependencies from upstream requirements
# Filter out platform-specific markers for non-Linux and build-only tools
sed -e '/platform_system.*Windows/d' \
-e '/platform_system.*Darwin/d' \
-e "/sys_platform.*darwin/d" \
-e '/pyinstaller/d' \
-e '/^#/d' \
-e '/^$/d' \
src/requirements.txt > "${T}/requirements-linux.txt" || die
"${pip}" install -r "${T}/requirements-linux.txt" || die "pip install failed"
# Compile .qm translations if .ts files are newer (upstream ships .qm so this is optional)
if type -P lrelease >/dev/null 2>&1; then
local ts
for ts in src/translations/*.ts; do
local qm="${ts%.ts}.qm"
[[ "${ts}" -nt "${qm}" ]] && lrelease "${ts}" -qm "${qm}"
done
fi
}
src_install() {
local inst_dir="/usr/lib/${PN}"
# Install venv
insinto "${inst_dir}"
doins -r .venv
# Fix venv shebangs and permissions
fperms -R +x "${inst_dir}/.venv/bin/"
# Install application source — all Python packages needed at runtime
insinto "${inst_dir}/src"
doins -r src/artisanlib src/plus src/help src/proto src/uic
doins src/artisan.py src/conftest.py
fperms +x "${inst_dir}/src/artisan.py"
# Translations
insinto "${inst_dir}/src/translations"
doins src/translations/*.qm
# Data files: includes (fonts, templates, icons, machines, themes, wheels)
insinto "${inst_dir}/src"
doins -r src/includes src/icons src/Wheels
# MIME type XML files
local xml
for xml in src/artisan-*.xml; do
[[ -f "${xml}" ]] && doins "${xml}"
done
# Logging config
[[ -f src/includes/logging.yaml ]] && doins src/includes/logging.yaml
# Launcher script
dobin "${FILESDIR}/artisan"
# Desktop entry
domenu "${FILESDIR}/org.artisan_scope.artisan.desktop"
# Icon
doicon -s scalable src/artisan.svg
newicon -s 256 src/debian/usr/share/pixmaps/artisan.png artisan.png
# Udev rules for USB hardware (Aillio, Yoctopuce, Phidgets)
udev_dorules "${FILESDIR}/99-artisan.rules"
# Man page (from debian packaging)
doman src/debian/usr/share/man/man1/artisan.1
# License
dodoc LICENSE
}
pkg_postinst() {
xdg_desktop_database_update
xdg_icon_cache_update
udev_reload
elog "Artisan installed to /usr/lib/artisan/"
elog ""
elog "Run 'artisan' to start."
elog ""
elog "For USB device access (Aillio, Phidgets, Yoctopuce), ensure your user"
elog "is in the 'usb' group, or udev rules have been reloaded:"
elog " udevadm control --reload-rules && udevadm trigger"
}
pkg_postrm() {
xdg_desktop_database_update
xdg_icon_cache_update
}
|