Skip to content

Commit 0bd61e4

Browse files
committed
Update packaging script for Fedora #340
- Removed building funcparserlib - Changed BuildArch from noarch to x86_64 - Resolved dependencies issues Signed-off-by: Chin Yeung Li <[email protected]>
1 parent 5896e2b commit 0bd61e4

File tree

1 file changed

+104
-81
lines changed

1 file changed

+104
-81
lines changed

etc/scripts/build_rpm_docker.py

Lines changed: 104 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,25 @@
33
Use Docker container to build an RPM.
44
Using Docker approach to ensure a consistent and isolated build environment.
55
6-
Requirement: The `toml` Python package
6+
Requirement:
7+
- toml
8+
- Docker
9+
10+
To install the required Python packages, run:
711
812
pip install toml
913
14+
To install Docker, follow the instructions at:
15+
https://docs.docker.com/get-docker/
16+
1017
To run the script:
1118
1219
python build_rpm_docker.py
1320
1421
This script will generate the RPM package files and place them in the
1522
dist/rpmbuild/ directory.
1623
17-
Once the RPM package is generated, you can install it using:
24+
Once the RPM package is generated, one can install it using:
1825
1926
sudo rpm -i /path/to/<dejacode>.rpm
2027
OR
@@ -23,6 +30,10 @@
2330
sudo yum install /path/to/<dejacode>.rpm
2431
2532
Replace the above path with the actual path to the generated RPM file.
33+
34+
Run the binary directly
35+
36+
dejacode
2637
"""
2738

2839
import os
@@ -47,11 +58,10 @@ def build_rpm_with_docker():
4758
# Generate requirements for RPM - exclude packages installed from GitHub
4859
dependencies = project["dependencies"]
4960

50-
# Exclude packages that will be installed from GitHub URLs
51-
excluded_packages = {"django-rest-hooks", "django_notifications_patched"}
52-
5361
filtered_dependencies = [
54-
dep for dep in dependencies if not any(excluded in dep for excluded in excluded_packages)
62+
dep
63+
for dep in dependencies
64+
if "django-rest-hooks" not in dep and "django-notifications-patched" not in dep
5565
]
5666

5767
# Create a requirements.txt content for installation
@@ -69,14 +79,12 @@ def build_rpm_with_docker():
6979
"/bin/bash",
7080
"-c",
7181
f"""set -ex
72-
# Install All build dependencies including development tools
73-
dnf install -y rpm-build python3-devel python3-setuptools python3-wheel \
74-
python3-build python3-pip python3-virtualenv curl gcc openldap-devel
75-
76-
# Clean up build directories to prevent recursive copying
77-
rm -rf build
82+
# Install build dependencies
83+
dnf install -y rpm-build python3-devel python3-setuptools python3-wheel \\
84+
python3-build python3-pip python3-virtualenv curl gcc openldap-devel git
7885
79-
# Build the wheel
86+
# Clean up and build wheel
87+
rm -rf build dist
8088
python3 -m build --wheel
8189
8290
# Get the wheel file name
@@ -99,13 +107,13 @@ def build_rpm_with_docker():
99107
# Get the changelog date
100108
CHANGELOG_DATE=$(date '+%a %b %d %Y')
101109
102-
# Create source tarball with actual name
110+
# Create source tarball
103111
tar czf dist/rpmbuild/SOURCES/{rpm_name}-{rpm_version}.tar.gz \\
104112
--transform "s,^,/{rpm_name}-{rpm_version}/," \\
105113
-C /workspace \\
106114
--exclude build --exclude=.git --exclude=dist --exclude=*.pyc --exclude=__pycache__ .
107115
108-
# Generate spec file with virtualenv approach - using actual values instead of variables
116+
# Generate spec file
109117
cat > dist/rpmbuild/SPECS/{rpm_name}.spec << EOF
110118
Name: {rpm_name}
111119
Version: {rpm_version}
@@ -123,16 +131,38 @@ def build_rpm_with_docker():
123131
}
124132
Source0: {rpm_name}-{rpm_version}.tar.gz
125133
Source1: requirements.txt
134+
Source2: $WHEEL_FILENAME
135+
136+
BuildArch: x86_64
137+
BuildRequires: python3-devel python3-virtualenv gcc openldap-devel git
138+
139+
# Runtime dependencies
140+
Requires: git
141+
Requires: python3
142+
Requires: postgresql
143+
Requires: postgresql-devel
144+
Requires: openldap
145+
146+
# Disable automatic debug package generation and file checking
147+
%global debug_package %{{nil}}
148+
%global __check_files %{{nil}}
149+
%global _enable_debug_package 0
150+
151+
# Only disable python bytecompilation which breaks virtualenvs
152+
%global __brp_python_bytecompile %{{nil}}
153+
154+
# Keep shebang mangling disabled for virtualenv
155+
%global __os_install_post %(echo '%{{__os_install_post}}' | \
156+
sed -e 's!/usr/lib/rpm/redhat/brp-mangle-shebangs!!g')
157+
%global __brp_mangle_shebangs %{{nil}}
126158
127-
BuildArch: noarch
128-
BuildRequires: python3-devel python3-virtualenv gcc openldap-devel
129159
AutoReqProv: no
130160
131161
%description
132162
{
133163
project.get(
134164
"description",
135-
"Automate open source license compliance and ensure supply chain integrity",
165+
"Automate open source license complianceand ensure supply chain integrity",
136166
)
137167
}
138168
@@ -142,93 +172,81 @@ def build_rpm_with_docker():
142172
%build
143173
144174
%install
175+
rm -rf %{{buildroot}}
145176
# Create directories
146177
mkdir -p %{{buildroot}}/opt/%{{name}}/venv
147178
mkdir -p %{{buildroot}}/usr/bin
179+
mkdir -p %{{buildroot}}/opt/%{{name}}/src
148180
149181
# Create virtual environment in a temporary location first
150182
mkdir -p /tmp/venv_build
151-
python3 -m venv /tmp/venv_build
152-
153-
# Upgrade pip in the temporary virtual environment
154-
/tmp/venv_build/bin/pip install --upgrade pip
155-
156-
# funcparserlib Patch/Install
157-
cd /tmp
158-
curl -L -o funcparserlib-0.3.6.tar.gz https://files.pythonhosted.org/packages/source/f/funcparserlib/funcparserlib-0.3.6.tar.gz
159-
tar -xzf funcparserlib-0.3.6.tar.gz
160-
cd funcparserlib-0.3.6
161-
162-
# rewrite setup.py to remove the "use_2to3" as this is not suported in Python3
163-
cat > setup.py << 'SETUP_EOF'
164-
from setuptools import setup
165-
166-
setup(
167-
name='funcparserlib',
168-
version='0.3.6',
169-
packages=['funcparserlib', 'funcparserlib.tests'],
170-
author='Andrey Vlasovskikh',
171-
author_email='[email protected]',
172-
description='Recursive descent parsing library based on functional '
173-
'combinators',
174-
license='MIT',
175-
url='http://code.google.com/p/funcparserlib/',
176-
)
177-
SETUP_EOF
178-
179-
# Install the patched funcparserlib
180-
/tmp/venv_build/bin/pip install .
181-
182-
# Clean up
183-
cd /tmp
184-
rm -rf funcparserlib-0.3.6 funcparserlib-0.3.6.tar.gz
185-
186-
# Install all other dependencies including the main package
183+
python3 -m venv /tmp/venv_build --copies
184+
187185
cd %{{_sourcedir}}
188-
/tmp/venv_build/bin/pip install -r requirements.txt
186+
/tmp/venv_build/bin/python -m pip install --upgrade pip
187+
188+
# Install system dependencies for psycopg
189+
dnf install -y postgresql-devel
189190
190191
# Install non-PyPI dependencies
191-
/tmp/venv_build/bin/pip install \\
192+
/tmp/venv_build/bin/python -m pip install \\
192193
https://github.com/aboutcode-org/django-rest-hooks/releases/download/1.6.1/django_rest_hooks-1.6.1-py2.py3-none-any.whl
193-
194-
/tmp/venv_build/bin/pip install \\
194+
/tmp/venv_build/bin/python -m pip install \\
195195
https://github.com/dejacode/django-notifications-patched/archive/refs/tags/2.0.0.tar.gz
196196
197-
# Install the main package from the wheel
198-
/tmp/venv_build/bin/pip install --no-deps $WHEEL_FILENAME
197+
# Install the main package
198+
/tmp/venv_build/bin/python -m pip install -r requirements.txt
199+
200+
# Install psycopg2-binary for compatibility
201+
/tmp/venv_build/bin/python -m pip install psycopg2-binary
202+
203+
# Install dejacode wheel
204+
/tmp/venv_build/bin/python -m pip install %{{_sourcedir}}/$WHEEL_FILENAME
205+
206+
# Extract source code for tests
207+
cd %{{_sourcedir}}
208+
tar xzf {rpm_name}-{rpm_version}.tar.gz
209+
cp -r {rpm_name}-{rpm_version}/* %{{buildroot}}/opt/%{{name}}/src/
210+
211+
# Clean up temporary virtualenv
212+
find /tmp/venv_build -name "*.pyc" -delete
213+
find /tmp/venv_build -name "__pycache__" -type d -exec rm -rf {{}} + 2>/dev/null || true
199214
200215
# Copy the completed virtual environment to the final location
201216
cp -r /tmp/venv_build/* %{{buildroot}}/opt/%{{name}}/venv/
202217
203218
# Clean up temporary virtual environment
204219
rm -rf /tmp/venv_build
205220
206-
# Doing clean up to prevent the "Arch dependent binaries in noarch package" error.
207-
# Remove arch-dependent shared object files (*.so)
208-
find %{{buildroot}}/opt/%{{name}}/venv -name "*.so*" -type f -delete
221+
# Fix shebang
222+
for script in %{{buildroot}}/opt/%{{name}}/venv/bin/*; do
223+
if [ -f "\\$script" ] && head -1 "\\$script" | grep -q "^#!"; then
224+
# Use sed to safely replace only the first line
225+
sed -i '1s|.*|#!/opt/%{{name}}/venv/bin/python3|' "\\$script"
226+
fi
227+
done
228+
229+
# Remove ONLY pip and wheel binaries
230+
rm -f %{{buildroot}}/opt/%{{name}}/venv/bin/pip*
231+
rm -f %{{buildroot}}/opt/%{{name}}/venv/bin/wheel
209232
210-
# Remove any other potential binary files
211-
find %{{buildroot}}/opt/%{{name}}/venv -type f -exec file {{}} \\; | grep -i \
212-
"executable" | cut -d: -f1 | xargs -r rm -f
233+
# Ensure executables have proper permissions
234+
find %{{buildroot}}/opt/%{{name}}/venv/bin -type f -exec chmod 755 {{}} \\;
213235
214-
# Create wrapper script for dejacode command
236+
# Create wrapper script with PYTHONPATH for tests
215237
cat > %{{buildroot}}/usr/bin/dejacode << 'WRAPPER_EOF'
216238
#!/bin/sh
217-
export PYTHONPATH="/opt/{rpm_name}/venv/lib/python3.13/site-packages"
218-
exec /usr/bin/python3 -m dejacode "\\$@"
239+
export PYTHONPATH="/opt/%{{name}}/src:/opt/%{{name}}/venv/lib/python3.13/site-packages"
240+
cd "/opt/%{{name}}/src"
241+
/opt/%{{name}}/venv/bin/dejacode "\\$@"
219242
WRAPPER_EOF
220243
chmod 755 %{{buildroot}}/usr/bin/dejacode
221244
222-
# Clean up any remaining build artifacts
223-
find %{{buildroot}}/opt/%{{name}}/venv -name "*.pyc" -delete
224-
find %{{buildroot}}/opt/%{{name}}/venv -name "__pycache__" -type d \
225-
-exec rm -rf {{}} + 2>/dev/null || true
226-
find %{{buildroot}}/opt/%{{name}}/venv -path "*/pip/_vendor/distlib/*.tmp" \
227-
-delete 2>/dev/null || true
228-
229245
%files
246+
%defattr(-,root,root,-)
230247
%dir /opt/%{{name}}
231-
/opt/%{{name}}/venv
248+
/opt/%{{name}}/venv/
249+
/opt/%{{name}}/src/
232250
/usr/bin/dejacode
233251
234252
%changelog
@@ -240,8 +258,13 @@ def build_rpm_with_docker():
240258
}
241259
EOF
242260
243-
# Build the RPM
244-
cd dist/rpmbuild && rpmbuild --define "_topdir $(pwd)" -bb SPECS/{rpm_name}.spec
261+
# Build RPM with only specific BRP processing disabled
262+
cd dist/rpmbuild && rpmbuild \\
263+
--define "_topdir $(pwd)" \\
264+
--define "__check_files /bin/true" \\
265+
--define "__brp_python_bytecompile /bin/true" \\
266+
-bb SPECS/{rpm_name}.spec
267+
245268
246269
# Fix permissions for Windows host
247270
chmod -R u+rwX /workspace/dist/rpmbuild
@@ -251,11 +274,11 @@ def build_rpm_with_docker():
251274
try:
252275
subprocess.run(docker_cmd, check=True, shell=False) # noqa: S603
253276
# Verify the existence of the .rpm
254-
rpm_file = next(Path("dist/rpmbuild/RPMS/noarch").glob("*.rpm"), None)
277+
rpm_file = next(Path("dist/rpmbuild/RPMS/x86_64").glob("*.rpm"), None)
255278
if rpm_file:
256279
print(f"\nSuccess! RPM built: {rpm_file}")
257280
else:
258-
print("Error: RPM not found in dist/rpmbuild/RPMS/noarch/", file=sys.stderr)
281+
print("Error: RPM not found in dist/rpmbuild/RPMS/x86_64/", file=sys.stderr)
259282
sys.exit(1)
260283
except subprocess.CalledProcessError as e:
261284
print(f"Build failed: {e}", file=sys.stderr)

0 commit comments

Comments
 (0)