Skip to content

Commit 1c58197

Browse files
authored
Merge branch 'master' into gitrefs
2 parents b9a1f26 + aac65cf commit 1c58197

36 files changed

+2787
-2506
lines changed

.github/ISSUE_TEMPLATE/bug_template.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ body:
1010
description: >-
1111
What version of flatpak-builder are you using?
1212
If unsure, run `flatpak-builder --version` in the terminal.
13-
placeholder: 1.2.0
13+
placeholder: 1.4.1
1414
validations:
1515
required: true
1616

@@ -43,6 +43,7 @@ body:
4343
- pip/flatpak-pip-generator
4444
- poetry/flatpak-poetry-generator.py
4545
- rubygems/flatpak_rubygems_generator.rb
46+
- spm/flatpak-spm-generator.swift
4647
- yarn/flatpak-yarn-generator.py
4748
validations:
4849
required: true

.github/workflows/node.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
python-version:
21-
- '3.7'
2221
- '3.8'
2322
- '3.9'
2423
- '3.10'
2524
- '3.11'
25+
- '3.12'
2626
poetry-version:
27-
- '1.1.13'
27+
- '1.6.1'
2828
runs-on: ubuntu-22.04
2929
steps:
3030
- uses: actions/checkout@v4
@@ -35,7 +35,7 @@ jobs:
3535
- uses: actions/setup-python@v4
3636
with:
3737
python-version: ${{ matrix.python-version }}
38-
- uses: abatilo/actions-poetry@v2.1.6
38+
- uses: abatilo/actions-poetry@v2.3.0
3939
with:
4040
poetry-version: ${{ matrix.poetry-version }}
4141
- name: Install OS dependencies

CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/spm/ @david-swift
2+
/gradle/ @hadess

cargo/README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,21 @@
22

33
Tool to automatically generate `flatpak-builder` manifest json from a `Cargo.lock`.
44

5-
## Requirements:
5+
## Requirements
66

7-
Python 3.8+ with following modules:
7+
Poetry users can run `poetry install` and skip this.
88

9+
Otherwise install Python 3.8+ with these modules:
910
- toml
1011
- aiohttp
1112

1213
Generated manifests are supported by flatpak-builder 1.2.x or newer.
1314

14-
## Usage:
15+
## Usage
1516

