Skip to content

Commit 6bc4579

Browse files
Include en_001 locale, the default locale in swift-foundation
1 parent d3e6011 commit 6bc4579

File tree

9 files changed

+57
-29
lines changed

9 files changed

+57
-29
lines changed

Example/Package.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import PackageDescription
44

55
let package = Package(
66
name: "Example",
7+
traits: [
8+
.default(enabledTraits: ["Slim"]),
9+
"Slim",
10+
"Minimal",
11+
],
712
dependencies: [
813
.package(name: "swift-icudata-slim", path: "../"),
914
],
1015
targets: [
1116
.executableTarget(
1217
name: "Example",
1318
dependencies: [
14-
.product(name: "ICUDataSlim", package: "swift-icudata-slim"),
19+
.product(name: "ICUDataSlim_Minimal", package: "swift-icudata-slim", condition: .when(traits: ["Minimal"])),
20+
.product(name: "ICUDataSlim", package: "swift-icudata-slim", condition: .when(traits: ["Slim"]))
1521
]
1622
),
1723
]
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
// The Swift Programming Language
2-
// https://docs.swift.org/swift-book
3-
41
import Foundation
52

63
@main
74
struct Example {
85
static func main() {
9-
print("Available locales: \(Locale.availableIdentifiers.joined(separator: ", "))")
10-
print("Available encodings: \(String.availableStringEncodings.map { "\($0)" }.joined(separator: ", "))")
6+
print("Current locale: \(Locale.current.identifier)")
7+
print("Available locales: \(Locale.availableIdentifiers)")
8+
print("Available encodings: \(String.availableStringEncodings)")
9+
let dateFormatter = DateFormatter()
10+
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
11+
print("Parsing date: \(dateFormatter.date(from: "2023-10-01T12:00:00").map { "\($0)" } ?? "Failed to parse date!?")")
1112
}
1213
}

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ This package is especially useful for platforms that only support static linking
1010
| ICU Data Variant | Data Size | Description |
1111
|:----------------------|----------:|---------------------------------------------|
1212
| Default | 29.3 MB | Full ICU data, all locales and features |
13-
| `ICUDataSlim` | 8.5 MB | Excludes some ICU features not used by Foundation; <br/> locale limited to `en_US` (see [default.json](./Scripts/filters/default.json)) |
14-
| `ICUDataSlim_Minimal` | 1.2 MB | Excludes even more features for a smaller footprint; <br/> locale limited to `en_US` (see [minimal.json](./Scripts/filters/minimal.json)) |
13+
| `ICUDataSlim` | 8.6 MB | Excludes some ICU features not used by Foundation; <br/> locale limited to `en_001` (see [default.json](./Scripts/filters/default.json)) |
14+
| `ICUDataSlim_Minimal` | 1.5 MB | Excludes even more features for a smaller footprint; <br/> locale limited to `en_001` (see [minimal.json](./Scripts/filters/minimal.json)) |
1515

1616
## When to use minimal
1717

@@ -57,6 +57,15 @@ See the [`Example`](./Example) directory for a complete setup.
5757
> [!WARNING]
5858
> The pre-compiled ICU data included in this package assumes a little endian platform. Big endian platforms are not supported. (Swift does not officially support big endian platforms though)
5959
60+
## FAQ
61+
62+
### Why is `en_001` used as the only available locale?
63+
64+
The slimmed-down variants include only the `en_001` locale.
65+
On non-Apple platforms, the swift-foundation implementation *always* returns `en_001` by `Locale.current` regardless of environment variables or system locale settings.
66+
67+
For more details, you can refer to the relevant implementation in the [swift-foundation source code](https://github.com/swiftlang/swift-foundation/blob/swift-6.2-DEVELOPMENT-SNAPSHOT-2025-07-08-a/Sources/FoundationEssentials/Locale/Locale_Unlocalized.swift#L39).
68+
6069
## License
6170

6271
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

Scripts/build-all.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/usr/bin/env python3
22
import json
3-
import os
43
import subprocess
54
from pathlib import Path
5+
import shutil
66

77
ICU_VERSIONS_FILE = Path(__file__).parent.parent / "icu-versions.json"
88
PACKAGE_SCRIPT = Path(__file__).parent / "package-icudata.py"
99
OUTPUT_BASE = Path(__file__).parent.parent / "Sources"
1010

11-
def build_with_filter(filter_json: Path, filter_name: str, versions: dict):
11+
def build_with_filter(filter_json: Path, filter_name: str, versions: dict, args):
1212
print(f"Building with filter {filter_json}")
1313
icu_versions = set(versions["swift-icu-versions"].values())
1414
build_dir = Path(__file__).parent.parent / ".build" / "icu"
@@ -18,20 +18,29 @@ def build_with_filter(filter_json: Path, filter_name: str, versions: dict):
1818
out_dir.mkdir(parents=True, exist_ok=True)
1919
out_c = out_dir / filter_name / "icudata.c"
2020
print(f"Building ICU data {icu_version} -> {out_c}")
21-
if out_c.exists():
21+
if out_c.exists() and not args.clean:
2222
print(f"Skipping {out_c} because it already exists")
2323
continue
24-
24+
25+
per_filter_build_dir = build_dir / filter_name
26+
if args.clean and per_filter_build_dir.exists():
27+
print(f"Cleaning build directory {per_filter_build_dir}")
28+
for item in per_filter_build_dir.iterdir():
29+
if item.is_file():
30+
item.unlink()
31+
else:
32+
shutil.rmtree(item)
33+
2534
args = [
2635
"python3", str(PACKAGE_SCRIPT),
2736
"--icu-version", icu_version,
2837
"--filter-json", str(filter_json),
2938
"--output", str(out_c),
30-
"--build-dir", str(build_dir / filter_name)
39+
"--build-dir", str(per_filter_build_dir)
3140
]
3241
print(f"Running {' '.join(args)}")
3342
subprocess.run(args, check=True)
34-
43+
3544
for swift_version in versions["swift-icu-versions"]:
3645
icu_version = versions["swift-icu-versions"][swift_version]
3746
out_dir = OUTPUT_BASE / f"ICUDataSlim_{swift_version.replace('.', '_')}" / filter_name
@@ -41,19 +50,28 @@ def build_with_filter(filter_json: Path, filter_name: str, versions: dict):
4150
with open(out_c, "w") as f:
4251
f.write(f"// Generated by build-all.py\n")
4352
f.write(f"#include \"../../icudata/{icu_version}/{filter_name}/icudata.c\"\n")
44-
53+
4554
out_empty_h = out_dir / "include" / "empty.h"
4655
out_empty_h.parent.mkdir(parents=True, exist_ok=True)
4756
out_empty_h.touch()
4857

4958

59+
def parse_args():
60+
import argparse
61+
parser = argparse.ArgumentParser(description="Build ICU data for all filters and versions.")
62+
parser.add_argument("--clean", action="store_true", help="Clean build directories before building")
63+
return parser.parse_args()
64+
65+
5066
def main():
67+
args = parse_args()
5168
with open(ICU_VERSIONS_FILE) as f:
5269
versions = json.load(f)
53-
70+
5471
filters_dir = Path(__file__).parent / "filters"
5572
for filter_file in filters_dir.glob("*.json"):
56-
build_with_filter(filter_file, filter_file.stem, versions)
73+
build_with_filter(filter_file, filter_file.stem, versions, args)
74+
5775

5876
if __name__ == "__main__":
5977
main()

Scripts/filters/default.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"filterType": "locale",
44
"includeScripts": false,
55
"includelist": [
6-
"en_US"
6+
"en_001"
77
]
88
},
99
"featureFilters": {
@@ -36,4 +36,4 @@
3636
"filterType": "exclude"
3737
}
3838
}
39-
}
39+
}

Scripts/filters/minimal.json

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"filterType": "locale",
44
"includeScripts": false,
55
"includelist": [
6-
"en_US"
6+
"en_001"
77
]
88
},
99
"featureFilters": {
@@ -44,15 +44,9 @@
4444
"zone_supplemental": {
4545
"filterType": "exclude"
4646
},
47-
"locales_tree": {
48-
"filterType": "exclude"
49-
},
5047
"conversion_mappings": {
5148
"filterType": "exclude"
5249
},
53-
"curr_tree": {
54-
"filterType": "exclude"
55-
},
5650
"translit": {
5751
"filterType": "exclude"
5852
},
@@ -66,4 +60,4 @@
6660
"filterType": "exclude"
6761
}
6862
}
69-
}
63+
}

Scripts/package-icudata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ def main():
116116
build_dir = Path(args.build_dir)
117117
icu_src = download_and_extract(icu_url, build_dir, icu_version)
118118
destdir = build_dir / "destdir"
119-
destdir.mkdir()
119+
destdir.mkdir(parents=True, exist_ok=True)
120120
dat_path, version = build_icu(icu_src, Path(args.filter_json).absolute(), args.jobs, destdir)
121121
dat_to_c(dat_path, version, args.output)
122122

123123
if __name__ == "__main__":
124-
main()
124+
main()
103 KB
Binary file not shown.
289 KB
Binary file not shown.

0 commit comments

Comments
 (0)