pupu-git

LOW
maintainer zxp19821005 0 votes scanned 2026-11-02 00:26:00.633185
View on AUR
Why flagged

The pip install is part of building the project's own dependencies in a local venv from requirements.txt and pyinstaller, which is normal for packaging and not an external untrusted install.

Triggered rules

Low AI review downgraded a static finding llm_review

The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-2507) reviewed the full PKGBUILD and judged it LOW (confidence 95%): The pip install is part of building the project's own dependencies in a local venv from requirements.txt and pyinstaller, which is normal for packaging and not an external untrusted install.

1 higher static finding superseded - not the current verdict (shown for transparency)
Medium pip install of an external package pip_install_external

`pip install <package>` fetches an unpinned package from PyPI at build time, outside source=() and makepkg's checksums.

  • PKGBUILD:150 "${VENV_PY}" -m pip install --disable-pip-version-check --retries 5 --timeout 60 --upgrade pip
  • PKGBUILD:151 "${VENV_PY}" -m pip install --disable-pip-version-check --retries 5 --timeout 60 \

PKGBUILD

2 offending line(s) highlighted
1# Maintainer: zxp19821005 <zxp19821005 at 163 dot com>
2pkgname=pupu-git
3_pkgname=PuPu
4pkgver=0.1.13.r1.g8b4097c
5_electronversion=40
6_nodeversion=24
7pkgrel=1
8pkgdesc="A simple and easy to use UI for the Ollama."
9arch=('any')
10url="https://github.com/haoxiang-xu/PuPu"
11license=('MIT')
12provides=("${pkgname%-git}=${pkgver%.r*}")
13conflicts=("${pkgname%-git}")
14depends=(
15 "electron${_electronversion}"
16 'uv'
17 'nodejs'
18 'python-urllib3'
19 'python-typing_extensions'
20 'python-legacy-cgi'
21 'python-packaging'
22 'python-attrs'
23 'python-filelock'
24 'python-keyring'
25 'python-pip'
26 'python-cryptography'
27 'libxcrypt-compat'
28 'python-requests'
29)
30makedepends=(
31 'npm'
32 'nvm'
33 'git'
34 'gendesk'
35 'jq'
36 'python312'
37)
38source=(
39 "${pkgname//-/.}::git+${url}.git"
40 "unchain::git+https://github.com/haoxiang-xu/unchain.git"
41 "${pkgname%-git}.js"
42 "${pkgname%-git}.sh"
43)
44sha256sums=('SKIP'
45 'SKIP'
46 '562897be8a17076176f8d985c0d7bc1c685f2e7c9b3a932339ce015963243627'
47 '0f4675ddc96a032accf82723c7b6b66007bafd18aa8d919b61e983a68fd25328')
48_get_project_dir() {
49 local d
50 while IFS= read -r d; do
51 find "$d" -name "package.json" ! -path "*/node_modules/*" 2>/dev/null | grep -q . && { echo "$d"; return; }
52 done < <(find "${srcdir}" -maxdepth 1 -mindepth 1 -type d ! -name '.*')
53}
54pkgver() {
55 cd "$(_get_project_dir)"
56 set -o pipefail
57 git describe --long --tags --abbrev=7 | sed 's/\([^-]*-g\)/r\1/;s/-/./g;s/v//g' ||
58 printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)"
59}
60_ensure_local_nvm() {
61 local NVM_DIR="${srcdir}/.nvm"
62 source /usr/share/nvm/init-nvm.sh || [[ $? != 1 ]]
63 nvm install "${_nodeversion}"
64 nvm use "${_nodeversion}"
65}
66_get_app_dir() {
67 find "${srcdir}" -type f -name "resources.pak" ! -path "*/node_modules/*" -printf '%h\n' 2>/dev/null \
68 | while read -r d; do [[ -d "${d}/resources" ]] && { echo "$d"; return 0; }; done
69}
70_get_electron_version() {
71 _elec_ver=$(find "$(_get_project_dir)" -name "package.json" ! -path "*/node_modules/*" -print \
72 | xargs -I{} jq -r '(.devDependencies.electron // .dependencies.electron) // empty' {} 2>/dev/null \
73 | grep -oE '[0-9]+' | head -1)
74 [[ -z "${_elec_ver}" ]] && return 1
75 (( _elec_ver == _electronversion )) && c=32 || c=31
76 echo -e "Electron version: \033[1;${c}m${_elec_ver}$([[ $c -eq 31 ]] && echo " (expected ${_electronversion})")\033[0m"
77}
78_set_npm_build_env() {
79 export ELECTRON_DIST="/usr/lib/electron${_electronversion}"
80 export ELECTRON_OVERRIDE_DIST_PATH="${ELECTRON_DIST}"
81 export ELECTRON_SKIP_BINARY_DOWNLOAD=1
82 export ELECTRON_BUILDER_OFFLINE=true
83 export SYSTEM_ELECTRON_VERSION="$(electron${_electronversion} -v | sed 's/^v//')"
84 export HOME="${srcdir}/.home"
85 export XDG_CACHE_HOME="${HOME}/.cache"
86 export XDG_CONFIG_HOME="${HOME}/.config"
87 export XDG_DATA_HOME="${HOME}/.local/share"
88 export npm_config_cache="${HOME}/.npm_cache"
89 export COREPACK_NPM_REGISTRY="${COREPACK_NPM_REGISTRY:-${NPM_CONFIG_REGISTRY:-https://registry.npmjs.org}}"
90 export COREPACK_HOME="${HOME}/.corepack"
91 export npm_config_audit=false
92 export npm_config_registry="${NPM_CONFIG_REGISTRY:-${npm_config_registry:-https://registry.npmjs.org}}"
93 mkdir -p "${HOME}" "${npm_config_cache}" "${COREPACK_HOME}"
94}
95_set_python_pip_build_env() {
96 export HOME="${srcdir}/.home"
97 export XDG_CACHE_HOME="${HOME}/.cache"
98 export XDG_CONFIG_HOME="${HOME}/.config"
99 export XDG_DATA_HOME="${HOME}/.local/share"
100 export XDG_STATE_HOME="${HOME}/.local/state"
101 export PIP_CONFIG_FILE="${HOME}/.pip/pip.conf"
102 export PIP_CACHE_DIR="${HOME}/.pip/cache"
103 export PIP_DISABLE_PIP_VERSION_CHECK=1
104 export PIP_NO_INPUT=1
105 export PIP_NO_COLOR=1
106 export PIP_USER=0
107 export PIP_ROOT_USER_ACTION=ignore
108 export PYTHONDONTWRITEBYTECODE=1
109 export PYTHONNOUSERSITE=1
110 export PYTHONHASHSEED=0
111 mkdir -p "${HOME}" "${srcdir}/.pip" "${PIP_CACHE_DIR}"
112 : > "${HOME}/.pip/pip.conf"
113}
114prepare() {
115 cd "$(_get_project_dir)"
116 _get_electron_version
117 sed -i -e "
118 s/@electronversion@/${_electronversion}/g
119 s/@appname@/${pkgname%-git}/g
120 " "${srcdir}/${pkgname%-git}.sh" "${srcdir}/${pkgname%-git}.js"
121 gendesk -q -f -n \
122 --pkgname="${pkgname%-git}" \
123 --pkgdesc="${pkgdesc}" \
124 --categories="Utility" \
125 --name="${_pkgname}" \
126 --exec="${pkgname%-git} %U"
127 _ensure_local_nvm
128 _set_npm_build_env
129 _set_python_pip_build_env
130 sed -i "s/sys.version_info\[:2\] == (3, 12)/sys.version_info[0] == 3 and sys.version_info[1] >= 12/g" unchain_runtime/scripts/build_unchain_server.sh
131 sed -i "s/sys.version_info\[:2\] == (3, 12)/sys.version_info[0] == 3 and sys.version_info[1] >= 12/g" scripts/init_python312_venv.sh
132 jq --arg ver "${SYSTEM_ELECTRON_VERSION}" '.devDependencies.electron = $ver' package.json > package.json.tmp && mv package.json.tmp package.json
133 # Skip macOS-specific postinstall script on Linux
134 sed -i 's|"postinstall": "node scripts/release-qa/patch-macos-keychain.cjs"|"postinstall": "echo Skipping macOS-specific patches on Linux"|' package.json
135 # Fix broken progress package (lib directory is empty)
136 sed -i 's/"overrides": {/"overrides": {\n "progress": "2.0.3",/' package.json
137 export NODE_ENV=development
138 npm install --legacy-peer-deps
139}
140build() {
141 cd "$(_get_project_dir)"
142 _ensure_local_nvm
143 _set_npm_build_env
144 _set_python_pip_build_env
145 export PUPU_BUILD_VERSION="$(node -p "require('./package.json').version")"
146 export UNCHAIN_ARTIFACT_SOURCE_PATH="${srcdir}/unchain"
147 rm -rf "$(_get_project_dir)/.venv"
148 python3.12 -m venv "$(_get_project_dir)/.venv"
149 VENV_PY="$(_get_project_dir)/.venv/bin/python"
150 "${VENV_PY}" -m pip install --disable-pip-version-check --retries 5 --timeout 60 --upgrade pip
151 "${VENV_PY}" -m pip install --disable-pip-version-check --retries 5 --timeout 60 \
152 -r unchain_runtime/server/requirements.txt "pyinstaller==6.22.1"
153 export UNCHAIN_BUILD_VENV="$(_get_project_dir)/.venv"
154 export NODE_ENV=production
155 npm run build:unchain:linux
156 npm run build:web
157 npm exec -c "electron-builder --linux dir -c.electronDist=${ELECTRON_DIST}"
158}
159
160package() {
161 install -Dm755 "${srcdir}/${pkgname%-git}.sh" "${pkgdir}/usr/bin/${pkgname%-git}"
162 install -Dm644 "${srcdir}/${pkgname%-git}.js" -t "${pkgdir}/usr/lib/${pkgname%-git}"
163 cp -a "$(_get_app_dir)/resources/." "${pkgdir}/usr/lib/${pkgname%-git}/"
164 _icon_sizes=(192 512)
165 for _icons in "${_icon_sizes[@]}";do
166 install -Dm644 "$(_get_project_dir)/public/logo${_icons}.png" \
167 "${pkgdir}/usr/share/icons/hicolor/${_icons}x${_icons}/apps/${pkgname%-git}.png"
168 done
169 install -Dm644 "$(_get_project_dir)/${pkgname%-git}.desktop" -t "${pkgdir}/usr/share/applications"
170 install -Dm644 "$(_get_project_dir)/LICENSE" -t "${pkgdir}/usr/share/licenses/${pkgname}"
171}
172