16-
The first step is to convert the locked dependencies by Cargo into a format flatpak-builder can understand
17+
Poetry users: first activate your virtualenv by running `poetry shell`.
18+
19+
Convert the locked dependencies by Cargo into a format flatpak-builder can understand:
1720
```
1821
python3 ./flatpak-cargo-generator.py ./quickstart/Cargo.lock -o cargo-sources.json
1922
```
@@ -26,7 +29,7 @@ The output file should be added to the manifest like
2629
"build-commands": [
2730
"cargo --offline fetch --manifest-path Cargo.toml --verbose",
2831
"cargo --offline build --release --verbose",
29-
"install -Dm755 ./target/debug/quickstart -t /app/bin/"
32+
"install -Dm755 ./target/release/quickstart -t /app/bin/"
3033
],
3134
"sources": [
3235
{
@@ -42,3 +45,4 @@ Make sure to override CARGO_HOME env variable to point it to `/run/build/$module
4245

4346

4447
For a complete example see the quickstart project.
48+

cargo/flatpak-cargo-generator.py

Lines changed: 66 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,51 @@ def fetch_git_repo(git_url: str, commit: str) -> str:
114114
if head[:COMMIT_LEN] != commit[:COMMIT_LEN]:
115115
subprocess.run(['git', 'fetch', 'origin', commit], cwd=clone_dir, check=True)
116116
subprocess.run(['git', 'checkout', commit], cwd=clone_dir, check=True)
117+
118+
# Get the submodules as they might contain dependencies. This is a noop if
119+
# there are no submodules in the repository
120+
subprocess.run(['git', 'submodule', 'update', '--init', '--recursive'], cwd=clone_dir, check=True)
121+
117122
return clone_dir
118123

124+
def update_workspace_keys(pkg, workspace):
125+
for key, item in pkg.items():
126+
# There cannot be a 'workspace' key if the item is not a dict.
127+
if not isinstance(item, dict):
128+
continue;
129+
130+
# Recurse for keys under target.cfg(..)
131+
if key == 'target':
132+
for target in item.values():
133+
update_workspace_keys(target, workspace)
134+
continue;
135+
# dev-dependencies and build-dependencies should reference root dependencies table from workspace
136+
elif key == 'dev-dependencies' or key == 'build-dependencies':
137+
update_workspace_keys(item, workspace.get('dependencies', None))
138+
continue;
139+
140+
if not workspace or not key in workspace:
141+
continue;
142+
143+
workspace_item = workspace[key]
144+
145+
if 'workspace' in item:
146+
if isinstance(workspace_item, dict):
147+
del item['workspace']
148+
149+
for dep_key, workspace_value in workspace_item.items():
150+
# features are additive
151+
if dep_key == 'features' and 'features' in item:
152+
item['features'] += workspace_value
153+
else:
154+
item[dep_key] = workspace_value
155+
elif len(item) > 1:
156+
del item['workspace']
157+
item.update({ 'version': workspace_item })
158+
else:
159+
pkg[key] = workspace_item
160+
else:
161+
update_workspace_keys(item, workspace_item)
119162

120163
class _GitPackage(NamedTuple):
121164
path: str
@@ -127,18 +170,10 @@ def normalized(self) -> _TomlType:
127170
package = copy.deepcopy(self.package)
128171
if self.workspace is None:
129172
return package
130-
for section_key, section in package.items():
131-
# XXX We ignore top-level lists here; maybe we should iterate over list items, too
132-
if not isinstance(section, dict):
133-
continue
134-
for key, value in section.items():
135-
if not isinstance(value, dict):
136-
continue
137-
if not value.get('workspace'):
138-
continue
139-
package[section_key][key] = self.workspace[section_key][key]
140-
return package
141173

174+
update_workspace_keys(package, self.workspace)
175+
176+
return package
142177

143178
_GitPackagesType = Dict[str, _GitPackage]
144179

@@ -148,13 +183,27 @@ async def get_git_repo_packages(git_url: str, commit: str) -> _GitPackagesType:
148183
git_repo_dir = fetch_git_repo(git_url, commit)
149184
packages: _GitPackagesType = {}
150185

186+
def get_cargo_toml_packages(root_dir: str, workspace: Optional[_TomlType] = None):
187+
assert not os.path.isabs(root_dir) and os.path.isdir(root_dir)
188+
189+
with workdir(root_dir):
190+
if os.path.exists('Cargo.toml'):
191+
cargo_toml = load_toml('Cargo.toml')
192+
workspace = cargo_toml.get('workspace') or workspace
193+
194+
if 'package' in cargo_toml:
195+
packages[cargo_toml['package']['name']] = _GitPackage(
196+
path=os.path.normpath(root_dir),
197+
package=cargo_toml,
198+
workspace=workspace
199+
)
200+
for child in os.scandir(root_dir):
201+
if child.is_dir():
202+
# the workspace can be referenced by any subdirectory
203+
get_cargo_toml_packages(child.path, workspace)
204+
151205
with workdir(git_repo_dir):
152-
if os.path.isfile('Cargo.toml'):
153-
packages.update(await get_cargo_toml_packages(load_toml('Cargo.toml'), '.'))
154-
else:
155-
for toml_path in glob.glob('*/Cargo.toml'):
156-
packages.update(await get_cargo_toml_packages(load_toml(toml_path),
157-
os.path.dirname(toml_path)))
206+
get_cargo_toml_packages('.')
158207

159208
assert packages, f"No packages found in {git_repo_dir}"
160209
logging.debug(
@@ -168,68 +217,6 @@ async def get_git_repo_packages(git_url: str, commit: str) -> _GitPackagesType:
168217
return packages
169218

170219

171-
async def get_cargo_toml_packages(root_toml: _TomlType, root_dir: str) -> _GitPackagesType:
172-
assert not os.path.isabs(root_dir) and os.path.isdir(root_dir)
173-
assert 'package' in root_toml or 'workspace' in root_toml
174-
packages: _GitPackagesType = {}
175-
176-
async def get_dep_packages(
177-
entry: _TomlType,
178-
toml_dir: str,
179-
workspace: Optional[_TomlType] = None,
180-
):
181-
assert not os.path.isabs(toml_dir)
182-
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
183-
if 'dependencies' in entry:
184-
for dep_name, dep in entry['dependencies'].items():
185-
if 'package' in dep:
186-
dep_name = dep['package']
187-
if 'path' not in dep:
188-
continue
189-
if dep_name in packages:
190-
continue
191-
dep_dir = os.path.normpath(os.path.join(toml_dir, dep['path']))
192-
logging.debug("Loading dependency %s from %s", dep_name, dep_dir)
193-
dep_toml = load_toml(os.path.join(dep_dir, 'Cargo.toml'))
194-
assert dep_toml['package']['name'] == dep_name, toml_dir
195-
await get_dep_packages(dep_toml, dep_dir, workspace)
196-
packages[dep_name] = _GitPackage(
197-
path=dep_dir,
198-
package=dep,
199-
workspace=workspace,
200-
)
201-
if 'target' in entry:
202-
for _, target in entry['target'].items():
203-
await get_dep_packages(target, toml_dir)
204-
205-
if 'package' in root_toml:
206-
await get_dep_packages(root_toml, root_dir)
207-
packages[root_toml['package']['name']] = _GitPackage(
208-
path=root_dir,
209-
package=root_toml,
210-
workspace=None,
211-
)
212-
213-
if 'workspace' in root_toml:
214-
for member in root_toml['workspace'].get('members', []):
215-
for subpkg_toml in glob.glob(os.path.join(root_dir, member, 'Cargo.toml')):
216-
subpkg = os.path.normpath(os.path.dirname(subpkg_toml))
217-
logging.debug(
218-
"Loading workspace member %s in %s",
219-
subpkg_toml,
220-
os.path.abspath(root_dir),
221-
)
222-
pkg_toml = load_toml(subpkg_toml)
223-
await get_dep_packages(pkg_toml, subpkg, root_toml['workspace'])
224-
packages[pkg_toml['package']['name']] = _GitPackage(
225-
path=subpkg,
226-
package=pkg_toml,
227-
workspace=root_toml['workspace'],
228-
)
229-
230-
return packages
231-
232-
233220
_FlatpakSourceType = Dict[str, Any]
234221

235222

cargo/pyproject.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[tool.poetry]
2+
package-mode = false
3+
4+
[tool.poetry.dependencies]
5+
python = ">=3.8"
6+
aiohttp = "^3.9.5"
7+
toml = "^0.10.2"
8+
9+
10+
[build-system]
11+
requires = ["poetry-core"]
12+
build-backend = "poetry.core.masonry.api"

cargo/quickstart/com.flatpak.quickstart.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"build-commands": [
2626
"cargo --offline fetch --manifest-path Cargo.toml --verbose",
2727
"cargo --offline build --release --verbose",
28-
"install -Dm755 ./target/debug/qucikstart -t /app/bin/"
28+
"install -Dm755 ./target/release/quickstart -t /app/bin/"
2929
],
3030
"sources": [{
3131
"type": "dir",

dotnet/README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,17 @@ If you want to change the directory name, run `flatpak-dotnet-generator.py` with
3232
- `--runtime` or `-r` The target [runtime](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#linux-rids) to restore packages for.
3333
- `--dotnet` or `-d` The target version of dotnet to use. (Defaults to latest LTS version)
3434
- `--freedesktop` or `-f` The target version of the freedesktop sdk to use. (Defaults to latest version)
35-
- `--destdir` The directory the generated sources file will save sources to `nuget-sources` by default.
35+
- `--destdir` The directory the generated sources file will save sources to `nuget-sources` by default.
36+
- `--dotnet-args` or `-a` Pass additional arguments to the `dotnet` command.
37+
38+
## Example
39+
40+
To pass multiple arguments to the `dotnet` command, use the `--dotnet-args` option:
41+
42+
```bash
43+
python3 flatpak-dotnet-generator.py my-output-sources.json my.input.Desktop.csproj --runtime linux-x64 --dotnet-args --no-cache --verbosity detailed
44+
```
45+
46+
In this example:
47+
- `--no-cache` and `--verbosity detailed` are additional arguments passed to the `dotnet` command.
48+
- You can add as many arguments as needed after `--dotnet-args`.

dotnet/flatpak-dotnet-generator.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,50 @@
1010
import json
1111
import subprocess
1212
import tempfile
13-
13+
import concurrent.futures
1414

1515
def main():
1616
# Bump this to latest freedesktop runtime version.
17-
freedesktop_default = '22.08'
17+
freedesktop_default = '24.08'
1818
# Bump this to an LTS dotnet version.
19-
dotnet_default = '6'
19+
dotnet_default = '8'
2020

2121
parser = argparse.ArgumentParser()
2222
parser.add_argument('output', help='The output JSON sources file')
23-
parser.add_argument('project', help='The project file')
24-
parser.add_argument('--runtime', '-r', help='The target runtime to restore packages for')
23+
parser.add_argument('project', nargs='+', help='The project file(s)')
24+
parser.add_argument('--runtime', '-r', nargs='+', default=[None], help='The target runtime(s) to restore packages for')
2525
parser.add_argument('--freedesktop', '-f', help='The target version of the freedesktop sdk to use',
2626
default=freedesktop_default)
2727
parser.add_argument('--dotnet', '-d', help='The target version of dotnet to use',
2828
default=dotnet_default)
2929
parser.add_argument('--destdir',
3030
help='The directory the generated sources file will save sources to',
3131
default='nuget-sources')
32+
parser.add_argument('--dotnet-args', '-a', nargs=argparse.REMAINDER,
33+
help='Additional arguments to pass to the dotnet command')
3234
args = parser.parse_args()
3335

3436
sources = []
35-
3637
with tempfile.TemporaryDirectory(dir=Path()) as tmp:
37-
runtime_args = []
38-
if args.runtime:
39-
runtime_args.extend(('-r', args.runtime))
38+
def restore_project(project, runtime):
39+
subprocess.run([
40+
'flatpak', 'run',
41+
'--env=DOTNET_CLI_TELEMETRY_OPTOUT=true',
42+
'--env=DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true',
43+
'--command=sh', f'--runtime=org.freedesktop.Sdk//{args.freedesktop}', '--share=network',
44+
'--filesystem=host', f'org.freedesktop.Sdk.Extension.dotnet{args.dotnet}//{args.freedesktop}', '-c',
45+
f'PATH="${{PATH}}:/usr/lib/sdk/dotnet{args.dotnet}/bin" LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib/sdk/dotnet{args.dotnet}/lib" exec dotnet restore "$@"',
46+
'--', '--packages', tmp, project] + (['-r', runtime] if runtime else []) + (args.dotnet_args or []))
4047

41-
subprocess.run([
42-
'flatpak', 'run',
43-
'--env=DOTNET_CLI_TELEMETRY_OPTOUT=true',
44-
'--env=DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true',
45-
'--command=sh', f'--runtime=org.freedesktop.Sdk//{args.freedesktop}', '--share=network',
46-
'--filesystem=host', f'org.freedesktop.Sdk.Extension.dotnet{args.dotnet}//{args.freedesktop}', '-c',
47-
f'PATH="${{PATH}}:/usr/lib/sdk/dotnet{args.dotnet}/bin" LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib/sdk/dotnet{args.dotnet}/lib" exec dotnet restore "$@"',
48-
'--', '--packages', tmp, args.project] + runtime_args)
48+
with concurrent.futures.ThreadPoolExecutor() as executor:
49+
futures = []
50+
for project in args.project:
51+
if args.runtime:
52+
for runtime in args.runtime:
53+
futures.append(executor.submit(restore_project, project, runtime))
54+
else:
55+
futures.append(executor.submit(restore_project, project, None))
56+
concurrent.futures.wait(futures)
4957

5058
for path in Path(tmp).glob('**/*.nupkg.sha512'):
5159
name = path.parent.parent.name

go-get/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Flatpak Go Get Generator
2-
Tool to automatically create the source list for a Go module.
2+
Tool to automatically create the source list for a Go module (legacy).
3+
4+
It runs the build in a legacy `GOPATH` mode.
5+
For a module-aware mode, see [go-modules](../go-modules/README.md) or [flatpak-go-vendor-generator](./flatpak-go-vendor-generator.py) script.
36

47
The script does not require Go in the host system.
58

0 commit comments

Comments
 (0)