feat(cli): UTExportedTypeDeclarations support for file associations - #51
Conversation
Review Summary by QodoAdd UTExportedTypeDeclarations and content types support for file associations
WalkthroughsDescription• Add UTExportedTypeDeclarations support for custom file types on macOS • Add content_types field to declare file format support via LSItemContentTypes • Add ExportedFileAssociation struct for defining custom type metadata • Update file association logic to conditionally populate plist entries • Improve error handling with explicit expect() for required name field Diagramflowchart LR
FA["FileAssociation struct"]
CT["content_types field"]
ET["exported_type field"]
EFA["ExportedFileAssociation struct"]
PLIST["macOS Info.plist"]
LSI["LSItemContentTypes"]
UTED["UTExportedTypeDeclarations"]
FA --> CT
FA --> ET
ET --> EFA
CT --> PLIST
EFA --> PLIST
PLIST --> LSI
PLIST --> UTED
File Changes1. crates/tauri-bundler/src/bundle/macos/app.rs
|
Code Review by Qodo
1. association.name uses expect
|
| "CFBundleTypeName".into(), | ||
| association | ||
| .name | ||
| .as_ref() | ||
| .unwrap_or(&association.ext[0].0) | ||
| .expect("File association must have a name") | ||
| .to_string() |
There was a problem hiding this comment.
1. association.name uses expect 📘 Rule violation ⛯ Reliability
create_info_plist panics when association.name is None due to an expect, instead of returning a Result error for invalid user configuration. This can crash bundling for valid configs that omit name (it is optional elsewhere), violating the no-panic guidance for fallible operations.
Agent Prompt
## Issue description
`create_info_plist` unwraps `association.name` with `expect("File association must have a name")`, which can panic during bundling when the config omits `name`.
## Issue Context
`create_info_plist` already returns `crate::Result<()>`, so invalid/missing configuration should be reported via a returned error (or handled with a safe fallback) rather than panicking.
## Fix Focus Areas
- crates/tauri-bundler/src/bundle/macos/app.rs[348-356]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if association.ext.is_empty() { | ||
| dict.insert( | ||
| "CFBundleTypeExtensions".into(), | ||
| plist::Value::Array( | ||
| association | ||
| .ext | ||
| .iter() | ||
| .map(|ext| ext.to_string().into()) | ||
| .collect(), | ||
| ), | ||
| ); | ||
| } |
There was a problem hiding this comment.
2. Missing cfbundletypeextensions 🐞 Bug ✓ Correctness
In create_info_plist (macOS), CFBundleTypeExtensions is only inserted when association.ext is empty, so typical associations with extensions omit CFBundleTypeExtensions entirely and cannot be registered by extension.
Agent Prompt
### Issue description
`CFBundleTypeExtensions` is currently inserted only when `association.ext.is_empty()`, which suppresses extension-based associations for normal configs.
### Issue Context
macOS file associations by extension rely on `CFBundleDocumentTypes` entries containing `CFBundleTypeExtensions`. The config model describes `ext` as the primary association mechanism.
### Fix Focus Areas
- crates/tauri-bundler/src/bundle/macos/app.rs[328-339]
### Expected change
- Change `if association.ext.is_empty()` to `if !association.ext.is_empty()` (or remove the condition if always desired).
- Ensure the `ext.is_empty()` case does not insert an empty `CFBundleTypeExtensions` array unless explicitly required and documented.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if let Some(content_types) = &association.content_types { | ||
| dict.insert( | ||
| "UTTypeConformsTo".into(), | ||
| plist::Value::Array(content_types.iter().map(|s| s.clone().into()).collect()), | ||
| ); | ||
| } |
There was a problem hiding this comment.
3. Wrong uttypeconformsto source 🐞 Bug ✓ Correctness
UTExportedTypeDeclarations populates UTTypeConformsTo from FileAssociation.content_types instead of ExportedFileAssociation.conforms_to, so exportedType.conformsTo is ignored and exported type metadata is incorrect.
Agent Prompt
### Issue description
`UTTypeConformsTo` for `UTExportedTypeDeclarations` is currently derived from `FileAssociation.content_types`, so `exportedType.conformsTo` is ignored.
### Issue Context
The config type `ExportedFileAssociation.conforms_to` is explicitly documented as mapping to `UTTypeConformsTo`. `contentTypes` is documented as mapping to `LSItemContentTypes`.
### Fix Focus Areas
- crates/tauri-bundler/src/bundle/macos/app.rs[274-289]
- crates/tauri-utils/src/config.rs[1212-1216]
### Expected change
- Replace the `if let Some(content_types) = &association.content_types` block (for UTTypeConformsTo) with logic that uses `exported_type.conforms_to`.
- Do not change the existing `LSItemContentTypes` insertion, which should continue to use `association.content_types`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Benchmark PR from agentic-review-benchmarks#12