crosspack 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +36 -0
- data/LICENSE +18 -0
- data/README.md +192 -0
- data/exe/crossbuild +76 -0
- data/exe/crosspack +119 -0
- data/lib/crossbuild/build_manifest.rb +374 -0
- data/lib/crossbuild/builder.rb +72 -0
- data/lib/crossbuild/distributor.rb +76 -0
- data/lib/crossbuild/matrix.rb +52 -0
- data/lib/crossbuild/platform.rb +40 -0
- data/lib/crossbuild/runner.rb +62 -0
- data/lib/crossbuild/version.rb +5 -0
- data/lib/crossbuild/version_scheme.rb +51 -0
- data/lib/crossbuild.rb +27 -0
- data/lib/crosspack/builders/app_dir.rb +88 -0
- data/lib/crosspack/builders/deb.rb +121 -0
- data/lib/crosspack/builders/pkgbuild.rb +64 -0
- data/lib/crosspack/builders/rpm.rb +149 -0
- data/lib/crosspack/builders/wix.rb +119 -0
- data/lib/crosspack/builds.rb +61 -0
- data/lib/crosspack/manifest.rb +237 -0
- data/lib/crosspack/matrix.rb +67 -0
- data/lib/crosspack/package_manifest.rb +219 -0
- data/lib/crosspack/packer.rb +223 -0
- data/lib/crosspack/resolver.rb +91 -0
- data/lib/crosspack/target.rb +93 -0
- data/lib/crosspack/version.rb +5 -0
- data/lib/crosspack.rb +38 -0
- metadata +78 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: cb2e2fb91b4f2215649e739ff6ec7128a11e06abe8d776f870d686261439a974
|
|
4
|
+
data.tar.gz: 3b17f1325d46d5147a0d87fee2d62ee2cb021f4a11c4ab16cf54a94562d843ad
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 19cfe0db0863bff0e3b69d39ccefd0066ae99a85586ae8cabe19951897f0852b70966cc39372740a9a7e779ad36c81827797094befe8e292c7f420d1a17a0578
|
|
7
|
+
data.tar.gz: 9b220eff4186f4f1f88875d0b802c0d7a76f1b5d394e0ec828706a2e56d71676f809c1726de82e39f950ad323056b73104c9022c9fa181f554830817748dd612
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2026-09-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Merged the `crossbuild` gem into `crosspack`: one gem, two commands.
|
|
12
|
+
`crossbuild build` runs `build.yaml` matrix steps on the host and fans
|
|
13
|
+
artifacts out into `builds/<family>[/<version>]/<arch>/`; `crosspack pack`
|
|
14
|
+
packages that tree as before.
|
|
15
|
+
- `build.yaml` manifest with schema validation, version schemes
|
|
16
|
+
(`calver` / `git-tag` / `env:VAR` / literal), `{{version}}`-style
|
|
17
|
+
placeholder expansion and `CROSSBUILD_*` environment facts.
|
|
18
|
+
- crossbuild CLI: `validate`, `matrix`, `version`, `build`, `targets`.
|
|
19
|
+
- Library API: `Crossbuild.build` plus public `BuildManifest`,
|
|
20
|
+
`VersionScheme`, `Runner`, `Distributor`, `Matrix`, `Builder`, `Platform`.
|
|
21
|
+
|
|
22
|
+
## [0.1.0] - 2026-09-08
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- `package.yaml` / `deps.yaml` manifests with embedded schema validation and
|
|
26
|
+
path-pointing error messages.
|
|
27
|
+
- Dependency resolution per distro family/version (`Resolver`), dependency ×
|
|
28
|
+
target matrix rendering (`Matrix`).
|
|
29
|
+
- Builders: deb (`dpkg-deb`), rpm (`rpmbuild`), PKGBUILD, WiX sources (`.wxs`),
|
|
30
|
+
macOS app bundle staging.
|
|
31
|
+
- CLI: `validate`, `resolve`, `matrix`, `pack`, `targets`.
|
|
32
|
+
- Library API: `Crosspack.pack` plus public `PackageManifest`, `Manifest`,
|
|
33
|
+
`Resolver`, `Matrix`, `Target`, `Builders::*`.
|
|
34
|
+
|
|
35
|
+
[0.2.0]: https://github.com/OrelSokolov/crosspack/releases/tag/v0.2.0
|
|
36
|
+
[0.1.0]: https://github.com/OrelSokolov/crosspack/releases/tag/v0.1.0
|
data/LICENSE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Copyright (c) 2026 Oleg Orlov
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and its source code are proprietary and confidential.
|
|
6
|
+
No part of this software may be copied, modified, distributed, sublicensed,
|
|
7
|
+
or sold without the prior written permission of the copyright holder.
|
|
8
|
+
|
|
9
|
+
This software is provided by the copyright holder "as is" and any express
|
|
10
|
+
or implied warranties, including, but not limited to, the implied warranties
|
|
11
|
+
of merchantability and fitness for a particular purpose are disclaimed.
|
|
12
|
+
In no event shall the copyright holder be liable for any direct, indirect,
|
|
13
|
+
incidental, special, exemplary, or consequential damages (including, but
|
|
14
|
+
not limited to, procurement of substitute goods or services; loss of use,
|
|
15
|
+
data, or profits; or business interruption) however caused and on any theory
|
|
16
|
+
of liability, whether in contract, strict liability, or tort (including
|
|
17
|
+
negligence or otherwise) arising in any way out of the use of this software,
|
|
18
|
+
even if advised of the possibility of such damage.
|
data/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# crosspack
|
|
2
|
+
|
|
3
|
+
Cross-platform build **and** pack toolchain for Wails-style desktop apps,
|
|
4
|
+
shipped as one gem with two cooperating commands:
|
|
5
|
+
|
|
6
|
+
- **`crossbuild`** — runs the build steps of a project from a small
|
|
7
|
+
`build.yaml` matrix and fans the produced artifacts out into the
|
|
8
|
+
per-target tree `builds/<family>[/<version>]/<arch>/`.
|
|
9
|
+
- **`crosspack`** — turns that compiled tree into native packages
|
|
10
|
+
(deb / rpm / PKGBUILD / WiX / app bundle) for any target
|
|
11
|
+
distro × version × arch, driven by two small manifests.
|
|
12
|
+
|
|
13
|
+
The two commands share the same target vocabulary (`Crosspack::Target`),
|
|
14
|
+
so the build tree and the pack tree never drift apart. Build and pack
|
|
15
|
+
stay cleanly separated: `crossbuild` never packages, `crosspack` never
|
|
16
|
+
compiles — feed the output of one straight into the other:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
crossbuild build # builds/ tree
|
|
20
|
+
crosspack pack --target debian-12 --version 2026.08.31-33837
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## crossbuild: build.yaml
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
name: myapp
|
|
27
|
+
version: calver # calver | git-tag | env:VAR | any literal string
|
|
28
|
+
output: builds # default builds; mirrors package.yaml `sources`
|
|
29
|
+
|
|
30
|
+
matrix:
|
|
31
|
+
- build: linux/amd64 # os/arch this entry builds on (arch may be "any")
|
|
32
|
+
env: # extra env for the steps of this entry
|
|
33
|
+
CGO_ENABLED: "1"
|
|
34
|
+
steps: # shell commands, run from the project root
|
|
35
|
+
- wails build -platform linux/amd64 -ldflags "-X myapp/internal/app.appVersion={{version}}"
|
|
36
|
+
- cargo build --release -p helper --locked
|
|
37
|
+
artifacts:
|
|
38
|
+
from: build/bin # what got built
|
|
39
|
+
include: [myapp, helper, "*.onnx", "*.so*"] # default: ["*"]
|
|
40
|
+
to: [ubuntu-22.04, ubuntu-24.04, debian-12, debian-13]
|
|
41
|
+
mode: symlink # symlink | copy, default symlink
|
|
42
|
+
|
|
43
|
+
- id: windows # defaults to the build platform string
|
|
44
|
+
build: windows/amd64
|
|
45
|
+
steps:
|
|
46
|
+
- wails build -platform windows/amd64 -ldflags "-X ...={{version}}"
|
|
47
|
+
artifacts:
|
|
48
|
+
from: build/bin
|
|
49
|
+
include: [myapp.exe]
|
|
50
|
+
to: [windows-11.0]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Placeholders `{{version}}`, `{{name}}`, `{{platform}}`, `{{os}}`, `{{arch}}`
|
|
54
|
+
and `{{id}}` are expanded by the gem itself (works the same under POSIX
|
|
55
|
+
shells and cmd.exe); the same facts are exported as `CROSSBUILD_VERSION`,
|
|
56
|
+
`CROSSBUILD_NAME`, ... environment variables. Steps may freely call existing
|
|
57
|
+
rake tasks (`rake build:prepare`) or helper scripts.
|
|
58
|
+
|
|
59
|
+
Artifacts land in the shared layout, e.g.:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
builds/ubuntu/24.04/amd64/myapp -> build/bin/myapp (symlink)
|
|
63
|
+
builds/windows/11.0/x86_64/myapp.exe
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Version schemes
|
|
67
|
+
|
|
68
|
+
| scheme | value |
|
|
69
|
+
|---------------|------------------------------------------------------------|
|
|
70
|
+
| `calver` | `YYYY.MM.DD-<secs since local midnight>`, e.g. `2026.08.31-33837` (default) |
|
|
71
|
+
| `git-tag` | latest `git describe --tags --abbrev=0`, fallback `0.0.0-dev` |
|
|
72
|
+
| `env:VAR` | taken from `VAR`; build fails loudly when unset |
|
|
73
|
+
| other string | used verbatim, e.g. `version: 1.2.3` |
|
|
74
|
+
|
|
75
|
+
### crossbuild CLI
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
crossbuild validate # build.yaml against the schema
|
|
79
|
+
crossbuild matrix # entries × host buildability table
|
|
80
|
+
crossbuild version # computed version
|
|
81
|
+
crossbuild build [--target linux/amd64] # all host-buildable entries, or one
|
|
82
|
+
crossbuild targets # what is in builds/ ready to pack
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`build` refuses invalid manifests with path-pointing errors, runs only the
|
|
86
|
+
entries whose `build:` platform matches the host, then distributes.
|
|
87
|
+
|
|
88
|
+
## crosspack: two manifests
|
|
89
|
+
|
|
90
|
+
**`package.yaml`** — what and how to pack:
|
|
91
|
+
|
|
92
|
+
```yaml
|
|
93
|
+
name: myapp
|
|
94
|
+
maintainer: Your Name <you@example.com>
|
|
95
|
+
summary: MyApp - cross-platform desktop application # optional
|
|
96
|
+
description: |-
|
|
97
|
+
MyApp - cross-platform desktop application.
|
|
98
|
+
Bundles helper binaries and model assets alongside the GUI...
|
|
99
|
+
license: Proprietary # optional, default Proprietary
|
|
100
|
+
section: utils # optional, deb only
|
|
101
|
+
|
|
102
|
+
sources: builds # compiled artifacts tree written by crossbuild:
|
|
103
|
+
# builds/<family>/<version>/<arch>/ — pack without
|
|
104
|
+
# a matching build directory fails honestly
|
|
105
|
+
prefix: usr/local # install prefix inside the package
|
|
106
|
+
lib_dir: lib/myapp # optional, default lib/<name>
|
|
107
|
+
|
|
108
|
+
payload: # files from sources -> <prefix>/<lib_dir>/
|
|
109
|
+
- myapp
|
|
110
|
+
- helper
|
|
111
|
+
- model.onnx
|
|
112
|
+
|
|
113
|
+
executables: [myapp, helper] # chmod 755, must be in payload
|
|
114
|
+
|
|
115
|
+
links: # symlinks relative to prefix
|
|
116
|
+
bin/myapp: ../lib/myapp/myapp
|
|
117
|
+
|
|
118
|
+
desktop: # optional, .desktop generated
|
|
119
|
+
name: MyApp
|
|
120
|
+
comment: Cross-platform desktop application
|
|
121
|
+
categories: Utility;Audio
|
|
122
|
+
|
|
123
|
+
icon: build/appicon.png # optional, -> <prefix>/share/pixmaps/<name>.png
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**`deps.yaml`** — canonical dependency names resolved to concrete packages
|
|
127
|
+
per distro family/version (see the file itself for the full schema):
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
webkit2gtk:
|
|
131
|
+
targets:
|
|
132
|
+
debian:
|
|
133
|
+
"12": [libwebkit2gtk-4.1-0, libwebkit2gtk-4.0-37] # deb: a | b
|
|
134
|
+
fedora: { "*": [webkit2gtk4.1] }
|
|
135
|
+
macos: system # OS component
|
|
136
|
+
windows: system # preinstalled (WebView2)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Both files are validated against embedded schemas with actionable,
|
|
140
|
+
path-pointing error messages; every builder refuses to run on an invalid
|
|
141
|
+
manifest.
|
|
142
|
+
|
|
143
|
+
## CLI
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
crosspack validate # both package.yaml and deps.yaml
|
|
147
|
+
crosspack resolve --target debian-12 # Depends line for the target
|
|
148
|
+
crosspack matrix # dependency x target table
|
|
149
|
+
crosspack pack --target debian-12 --version 2026.08.31-1234 [--root .]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`pack` picks the builder from the target and writes to
|
|
153
|
+
`crosspacks/<family>/<version>/<arch>/`:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
crosspacks/ubuntu/26.04/amd64/myapp_2026.08.31-1234_amd64.deb
|
|
157
|
+
crosspacks/fedora/41/x86_64/myapp-2026.08.31-1234.x86_64.rpm (needs rpmbuild)
|
|
158
|
+
crosspacks/arch/x86_64/PKGBUILD
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Library
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
require 'crosspack' # pulls in Crossbuild too
|
|
165
|
+
|
|
166
|
+
Crossbuild.build('build.yaml', root: Dir.pwd) # all host entries
|
|
167
|
+
Crossbuild.build('build.yaml', entry_id: 'windows') # one entry explicitly
|
|
168
|
+
|
|
169
|
+
Crosspack.pack(
|
|
170
|
+
manifest: 'package.yaml', deps: 'deps.yaml',
|
|
171
|
+
target: Crosspack::Target.parse('debian-12', arch: 'amd64'),
|
|
172
|
+
version: '2026.08.31-1234',
|
|
173
|
+
root: Dir.pwd, output_base: 'crosspacks'
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Lower-level pieces are public too: on the build side `Crossbuild::
|
|
178
|
+
BuildManifest`, `VersionScheme`, `Runner`, `Distributor`, `Matrix`,
|
|
179
|
+
`Builder`, `Platform`; on the pack side `Crosspack::PackageManifest`,
|
|
180
|
+
`Manifest`, `Resolver`, `Matrix`, `Target`, `Builders::*`.
|
|
181
|
+
|
|
182
|
+
Deb needs `dpkg-deb` (present on any Debian/Ubuntu), rpm needs
|
|
183
|
+
`rpmbuild` (`sudo apt install rpm`), PKGBUILD generation needs nothing.
|
|
184
|
+
The WiX builder generates `.wxs` sources (run the WiX Toolset yourself to
|
|
185
|
+
get an MSI), the macOS builder stages the `.app` bundle (signing, notarization
|
|
186
|
+
and .dmg creation are out of scope). Requires Ruby >= 3.2.
|
|
187
|
+
|
|
188
|
+
## Tests
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
cd crosspack && rake test
|
|
192
|
+
```
|
data/exe/crossbuild
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'optparse'
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require 'crossbuild'
|
|
8
|
+
rescue LoadError
|
|
9
|
+
require_relative '../lib/crossbuild'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def abort_with(message)
|
|
13
|
+
warn message
|
|
14
|
+
exit 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
options = { file: 'build.yaml', root: Dir.pwd, target: nil, version: nil, output_base: nil }
|
|
18
|
+
parser = OptionParser.new do |opts|
|
|
19
|
+
opts.banner = "crossbuild #{Crossbuild::VERSION} — cross-platform build orchestrator\n" \
|
|
20
|
+
"Usage: crossbuild <command> [options]\n" \
|
|
21
|
+
'Commands: validate, matrix, version, build, targets'
|
|
22
|
+
|
|
23
|
+
opts.on('-f', '--file PATH', 'path to build.yaml (default: ./build.yaml)') { |v| options[:file] = v }
|
|
24
|
+
opts.on('--target ID', 'matrix entry to build, e.g. linux/amd64 (default: every host-buildable entry)') { |v| options[:target] = v }
|
|
25
|
+
opts.on('--version VERSION', 'override the version scheme for build') { |v| options[:version] = v }
|
|
26
|
+
opts.on('--root PATH', 'project root for relative paths (default: .)') { |v| options[:root] = v }
|
|
27
|
+
opts.on('--output-base DIR', 'output directory (default: the manifest output, builds)') { |v| options[:output_base] = v }
|
|
28
|
+
opts.on('-h', '--help', 'show help') do
|
|
29
|
+
puts opts
|
|
30
|
+
exit
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
parser.parse!
|
|
34
|
+
|
|
35
|
+
command = ARGV.shift
|
|
36
|
+
abort_with 'No command given. See: crossbuild --help' if command.nil?
|
|
37
|
+
|
|
38
|
+
# Positional file path: crossbuild validate path/to/build.yaml
|
|
39
|
+
options[:file] = ARGV.shift if ARGV.first && !ARGV.first.start_with?('-')
|
|
40
|
+
|
|
41
|
+
file = File.expand_path(options[:file], options[:root])
|
|
42
|
+
begin
|
|
43
|
+
manifest = Crossbuild::BuildManifest.load(file)
|
|
44
|
+
rescue Crossbuild::InvalidManifestError => e
|
|
45
|
+
abort_with e.message
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
case command
|
|
49
|
+
when 'validate'
|
|
50
|
+
puts manifest.error_report
|
|
51
|
+
exit(manifest.valid? ? 0 : 1)
|
|
52
|
+
when 'matrix'
|
|
53
|
+
abort_with 'Schema is invalid — the matrix cannot be rendered. Run: crossbuild validate' unless manifest.valid?
|
|
54
|
+
puts Crossbuild::Matrix.new(manifest).render
|
|
55
|
+
when 'version'
|
|
56
|
+
abort_with 'Schema is invalid. Run: crossbuild validate' unless manifest.valid?
|
|
57
|
+
begin
|
|
58
|
+
puts Crossbuild::VersionScheme.new(manifest.version).compute(root: options[:root])
|
|
59
|
+
rescue Crossbuild::VersionScheme::Error => e
|
|
60
|
+
abort_with e.message
|
|
61
|
+
end
|
|
62
|
+
when 'build'
|
|
63
|
+
begin
|
|
64
|
+
result = Crossbuild::Builder.new(manifest, root: options[:root], output_base: options[:output_base],
|
|
65
|
+
version: options[:version]).run(entry_id: options[:target])
|
|
66
|
+
rescue Crossbuild::Error, Crosspack::InvalidManifestError => e
|
|
67
|
+
abort_with e.message
|
|
68
|
+
end
|
|
69
|
+
puts "\n📦 #{result.entries.size} entr#{result.entries.size == 1 ? 'y' : 'ies'} built, version #{result.version}"
|
|
70
|
+
puts 'Pack with: crosspack pack --target <target> --version ' + result.version
|
|
71
|
+
when 'targets'
|
|
72
|
+
base = options[:output_base] || manifest.output
|
|
73
|
+
puts Crosspack::Builds.report(File.expand_path(base, options[:root]))
|
|
74
|
+
else
|
|
75
|
+
abort_with "Unknown command #{command.inspect}. Available: validate, matrix, version, build, targets"
|
|
76
|
+
end
|
data/exe/crosspack
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'optparse'
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require 'crosspack'
|
|
8
|
+
rescue LoadError
|
|
9
|
+
require_relative '../lib/crosspack'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def abort_with(message)
|
|
13
|
+
warn message
|
|
14
|
+
exit 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
options = { file: 'deps.yaml', package: 'package.yaml', arch: 'amd64', format: nil,
|
|
18
|
+
version: nil, root: Dir.pwd, output_base: 'crosspacks' }
|
|
19
|
+
parser = OptionParser.new do |opts|
|
|
20
|
+
opts.banner = "crosspack #{Crosspack::VERSION} — native package packer (deb/rpm/PKGBUILD/MSI/app)\n" \
|
|
21
|
+
"Usage: crosspack <command> [options]\n" \
|
|
22
|
+
'Commands: validate, resolve, matrix, pack, targets'
|
|
23
|
+
|
|
24
|
+
opts.on('-f', '--file PATH', 'path to deps.yaml (default: ./deps.yaml)') { |v| options[:file] = v }
|
|
25
|
+
opts.on('--package PATH', 'path to package.yaml (default: ./package.yaml)') { |v| options[:package] = v }
|
|
26
|
+
opts.on('--target TARGET', 'target: debian-12, ubuntu-24.04, fedora-41, arch, macos, windows') { |v| options[:target] = v }
|
|
27
|
+
opts.on('--arch ARCH', 'architecture: amd64/x86_64, arm64/aarch64 (default: amd64)') { |v| options[:arch] = v }
|
|
28
|
+
opts.on('--format FORMAT', 'output format for resolve: deb, rpm, pkgbuild (default: derived from the target)') { |v| options[:format] = v.to_sym }
|
|
29
|
+
opts.on('--version VERSION', 'package version for pack (required for pack)') { |v| options[:version] = v }
|
|
30
|
+
opts.on('--root PATH', 'project root for relative paths (default: .)') { |v| options[:root] = v }
|
|
31
|
+
opts.on('--output-base DIR', 'output directory (default: ./crosspacks)') { |v| options[:output_base] = v }
|
|
32
|
+
opts.on('-h', '--help', 'show help') do
|
|
33
|
+
puts opts
|
|
34
|
+
exit
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
begin
|
|
38
|
+
parser.parse!
|
|
39
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
|
|
40
|
+
abort_with "#{e.message}\nSee: crosspack --help"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
command = ARGV.shift
|
|
44
|
+
abort_with 'No command given. See: crosspack --help' if command.nil?
|
|
45
|
+
|
|
46
|
+
# Positional file path: crosspack validate path/to/deps.yaml
|
|
47
|
+
options[:file] = ARGV.shift if ARGV.first && !ARGV.first.start_with?('-')
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
manifest = Crosspack::Manifest.load(options[:file])
|
|
51
|
+
rescue Crosspack::InvalidManifestError => e
|
|
52
|
+
abort_with e.message
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
case command
|
|
56
|
+
when 'validate'
|
|
57
|
+
begin
|
|
58
|
+
pkg = Crosspack::PackageManifest.load(options[:package])
|
|
59
|
+
rescue Crosspack::InvalidManifestError => e
|
|
60
|
+
abort_with e.message
|
|
61
|
+
end
|
|
62
|
+
puts manifest.error_report
|
|
63
|
+
puts pkg.error_report
|
|
64
|
+
exit(manifest.valid? && pkg.valid? ? 0 : 1)
|
|
65
|
+
when 'matrix'
|
|
66
|
+
abort_with 'Schema is invalid — the matrix cannot be built. Run: crosspack validate' unless manifest.valid?
|
|
67
|
+
puts Crosspack::Matrix.new(manifest).render
|
|
68
|
+
when 'resolve'
|
|
69
|
+
abort_with 'Specify a target: --target debian-12 (see crosspack --help)' unless options[:target]
|
|
70
|
+
begin
|
|
71
|
+
target = Crosspack::Target.parse(options[:target], arch: options[:arch])
|
|
72
|
+
rescue Crosspack::Target::Error => e
|
|
73
|
+
abort_with "Invalid target #{options[:target].inspect}: #{e.message}"
|
|
74
|
+
end
|
|
75
|
+
begin
|
|
76
|
+
resolver = Crosspack::Resolver.new(manifest)
|
|
77
|
+
format = options[:format] || target.format
|
|
78
|
+
result = resolver.depends(target, format: format)
|
|
79
|
+
if result.is_a?(Array)
|
|
80
|
+
puts "# #{target} (#{format})"
|
|
81
|
+
result.each { |d| puts d }
|
|
82
|
+
else
|
|
83
|
+
puts "# #{target} (#{format})"
|
|
84
|
+
puts "Depends: #{result}"
|
|
85
|
+
end
|
|
86
|
+
rescue Crosspack::ResolveError => e
|
|
87
|
+
abort_with "Failed to resolve dependencies for #{target}:\n #{e.message}"
|
|
88
|
+
end
|
|
89
|
+
when 'pack'
|
|
90
|
+
abort_with 'Specify a target: --target debian-12 and a version: --version 1.0-1' unless options[:target] && options[:version]
|
|
91
|
+
begin
|
|
92
|
+
target = Crosspack::Target.parse(options[:target], arch: options[:arch])
|
|
93
|
+
path = Crosspack.pack(
|
|
94
|
+
manifest: options[:package],
|
|
95
|
+
deps: options[:file],
|
|
96
|
+
target: target,
|
|
97
|
+
version: options[:version],
|
|
98
|
+
root: options[:root],
|
|
99
|
+
output_base: options[:output_base]
|
|
100
|
+
)
|
|
101
|
+
rescue Crosspack::Target::Error => e
|
|
102
|
+
abort_with "Invalid target #{options[:target].inspect}: #{e.message}"
|
|
103
|
+
rescue Crosspack::InvalidManifestError, Crosspack::ResolveError, Crosspack::BuildError => e
|
|
104
|
+
abort_with e.message
|
|
105
|
+
end
|
|
106
|
+
puts "📦 #{path}"
|
|
107
|
+
when 'targets'
|
|
108
|
+
# What can actually be packed: builds tree + resolvable deps per target.
|
|
109
|
+
pkg_path = File.expand_path(options[:package], options[:root])
|
|
110
|
+
sources = begin
|
|
111
|
+
Crosspack::PackageManifest.load(pkg_path).sources
|
|
112
|
+
rescue Crosspack::InvalidManifestError
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
root = sources ? File.expand_path(sources, options[:root]) : File.join(options[:root], 'builds')
|
|
116
|
+
puts Crosspack::Builds.report(root)
|
|
117
|
+
else
|
|
118
|
+
abort_with "Unknown command #{command.inspect}. Available: validate, resolve, matrix, pack, targets"
|
|
119
|
+
end
|