Changes since previous scan

--- PKGBUILD @ 2026-10-29 00:13
+++ PKGBUILD @ 2026-11-02 00:26
@@ -1,9 +1,9 @@
# Maintainer: zxp19821005 <zxp19821005 at 163 dot com>
pkgname=pupu-git
_pkgname=PuPu
-pkgver=0.1.11.tools.5.r35.g216b0bf
+pkgver=0.1.13.r1.g8b4097c
_electronversion=40
-_nodeversion=22
+_nodeversion=24
pkgrel=1
pkgdesc="A simple and easy to use UI for the Ollama."
arch=('any')
@@ -13,8 +13,8 @@
conflicts=("${pkgname%-git}")
depends=(
"electron${_electronversion}"
+ 'uv'
'nodejs'
- 'uv'
'python-urllib3'
'python-typing_extensions'
'python-legacy-cgi'
@@ -31,63 +31,93 @@
'npm'
'nvm'
'git'
- 'curl'
'gendesk'
'jq'
+ 'python312'
)
source=(
"${pkgname//-/.}::git+${url}.git"
"unchain::git+https://github.com/haoxiang-xu/unchain.git"
+ "${pkgname%-git}.js"
"${pkgname%-git}.sh"
)
sha256sums=('SKIP'
'SKIP'
- 'a774c2f54fbbeeaac3cefc0f7250796d30c86d27f0fd40b7eaf9c0fdb021623d')
+ '562897be8a17076176f8d985c0d7bc1c685f2e7c9b3a932339ce015963243627'
+ '0f4675ddc96a032accf82723c7b6b66007bafd18aa8d919b61e983a68fd25328')
+_get_project_dir() {
+ local d
+ while IFS= read -r d; do
+ find "$d" -name "package.json" ! -path "*/node_modules/*" 2>/dev/null | grep -q . && { echo "$d"; return; }
+ done < <(find "${srcdir}" -maxdepth 1 -mindepth 1 -type d ! -name '.*')
+}
pkgver() {
- cd "${srcdir}/${pkgname//-/.}"
- set -o pipefail
- git describe --long --tags --abbrev=7 | sed 's/\([^-]*-g\)/r\1/;s/-/./g;s/v//g' ||
- printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)"
+ cd "$(_get_project_dir)"
+ set -o pipefail
+ git describe --long --tags --abbrev=7 | sed 's/\([^-]*-g\)/r\1/;s/-/./g;s/v//g' ||
+ printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)"
}
_ensure_local_nvm() {
- local NVM_DIR="${srcdir}/.nvm"
- source /usr/share/nvm/init-nvm.sh || [[ $? != 1 ]]
- nvm install "${_nodeversion}"
- nvm use "${_nodeversion}"
+ local NVM_DIR="${srcdir}/.nvm"
+ source /usr/share/nvm/init-nvm.sh || [[ $? != 1 ]]
+ nvm install "${_nodeversion}"
+ nvm use "${_nodeversion}"
}
-_set_build_env() {
+_get_app_dir() {
+ find "${srcdir}" -type f -name "resources.pak" ! -path "*/node_modules/*" -printf '%h\n' 2>/dev/null \
+ | while read -r d; do [[ -d "${d}/resources" ]] && { echo "$d"; return 0; }; done
+}
+_get_electron_version() {
+ _elec_ver=$(find "$(_get_project_dir)" -name "package.json" ! -path "*/node_modules/*" -print \
+ | xargs -I{} jq -r '(.devDependencies.electron // .dependencies.electron) // empty' {} 2>/dev/null \
+ | grep -oE '[0-9]+' | head -1)
+ [[ -z "${_elec_ver}" ]] && return 1
+ (( _elec_ver == _electronversion )) && c=32 || c=31
+ echo -e "Electron version: \033[1;${c}m${_elec_ver}$([[ $c -eq 31 ]] && echo " (expected ${_electronversion})")\033[0m"
+}
+_set_npm_build_env() {
export ELECTRON_DIST="/usr/lib/electron${_electronversion}"
export ELECTRON_OVERRIDE_DIST_PATH="${ELECTRON_DIST}"
export ELECTRON_SKIP_BINARY_DOWNLOAD=1
+ export ELECTRON_BUILDER_OFFLINE=true
export SYSTEM_ELECTRON_VERSION="$(electron${_electronversion} -v | sed 's/^v//')"
- export HOME="${srcdir}/.electron-gyp"
- export XDG_CACHE_HOME="${srcdir}/.cache"
- export XDG_CONFIG_HOME="${srcdir}/.config"
- export XDG_DATA_HOME="${srcdir}/.local/share"
- export npm_config_cache="${srcdir}/.npm_cache"
+ export HOME="${srcdir}/.home"
+ export XDG_CACHE_HOME="${HOME}/.cache"
+ export XDG_CONFIG_HOME="${HOME}/.config"
+ export XDG_DATA_HOME="${HOME}/.local/share"
+ export npm_config_cache="${HOME}/.npm_cache"
export COREPACK_NPM_REGISTRY="${COREPACK_NPM_REGISTRY:-${NPM_CONFIG_REGISTRY:-https://registry.npmjs.org}}"
- export COREPACK_HOME="${srcdir}/.corepack"
+ export COREPACK_HOME="${HOME}/.corepack"
export npm_config_audit=false
+ export npm_config_registry="${NPM_CONFIG_REGISTRY:-${npm_config_registry:-https://registry.npmjs.org}}"
mkdir -p "${HOME}" "${npm_config_cache}" "${COREPACK_HOME}"
}
-_get_app_dir() {
- find "${srcdir}" -type d -name "node_modules" -prune -o -type f -name "resources.pak" -print0 | xargs -0 dirname | head -n 1
-}
-_get_electron_version() {
- _elec_ver=$(find "${srcdir}" -maxdepth 5 -name "package.json" ! -path "*/node_modules/*" \
- -exec grep -l '"electron"' {} + | xargs -I{} jq -r '(.devDependencies.electron // .dependencies.electron) // empty' {} 2>/dev/null | head -1)
- [[ -z "${_elec_ver}" ]] && return 1
- echo -e "The electron version is: \033[1;31m${_elec_ver%%.*}\033[0m"
+_set_python_pip_build_env() {
+ export HOME="${srcdir}/.home"
+ export XDG_CACHE_HOME="${HOME}/.cache"
+ export XDG_CONFIG_HOME="${HOME}/.config"
+ export XDG_DATA_HOME="${HOME}/.local/share"
+ export XDG_STATE_HOME="${HOME}/.local/state"
+ export PIP_CONFIG_FILE="${HOME}/.pip/pip.conf"
+ export PIP_CACHE_DIR="${HOME}/.pip/cache"
+ export PIP_DISABLE_PIP_VERSION_CHECK=1
+ export PIP_NO_INPUT=1
+ export PIP_NO_COLOR=1
+ export PIP_USER=0
+ export PIP_ROOT_USER_ACTION=ignore
+ export PYTHONDONTWRITEBYTECODE=1
+ export PYTHONNOUSERSITE=1
+ export PYTHONHASHSEED=0
+ mkdir -p "${HOME}" "${srcdir}/.pip" "${PIP_CACHE_DIR}"
+ : > "${HOME}/.pip/pip.conf"
}
prepare() {
- cd "${srcdir}/${pkgname//-/.}"
+ cd "$(_get_project_dir)"
_get_electron_version
- sed -e "
+ sed -i -e "
s/@electronversion@/${_electronversion}/g
s/@appname@/${pkgname%-git}/g
- s/@runname@/app.asar/g
- s/@cfgdirname@/${pkgname%-git}/g
- " -i "${srcdir}/${pkgname%-git}.sh"
+ " "${srcdir}/${pkgname%-git}.sh" "${srcdir}/${pkgname%-git}.js"
gendesk -q -f -n \
--pkgname="${pkgname%-git}" \
--pkgdesc="${pkgdesc}" \
@@ -95,44 +125,48 @@
--name="${_pkgname}" \
--exec="${pkgname%-git} %U"
_ensure_local_nvm
- _set_build_env
+ _set_npm_build_env
+ _set_python_pip_build_env
sed -i "s/sys.version_info\[:2\] == (3, 12)/sys.version_info[0] == 3 and sys.version_info[1] >= 12/g" unchain_runtime/scripts/build_unchain_server.sh
sed -i "s/sys.version_info\[:2\] == (3, 12)/sys.version_info[0] == 3 and sys.version_info[1] >= 12/g" scripts/init_python312_venv.sh
- find src -type f -exec sed -i "s/process.resourcesPath/\'\/usr\/lib\/${pkgname%-git}\'/g" {} +
- sed -i "s/\"electron\": \"[^\"]*\"/\"electron\": \"${SYSTEM_ELECTRON_VERSION}\"/g" package.json
+ jq --arg ver "${SYSTEM_ELECTRON_VERSION}" '.devDependencies.electron = $ver' package.json > package.json.tmp && mv package.json.tmp package.json
+ # Skip macOS-specific postinstall script on Linux
+ sed -i 's|"postinstall": "node scripts/release-qa/patch-macos-keychain.cjs"|"postinstall": "echo Skipping macOS-specific patches on Linux"|' package.json
# Fix broken progress package (lib directory is empty)
sed -i 's/"overrides": {/"overrides": {\n "progress": "2.0.3",/' package.json
- NODE_ENV=development npm install --legacy-peer-deps
+ export NODE_ENV=development
+ npm install --legacy-peer-deps
}
build() {
- cd "${srcdir}/${pkgname//-/.}"
+ cd "$(_get_project_dir)"
_ensure_local_nvm
- _set_build_env
+ _set_npm_build_env
+ _set_python_pip_build_env
export PUPU_BUILD_VERSION="$(node -p "require('./package.json').version")"
- export UNCHAIN_SOURCE_PATH="${srcdir}/unchain"
- rm -rf "${srcdir}/.venv"
- python3.12 -m venv "${srcdir}/.venv"
- source "${srcdir}/.venv/bin/activate"
- python -m pip install --upgrade pip
- python -m pip install -r unchain_runtime/server/requirements.txt -e ../unchain pyinstaller
- export UNCHAIN_BUILD_VENV="${srcdir}/.venv"
- export UNCHAIN_BUILD_SKIP_INSTALL=1
- NODE_ENV=production npm run build:unchain:linux
- NODE_ENV=production npm run build:web
- NODE_ENV=production npm exec -c "electron-builder --linux dir -c.electronDist=${ELECTRON_DIST}"
+ export UNCHAIN_ARTIFACT_SOURCE_PATH="${srcdir}/unchain"
+ rm -rf "$(_get_project_dir)/.venv"
+ python3.12 -m venv "$(_get_project_dir)/.venv"
+ VENV_PY="$(_get_project_dir)/.venv/bin/python"
+ "${VENV_PY}" -m pip install --disable-pip-version-check --retries 5 --timeout 60 --upgrade pip
+ "${VENV_PY}" -m pip install --disable-pip-version-check --retries 5 --timeout 60 \
+ -r unchain_runtime/server/requirements.txt "pyinstaller==6.22.1"
+ export UNCHAIN_BUILD_VENV="$(_get_project_dir)/.venv"
+ export NODE_ENV=production
+ npm run build:unchain:linux
+ npm run build:web
+ npm exec -c "electron-builder --linux dir -c.electronDist=${ELECTRON_DIST}"
}
package() {
install -Dm755 "${srcdir}/${pkgname%-git}.sh" "${pkgdir}/usr/bin/${pkgname%-git}"
- install -Dm755 -d "${pkgdir}/usr/lib/${pkgname%-git}"
- local _app_dir=$(_get_app_dir)
- cp -a "${_app_dir}/resources/." "${pkgdir}/usr/lib/${pkgname%-git}/"
+ install -Dm644 "${srcdir}/${pkgname%-git}.js" -t "${pkgdir}/usr/lib/${pkgname%-git}"
+ cp -a "$(_get_app_dir)/resources/." "${pkgdir}/usr/lib/${pkgname%-git}/"
_icon_sizes=(192 512)
for _icons in "${_icon_sizes[@]}";do
- install -Dm644 "${srcdir}/${pkgname//-/.}/public/logo${_icons}.png" \
+ install -Dm644 "$(_get_project_dir)/public/logo${_icons}.png" \
"${pkgdir}/usr/share/icons/hicolor/${_icons}x${_icons}/apps/${pkgname%-git}.png"
done
- install -Dm644 "${srcdir}/${pkgname//-/.}/${pkgname%-git}.desktop" -t "${pkgdir}/usr/share/applications"
- install -Dm644 "${srcdir}/${pkgname//-/.}/LICENSE" -t "${pkgdir}/usr/share/licenses/${pkgname}"
+ install -Dm644 "$(_get_project_dir)/${pkgname%-git}.desktop" -t "${pkgdir}/usr/share/applications"
+ install -Dm644 "$(_get_project_dir)/LICENSE" -t "${pkgdir}/usr/share/licenses/${pkgname}"
}

Scan history

Scanned at (UTC)SeverityRules
2026-11-02 00:26:00 Low 2
2026-11-01 00:21:48 Low 2
2026-10-31 00:07:41 Low 2
2026-10-30 00:29:30 Low 2
2026-10-29 11:52:15 Medium 1
2026-10-29 00:13:55 Low 2
2026-10-28 00:06:54 Low 2
2026-10-27 00:23:28 Low 2
2026-10-26 00:12:40 Low 2
2026-10-25 00:20:48 Low 2
2026-10-24 00:14:55 Low 2
2026-10-23 00:02:19 Low 2
2026-10-22 00:13:10 Low 2
2026-10-21 00:12:50 Low 2
2026-10-20 00:10:31 Low 2
2026-10-19 00:03:55 Low 2
2026-10-18 00:06:55 Low 2
2026-10-17 00:21:55 Low 2
2026-10-16 00:12:47 Low 2
2026-10-15 00:28:05 Low 2

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion