mirror of
https://github.com/aphrody-labs/gridcraft.git
synced 2026-10-14 03:29:07 +00:00
Packaging: offer GridCraft for .xlsb and .ods files on macOS
GridCraft imports XLSB (#101) and ODS (#100) files, and #321 added both to the Linux and Windows "Open with" lists, but the macOS Info.plist still declared only .xlsx, .xlsm, .csv and .tsv, so Finder's Open With didn't offer GridCraft for them. Add two CFBundleDocumentTypes entries (Editor, rank Alternate) with the UTIs macOS reports for these files, plus an imported UTI for .xlsb like the .xlsm one. A test now checks that the macOS and Windows packaging offer the same file types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fc45b7f6d8
commit
0485e7f4ba
4 files changed
+86
-5
No files matched your search
@@ -369,3 +369,32 @@ fn main() -> eframe::Result<()> {
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod packaging_tests {
|
||||
use gridcraft_engine::io::FileKind;
|
||||
|
||||
/// The text between `start` and `end` that follows each `marker` in `text`, sorted (e.g. the
|
||||
/// `xlsb` in `Classes\.xlsb\OpenWithProgids`).
|
||||
fn extensions(text: &str, marker: &str, start: &str, end: char) -> Vec<String> {
|
||||
let mut v: Vec<String> = text.split(marker).skip(1).filter_map(|s| s.split_once(start)?.1.split(end).next()).map(str::to_string).collect();
|
||||
v.sort();
|
||||
v
|
||||
}
|
||||
|
||||
/// macOS Open With (`CFBundleDocumentTypes`) offers GridCraft for the same files as Windows
|
||||
/// Open with, and GridCraft opens each of them. #321 added `.xlsb` and `.ods` on Windows and
|
||||
/// Linux only.
|
||||
#[test]
|
||||
fn macos_and_windows_offer_the_same_file_types() {
|
||||
let plist = include_str!("../../../packaging/macos/Info.plist.in");
|
||||
let wxs = include_str!("../../../packaging/windows/gridcraft.wxs");
|
||||
let mac = extensions(plist, "<key>CFBundleTypeExtensions</key>", "<string>", '<');
|
||||
let win = extensions(wxs, "Key=\"Software\\Classes\\.", "", '\\');
|
||||
assert!(mac.iter().any(|e| e == "xlsx"), "Info.plist.in extensions not found: {mac:?}");
|
||||
assert_eq!(mac, win);
|
||||
for ext in &mac {
|
||||
assert!(FileKind::from_path(&format!("book.{ext}")).is_some(), "GridCraft doesn't open .{ext}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# File-format parity
|
||||
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-12 · **Change:** minor (CSV save keeps the separator it was opened with) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-12 · **Change:** minor (macOS Open With offers GridCraft for `.xlsb` and `.ods`) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
|
||||
Every format Excel opens or saves, with GridCraft's read and write support, fidelity and tests.
|
||||
Part of [target-app-parity.md](target-app-parity.md). **File formats: ~50% ready, 80–120 h**
|
||||
@@ -78,6 +78,7 @@ refresh. Counted under features (Get & Transform, ~10% ready), not here.
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-12 | minor | macOS: the app bundle declares `.xlsb` and `.ods`, so Finder's Open With offers GridCraft for them, as Linux and Windows already did (#321) |
|
||||
| 2026-10-12 | minor | CSV: saving a file opened as CSV keeps its detected separator (`;` files were rewritten with `,`) |
|
||||
| 2026-10-11 | minor | XLSX: cell/shared/array formulas read through the file→model conversion (`_xlpm.` LET/LAMBDA parameter prefixes stripped); table column names keep line breaks; table names may start with `\` |
|
||||
| 2026-10-11 | minor | CSV/TSV export writes displayed values (number formats applied, no `#####`); `.xltx`, `.xltm` and `.xlsm` saved with their own workbook content types |
|
||||
|
||||
+4
-4
@@ -15,7 +15,7 @@ This is GridCraft's implementation of the shared [release playbook](release-play
|
||||
| Display name `GridCraft`, binaries `gridcraft` + `gridcraft-cli` | every script and workflow |
|
||||
| Bundle / app id `ai.storyteller.gridcraft` | `packaging/macos/Info.plist.in`, `packaging/linux/*`, flatpak manifest |
|
||||
| WiX UpgradeCode `5511327B-F305-41BE-92D0-EB84944E7C4D` (fixed forever) | `packaging/windows/gridcraft.wxs` |
|
||||
| File types `.xlsx` `.xlsm` `.csv` `.tsv` | Info.plist (`CFBundleDocumentTypes`), WiX (ProgIds/OpenWithProgids), `.desktop` `MimeType=`, `ai.storyteller.gridcraft.mime.xml`, metainfo |
|
||||
| File types `.xlsx` `.xlsm` `.xlsb` `.ods` `.csv` `.tsv` | Info.plist (`CFBundleDocumentTypes`), WiX (ProgIds/OpenWithProgids), `.desktop` `MimeType=`, `ai.storyteller.gridcraft.mime.xml`, metainfo |
|
||||
| Web app dir `apps/gridcraft-web` | `packaging/web/package.sh` |
|
||||
| App colour `#1f9d55` (ink `#147a40`), **proposed** | `assets/app-icon/README.md`, metainfo `<branding>` |
|
||||
|
||||
@@ -94,9 +94,9 @@ and upload their artifacts, the environment refuses macOS and Windows, and no re
|
||||
|
||||
- `Info.plist` comes from `Info.plist.in`: bundle id `ai.storyteller.gridcraft`,
|
||||
`LSMinimumSystemVersion` 11.0, `NSHighResolutionCapable`, category productivity, and
|
||||
`CFBundleDocumentTypes` for `.xlsx`, `.xlsm`, `.csv` and `.tsv` with rank **Alternate**, so
|
||||
GridCraft is offered in *Open With* without taking over Numbers' (or another app's)
|
||||
defaults. `.xlsm` gets an imported UTI in case macOS doesn't know it.
|
||||
`CFBundleDocumentTypes` for `.xlsx`, `.xlsm`, `.xlsb`, `.ods`, `.csv` and `.tsv` with rank
|
||||
**Alternate**, so GridCraft is offered in *Open With* without taking over Numbers' (or another
|
||||
app's) defaults. `.xlsm` and `.xlsb` get imported UTIs in case macOS doesn't know them.
|
||||
- **Signing** goes inside-out with the hardened runtime and a secure timestamp; no `--deep` on
|
||||
the final signature; `entitlements.plist` is deliberately empty.
|
||||
- **Notarization:** the app is zipped and sent with `xcrun notarytool submit --wait`, then
|
||||
|
||||
@@ -111,6 +111,39 @@
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array><string>text/tab-separated-values</string></array>
|
||||
</dict>
|
||||
<!-- .xlsb and .ods are imported (data only) into a new workbook that saves as .xlsx. -->
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Excel Binary Workbook</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.microsoft.excel.sheet.binary.macroenabled</string>
|
||||
</array>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array><string>xlsb</string></array>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array><string>application/vnd.ms-excel.sheet.binary.macroEnabled.12</string></array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>OpenDocument Spreadsheet</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.oasis-open.opendocument.spreadsheet</string>
|
||||
</array>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array><string>ods</string></array>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array><string>application/vnd.oasis.opendocument.spreadsheet</string></array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<!-- Types macOS may not know; the system's own declaration wins when it has one. -->
|
||||
@@ -134,6 +167,24 @@
|
||||
<array><string>application/vnd.ms-excel.sheet.macroEnabled.12</string></array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.microsoft.excel.sheet.binary.macroenabled</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Excel Binary Workbook</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>public.zip-archive</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array><string>xlsb</string></array>
|
||||
<key>public.mime-type</key>
|
||||
<array><string>application/vnd.ms-excel.sheet.binary.macroEnabled.12</string></array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
</dict>
|
||||
|
||||
Reference in new issue
Block a user