Skip to content

Commit 5fefe62

Browse files
committed
Package instead of single file
1 parent ce6eff2 commit 5fefe62

4 files changed

Lines changed: 167 additions & 5 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
99
subversion=1.14.1-3+deb11u2 && \
1010
rm -rf /var/lib/apt/lists/*
1111

12+
# Install ruby gem FPM for packaging
13+
RUN apt-get update && \
14+
apt-get install --no-install-recommends -y \
15+
ruby \
16+
ruby-dev \
17+
build-essential \
18+
rpm \
19+
git \
20+
curl \
21+
ca-certificates && \
22+
gem install --no-document fpm && \
23+
rm -rf /var/lib/apt/lists/*
24+
1225
WORKDIR /workspaces/dfetch
1326

1427
# Add a non-root user (dev)

.github/workflows/build.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ jobs:
3434
with:
3535
python-version: '3.13'
3636

37+
- name: Set up Ruby
38+
uses: ruby/setup-ruby@v1
39+
with:
40+
ruby-version: 3.2 # or any version you need
41+
42+
- name: Install fpm
43+
run: gem install --no-document fpm && fpm --version
44+
3745
- name: ccache
3846
uses: hendrikmuhs/ccache-action@5ebbd400eff9e74630f759d94ddd7b6c26299639 # v1.2
3947
if: ${{ matrix.platform != 'windows-latest' }}
@@ -59,6 +67,7 @@ jobs:
5967
run: |
6068
pip install .[build]
6169
python script/build.py
70+
python script/package.py
6271
6372
- name: Store the distribution packages
6473
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
@@ -85,27 +94,27 @@ jobs:
8594
- name: Prepare binary
8695
if: matrix.platform == 'ubuntu-latest'
8796
run: |
97+
ls -la .
8898
binary=$(ls dfetch-*-x86_64)
8999
ln -sf "$binary" dfetch
90100
chmod +x dfetch
91-
ls -la .
92101
shell: bash
93102

94103
- name: Prepare binary
95104
if: matrix.platform == 'macos-latest'
96105
run: |
106+
ls -la .
97107
binary=$(ls dfetch-*-osx)
98108
ln -sf "$binary" dfetch
99109
chmod +x dfetch
100-
ls -la .
101110
shell: bash
102111

103112
- name: Prepare binary on Windows
104113
if: matrix.platform == 'windows-latest'
105114
run: |
115+
Get-ChildItem
106116
$binary = Get-ChildItem dfetch-*.exe | Select-Object -First 1
107117
Copy-Item $binary -Destination dfetch.exe -Force
108-
Get-ChildItem
109118
shell: pwsh
110119

111120
- run: ./dfetch init

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ reportMissingModuleSource = false
190190
pythonVersion = "3.9"
191191

192192
[tool.nuitka]
193-
mode = "onefile" # Switch this between standalone and onefile as needed
194-
# jobs = "4" # Can be used to reduce memory usage, in case of compilation issues
193+
mode = "standalone" # Switch this between standalone and onefile as needed
194+
jobs = "2" # Can be used to reduce memory usage, in case of compilation issues
195195
# Enable below for debugging
196196
# show-progress = true
197197
assume-yes-for-downloads = true

script/package.py

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env python3
2+
"""This script packages the dfetch build directory into OS-specific installers using fpm."""
3+
import subprocess
4+
import sys
5+
from pathlib import Path
6+
7+
from dfetch import __version__
8+
9+
# Configuration
10+
BUILD_DIR = Path("build", "dfetch.dist")
11+
OUTPUT_DIR = Path("build", "dfetch-package")
12+
PACKAGE_NAME = "dfetch"
13+
INSTALL_PREFIX = "/opt/dfetch" # Where the files will be installed on Linux/macOS
14+
MAINTAINER = "DFetch Team <dfetch@spoor.cc>"
15+
DESCRIPTION = (
16+
"DFetch: A vendoring tool for fetching and managing external dependencies."
17+
)
18+
URL = "https://github.com/dfetch-org/dfetch"
19+
LICENSE = "MIT"
20+
21+
22+
def run_command(command):
23+
"""Run a system command and handle errors."""
24+
print("Running:", " ".join(command))
25+
subprocess.check_call(command)
26+
27+
28+
def package_linux() -> None:
29+
"""Package the build directory into .deb and .rpm installers."""
30+
for target in ("deb", "rpm"):
31+
output = f"{OUTPUT_DIR}/{PACKAGE_NAME}_{__version__}.{target}"
32+
cmd = [
33+
"fpm",
34+
"-s",
35+
"dir",
36+
"-t",
37+
target,
38+
"-n",
39+
PACKAGE_NAME,
40+
"-v",
41+
__version__,
42+
"-C",
43+
str(BUILD_DIR),
44+
"--prefix",
45+
INSTALL_PREFIX,
46+
"--description",
47+
DESCRIPTION,
48+
"--maintainer",
49+
MAINTAINER,
50+
"--url",
51+
URL,
52+
"--license",
53+
LICENSE,
54+
"-p",
55+
output,
56+
".",
57+
]
58+
run_command(cmd)
59+
60+
61+
def package_macos() -> None:
62+
"""Package the build directory into a .pkg installer for macOS."""
63+
cmd = [
64+
"fpm",
65+
"-s",
66+
"dir",
67+
"-t",
68+
"osxpkg",
69+
"-n",
70+
PACKAGE_NAME,
71+
"-v",
72+
__version__,
73+
"-C",
74+
str(BUILD_DIR),
75+
"--prefix",
76+
INSTALL_PREFIX,
77+
"--description",
78+
DESCRIPTION,
79+
"--maintainer",
80+
MAINTAINER,
81+
"--url",
82+
URL,
83+
"--license",
84+
LICENSE,
85+
"-p",
86+
f"{OUTPUT_DIR}/{PACKAGE_NAME}_{__version__}.pkg",
87+
".",
88+
]
89+
run_command(cmd)
90+
91+
92+
def package_windows() -> None:
93+
"""Package the build directory into a .msi installer for Windows."""
94+
cmd = [
95+
"fpm",
96+
"-s",
97+
"dir",
98+
"-t",
99+
"msi",
100+
"-n",
101+
PACKAGE_NAME,
102+
"-v",
103+
__version__,
104+
"-C",
105+
str(BUILD_DIR),
106+
"--description",
107+
DESCRIPTION,
108+
"--manufacturer",
109+
MAINTAINER,
110+
"--url",
111+
URL,
112+
"--license",
113+
LICENSE,
114+
"-p",
115+
f"{OUTPUT_DIR}/{PACKAGE_NAME}_{__version__}.msi",
116+
".",
117+
]
118+
run_command(cmd)
119+
120+
121+
def main() -> None:
122+
"""Main packaging function."""
123+
if not BUILD_DIR.exists():
124+
print(f"Error: Build directory {BUILD_DIR} does not exist. Run build.py first.")
125+
sys.exit(1)
126+
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
127+
128+
if sys.platform.startswith("linux"):
129+
package_linux()
130+
elif sys.platform.startswith("darwin"):
131+
package_macos()
132+
elif sys.platform.startswith("win"):
133+
package_windows()
134+
else:
135+
print(f"Unsupported platform: {sys.platform}")
136+
sys.exit(1)
137+
138+
139+
if __name__ == "__main__":
140+
main()

0 commit comments

Comments
 (0)