Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3 alpha feature/file association port #3873

Merged
merged 10 commits into from
Nov 8, 2024

Conversation

leaanthony
Copy link
Member

@leaanthony leaanthony commented Nov 3, 2024

Adds support for File Association with your Wails application.

Fixes #3655

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced support for file associations, allowing applications to handle specific file types.
    • Added a guide for implementing file associations in Wails v3 applications.
    • New event type ApplicationOpenedWithFile to enhance file handling capabilities.
  • Bug Fixes

    • Resolved issues with application termination when dialogs are displayed on macOS.
  • Documentation

    • Updated changelog to reflect new features and fixes.
    • Enhanced API documentation with new guidelines for handling dialogs and file associations.
  • Improvements

    • Refined event handling and API structure for better performance and usability.

Support `ApplicationOpenedWithFile` event on Windows
Add docs
Support `ApplicationOpenedWithFile` event on Windows
Add docs
Add test project
Fix show window bug.
Copy link
Contributor

coderabbitai bot commented Nov 3, 2024

Walkthrough

The pull request introduces several enhancements to the Wails framework, primarily focusing on file association features. Key changes include the addition of documentation on handling file associations, updates to event types for file opening, and modifications to application behavior on macOS. New configuration files and tasks for building applications are included, alongside updates to existing application structures to support these features. Overall, the changes aim to facilitate file management and improve user interaction within the Wails applications.

Changes

File Change Summary
mkdocs-website/docs/en/API/application_dialogs.md Added a warning section on macOS dialog handling during startup, including code snippets for configuration.
mkdocs-website/docs/en/changelog.md Updated changelog with new features, bug fixes, and significant changes including file association support and event handling updates.
mkdocs-website/docs/en/learn/guides/file-associations.md Introduced a guide on implementing file associations in Wails v3 applications with configuration examples.
mkdocs-website/docs/en/status.md Updated project status to Alpha 7 and added ongoing tasks related to file associations and drag-and-drop support.
mkdocs-website/mkdocs.yml Added navigation entry for the new file associations guide.
v3/examples/file-association/.gitignore Updated to ignore specific build artifacts.
v3/examples/file-association/Inter Font License.txt Added licensing terms for the Inter font.
v3/examples/file-association/README.md Created README for the file association sample project with instructions.
v3/examples/file-association/Taskfile.yml Introduced task management configuration for building the file association application.
v3/examples/file-association/build/Info.dev.plist Added a new plist file for application metadata.
v3/examples/file-association/build/Info.plist Added a new plist file defining essential metadata for macOS.
v3/examples/file-association/build/Taskfile.common.yml Added tasks for managing build processes.
v3/examples/file-association/build/Taskfile.darwin.yml Introduced macOS-specific task management for building and packaging.
v3/examples/file-association/build/Taskfile.linux.yml Introduced Linux-specific task management for building and packaging.
v3/examples/file-association/build/Taskfile.windows.yml Introduced Windows-specific task management for building and packaging.
v3/examples/file-association/build/appimage/build.sh Added a script for automating AppImage creation.
v3/examples/file-association/build/config.yml Created a new configuration file for application metadata and file associations.
v3/examples/file-association/build/devmode.config.yaml Added configuration for the development environment.
v3/examples/file-association/build/info.json Introduced JSON file for application metadata.
v3/examples/file-association/build/nsis/project.nsi Added NSIS script for building an installer.
v3/examples/file-association/build/nsis/wails_tools.nsh Introduced macros for file association management in the installer.
v3/examples/file-association/build/wails.exe.manifest Created a manifest file for application dependencies.
v3/examples/file-association/frontend/bindings/changeme/greetservice.js Added a greeting service with an exported function.
v3/examples/file-association/frontend/bindings/changeme/index.js Created an index file for re-exporting greeting service functions.
v3/examples/file-association/frontend/index.html Introduced a new HTML file for the frontend layout.
v3/examples/file-association/frontend/main.js Implemented functionality for greeting and time event handling.
v3/examples/file-association/frontend/package.json Created a package.json file for frontend dependencies.
v3/examples/file-association/frontend/public/style.css Added CSS file for styling the frontend application.
v3/examples/file-association/go.mod Created a go.mod file for managing dependencies.
v3/examples/file-association/greetservice.go Introduced a new service struct for greeting functionality.
v3/examples/file-association/main.go Implemented the main application logic, including event handling for file openings.
v3/examples/file-association/test.wails Added user instruction for application initiation.
v3/internal/commands/build-assets.go Restructured configuration options for build assets.
v3/internal/commands/build_assets/Taskfile.common.yml Added a new task for updating build assets.
v3/internal/commands/build_assets/config.yml Created a new configuration file for application metadata.
v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl Modified plist template for binary name reference.
v3/internal/commands/updatable_build_assets/Info.plist.tmpl Updated plist template for binary name reference.
v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl Enhanced NSIS template with file association macros.
v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js Added a new event type for file opening.
v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts Introduced a new event type for file opening.
v3/pkg/application/application_darwin.go Added a function to handle file opening events.
v3/pkg/application/application_darwin_delegate.h Updated class inheritance and added function declaration for file handling.
v3/pkg/application/application_darwin_delegate.m Introduced a method for handling file opening in the application.
v3/pkg/application/application_options.go Added a field for file associations in application options.
v3/pkg/application/application_windows.go Enhanced the run method to handle file associations.
v3/pkg/application/context_application_event.go Added methods for managing file opening context.
v3/pkg/application/dialogs_darwin.go Simplified alert handling in dialog functions.
v3/pkg/application/webview_window_darwin.go Modified window display handling logic.
v3/pkg/application/webview_window_windows.go Adjusted window visibility handling.
v3/pkg/events/events.go Added a new event type for file opening.
v3/pkg/events/events.txt Declared a new event for application lifecycle management.
v3/tasks/events/generate.go Enhanced event generation logic with version management.
v3/tasks/events/go.mod Created a go.mod file for the events module.

Assessment against linked issues

Objective Addressed Explanation
Port the feature from v2 (#[3655])
Implement file association handling in the application
Update documentation to reflect new features and usage

Possibly related PRs

  • [V3/Docs] Add Events documentation #3867: Changes related to handling dialogs in macOS applications during startup are connected to the new event types and event handling documentation introduced in this PR.

🐰 In the meadow, we hop and play,
New features bloom, bright as day!
File associations, a joyful cheer,
Wails grows stronger, year by year!
With every change, our hearts take flight,
Hopping forward, all feels right! 🐇✨


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8a2d39c and f9b13cb.

📒 Files selected for processing (2)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • mkdocs-website/mkdocs.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • mkdocs-website/docs/en/changelog.md
  • mkdocs-website/mkdocs.yml

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

cloudflare-workers-and-pages bot commented Nov 3, 2024

Deploying wails with  Cloudflare Pages  Cloudflare Pages

Latest commit: f9b13cb
Status: ✅  Deploy successful!
Preview URL: https://8ce7af1a.wails.pages.dev
Branch Preview URL: https://v3-alpha-feature-file-associ.wails.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 32

🧹 Outside diff range and nitpick comments (63)
v3/examples/file-association/greetservice.go (1)

1-7: LGTM, but example seems incomplete for file association demonstration.

While the code is syntactically correct, this example appears to be missing the actual file association demonstration that this PR aims to port from v2 to v3. Consider enhancing this example to show:

  • How to register file associations
  • How to handle file open events
  • How to process associated files when the application starts

Would you like assistance in expanding this example to better demonstrate the file association feature?

v3/pkg/application/application_darwin_delegate.h (1)

14-14: Consider adding safety measures for HandleOpenFile.

The C-style string parameter requires careful memory management. Consider these improvements:

  1. Add nullability annotations for better Swift interop
  2. Document the ownership/lifecycle of the char* parameter
-extern void HandleOpenFile(char *);
+extern void HandleOpenFile(char * _Nonnull filename) NS_SWIFT_NAME(handleOpenFile(_:));
v3/examples/file-association/README.md (2)

4-4: Format the URL using proper markdown link syntax.

Convert the bare URL to a properly formatted markdown link for better readability and maintainability.

-More info at: https://v3alpha.wails.io/learn/guides/file-associations/
+More info at: [File Associations Guide](https://v3alpha.wails.io/learn/guides/file-associations/)
🧰 Tools
🪛 Markdownlint

4-4: null
Bare URL used

(MD034, no-bare-urls)


6-11: Enhance instructions with additional details and verification steps.

While the instructions are clear, consider adding the following details to improve user experience:

  1. Specify where to find or how to create the test.wails file
  2. Explain what the .wails extension represents
  3. Add verification steps to confirm successful file association
 To run the sample, follow these steps:

 1. Run `wails3 package` to generate the package.
 2. On Windows, run the installer that was built in the `bin` directory.
+3. Create a test file with the `.wails` extension (e.g., `echo "test" > test.wails`)
-3. Double-click on the `test.wails` file to open it with the application.
-4. On macOS, double-click on the `test.wails` file and select the built application.
+4. Double-click on the `test.wails` file:
+   - On Windows: The file should automatically open with your application
+   - On macOS: Select the built application when prompted
+5. Verify that:
+   - The application launches successfully
+   - The file content is properly handled by the application
v3/examples/file-association/frontend/main.js (2)

7-17: Improve error handling and avoid global functions

Consider these improvements:

  1. Avoid attaching to window object directly
  2. Add proper input sanitization
  3. Provide more informative error messages
-window.doGreet = () => {
+const doGreet = () => {
     let name = document.getElementById('name').value;
-    if (!name) {
+    if (!name || !name.trim()) {
         name = 'anonymous';
     }
+    name = name.trim();
     GreetService.Greet(name).then((result) => {
         resultElement.innerText = result;
     }).catch((err) => {
-        console.log(err);
+        console.error('Greeting failed:', err);
+        resultElement.innerText = 'Error: Failed to generate greeting';
     });
 }
+
+// Export if needed
+window.doGreet = doGreet;

1-21: Enhance example to demonstrate file association features

As this is part of the file association example directory, it should primarily demonstrate how to handle file associations in a Wails application. The current implementation focuses on greeting functionality instead. Consider restructuring this example to:

  1. Focus on file handling and association features
  2. Demonstrate proper event handling for file open events
  3. Show how to process different file types
  4. Include error handling specific to file operations

Would you like assistance in implementing a more focused file association example?

v3/examples/file-association/build/devmode.config.yaml (1)

1-4: Consider adjusting development mode settings for better developer experience.

The current configuration might hinder development productivity:

  • Log level warn may hide useful debugging information
  • 1000ms debounce could cause noticeable delays in development feedback

Consider this configuration for development:

 config:
   root_path: .
-  log_level: warn
-  debounce: 1000
+  log_level: debug
+  debounce: 500
v3/examples/file-association/Taskfile.yml (1)

9-12: LGTM! Consider adding variable descriptions.

The variables are well-defined with appropriate defaults. Consider adding comments to document the purpose of each variable, especially VITE_PORT.

 vars:
+  # Name of the application binary
   APP_NAME: "fileassoc"
+  # Directory where built binaries are stored
   BIN_DIR: "bin"
+  # Port for Vite development server, defaults to 9245 if WAILS_VITE_PORT is not set
   VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}'
v3/examples/file-association/build/appimage/build.sh (2)

1-6: Consider removing the -x flag in production.

While the strict error handling is excellent, the -x flag (which prints each command) might generate too much output in production. Consider keeping it only for debugging.

-set -euxo pipefail
+set -euo pipefail

1-26: Consider adding logging and documentation.

As this is an example script that others will reference, consider these architectural improvements:

  1. Add a logging function to standardize output messages
  2. Include usage documentation in script comments
  3. Consider supporting command-line arguments for overriding environment variables
  4. Add a cleanup function to handle intermediate files and failed states

Would you like me to provide an example implementation of these improvements?

v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl (1)

Add file association configuration to the plist template

The v2 template includes file association support through CFBundleDocumentTypes, but this configuration is missing in the v3 template. Add the following configuration block to v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl:

{{if .FileAssociations}}
<key>CFBundleDocumentTypes</key>
<array>
    {{range .FileAssociations}}
    <dict>
        <key>CFBundleTypeExtensions</key>
        <array>
            <string>{{.Ext}}</string>
        </array>
        <key>CFBundleTypeName</key>
        <string>{{.Name}}</string>
        <key>CFBundleTypeRole</key>
        <string>{{.Role}}</string>
        <key>CFBundleTypeIconFile</key>
        <string>{{.IconName}}</string>
    </dict>
    {{end}}
</array>
{{end}}
🔗 Analysis chain

Line range hint 1-32: Verify file association configuration in plist template.

Since this PR implements file association support, the template might need additional keys like CFBundleDocumentTypes for file type associations.

Let's check if other plist templates in the codebase include file association configurations:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for file association configurations in plist templates
# and ensure consistency across templates

# Search for file association related keys in plist templates
rg -A 5 'CFBundleDocumentTypes|UTExportedTypeDeclarations|LSItemContentTypes' --glob '*.plist*'

Length of output: 1278


Script:

#!/bin/bash
# Let's check the v2 plist templates to understand the file association structure
cat v2/pkg/buildassets/build/darwin/Info.plist

Length of output: 2216

v3/internal/commands/build_assets/config.yml (4)

8-14: Add validation guidelines for info fields.

Consider adding comments about:

  • Required format for productIdentifier (reverse domain notation)
  • Version format requirements (semver recommended)
  • Character limits or restrictions for fields

18-29: Enhance file associations documentation.

Please add comments to clarify:

  1. Valid values for the role field (e.g., Editor, Viewer, Shell)
  2. Icon requirements (format, size, location)
  3. Whether these examples should be uncommented for basic setup

Consider adding this documentation above the section:

 # File Associations
+# Valid roles: Editor, Viewer, Shell
+# Icons should be provided in .ico format for Windows and .icns for macOS
+# Place icons in the build/appicon directory
+# Uncomment and modify the examples below to add file associations

30-32: Document the structure of 'other' data.

The purpose and expected structure of the other section is unclear. Please add documentation about:

  • Required fields for each entry
  • Purpose of this section
  • How this data is used in the application
🧰 Tools
🪛 yamllint

[error] 32-32: no new line character at the end of file

(new-line-at-end-of-file)


7-14: Consider security implications of configuration.

The info section contains potentially sensitive company information. Consider:

  1. Adding documentation about using environment variables for sensitive values
  2. Providing guidance on configuration file management in version control
  3. Adding validation for the productIdentifier to prevent spoofing
mkdocs-website/docs/en/status.md (1)

23-26: Consider adding more details about the in-progress features.

While the status items clearly indicate what's being worked on, it would be helpful to provide more context about:

  1. The scope of file association support (e.g., which platforms are supported)
  2. The relationship between file associations and drag-and-drop support
  3. Expected completion timeline or milestones

Consider expanding the section like this:

 ## Alpha 8 Status

-In Progress: Add support for File Associations
-In Progress: Drag and Drop support for Linux
+In Progress:
+- File Associations
+  - Porting from v2 (see #3655)
+  - Supporting Windows and macOS platforms
+  - Expected in next alpha release
+
+- Drag and Drop support for Linux
+  - Complementing existing platform support
+  - Enhancing file handling capabilities
v3/examples/file-association/build/Taskfile.darwin.yml (1)

43-45: Add validation to the run task.

The run task should verify that the binary exists before attempting to execute it.

Consider adding validation:

 run:
+  preconditions:
+    - sh: test -f {{.BIN_DIR}}/{{.APP_NAME}}
+      msg: "Binary not found. Please run the build task first."
   cmds:
     - '{{.BIN_DIR}}/{{.APP_NAME}}'
v3/pkg/application/context_application_event.go (2)

7-7: Consider a more specific constant name.

The constant filename could be more descriptive to indicate its specific purpose in the context of file association events. Consider using something like openedWithFilename or associatedFilename to better reflect its usage.

-	filename    = "filename"
+	openedWithFilename = "openedWithFilename"

63-73: Add documentation and consider storing constant lookup result.

  1. Add documentation for this exported method to describe its purpose and return value.
  2. Consider storing the constant lookup result to avoid potential maintenance issues if the constant name changes.
+// Filename returns the filepath that was used to open the application.
+// Returns an empty string if no file was used or if the value is invalid.
 func (c ApplicationEventContext) Filename() string {
-	filename, ok := c.data[filename]
+	value, ok := c.data[filename]
 	if !ok {
 		return ""
 	}
-	result, ok := filename.(string)
+	result, ok := value.(string)
 	if !ok {
 		return ""
 	}
 	return result
 }
v3/examples/file-association/build/Taskfile.windows.yml (3)

24-28: Consider adding validation steps to package task.

The package task could benefit from additional steps to validate the installer after creation, such as checking file size and presence of required resources.

 package:
   summary: Packages a production build of the application into a `.exe` bundle
   cmds:
     - task: create:nsis:installer
+    - cmd: |
+        if [ ! -f "{{.BIN_DIR}}/{{.APP_NAME}}-installer.exe" ]; then
+          echo "Installer not created successfully"
+          exit 1
+        fi

37-49: Add installer output path validation.

While the installer creation is well-configured, it would be beneficial to validate the output path and ensure the installer is created successfully.

 create:nsis:installer:
   summary: Creates an NSIS installer
   dir: build/nsis
   deps:
     - task: build
       vars:
         PRODUCTION: "true"
   cmds:
     - makensis -DARG_WAILS_{{.ARG_FLAG}}_BINARY="{{.ROOT_DIR}}\{{.BIN_DIR}}\{{.APP_NAME}}.exe" project.nsi
+    - cmd: |
+        if [ ! -f "{{.APP_NAME}}-installer.exe" ]; then
+          echo "NSIS installer creation failed"
+          exit 1
+        fi
   vars:
     ARCH: '{{.ARCH | default ARCH}}'
     ARG_FLAG: '{{if eq .ARCH "amd64"}}AMD64{{else}}ARM64{{end}}'

50-52: Add error handling to run task.

Consider adding basic error handling to ensure the executable exists before attempting to run it.

 run:
   cmds:
+    - cmd: |
+        if [ ! -f "{{.BIN_DIR}}\\{{.APP_NAME}}.exe" ]; then
+          echo "Executable not found"
+          exit 1
+        fi
     - '{{.BIN_DIR}}\\{{.APP_NAME}}.exe'
+

This change also addresses the missing newline at the end of file.

🧰 Tools
🪛 yamllint

[error] 52-52: no new line character at the end of file

(new-line-at-end-of-file)

v3/internal/commands/build_assets/Taskfile.common.yml (2)

71-75: Consider enhancing task caching capabilities.

While the task implementation is correct, consider adding sources and generates declarations to enable Go-Task's caching mechanism. This would prevent unnecessary re-runs when inputs haven't changed.

 update:build-assets:
   summary: Updates the build assets
   dir: build
+  sources:
+    - config.yml
+  generates:
+    - .wails/**/*
   cmds:
     - wails3 update build-assets -name "{{.APP_NAME}}" -binaryname "{{.APP_NAME}}" -config config.yml -dir .
+
🧰 Tools
🪛 yamllint

[error] 75-75: no new line character at the end of file

(new-line-at-end-of-file)


75-75: Add missing newline at end of file.

Add a newline character at the end of the file to comply with POSIX standards and prevent potential issues with text processing tools.

🧰 Tools
🪛 yamllint

[error] 75-75: no new line character at the end of file

(new-line-at-end-of-file)

v3/examples/file-association/build/Taskfile.common.yml (6)

4-12: Consider adding error handling for go mod tidy.

While the task is well-structured, it might be good to add error handling to ensure the command executed successfully.

 cmds:
-  - go mod tidy
+  - cmd: go mod tidy
+    silent: true
+    ignore_error: false

14-26: Consider adding caching for npm dependencies.

The task correctly handles dependencies, but build times could be improved by adding caching.

 cmds:
-  - npm install
+  - cmd: npm ci
+    sources:
+      - package-lock.json
+    generates:
+      - node_modules/.package-lock.json

28-40: Consider adding environment-specific build configurations.

The build task could be enhanced to support different environments (development, production, etc.).

 cmds:
-  - npm run build -q
+  - cmd: npm run build -q
+    env:
+      NODE_ENV: '{{.BUILD_ENV | default "production"}}'

41-51: Add explicit error handling for bindings generation.

The bindings generation is crucial for the application to work correctly. Consider adding explicit error handling.

 cmds:
-  - wails3 generate bindings -f '{{.BUILD_FLAGS}}'{{if .UseTypescript}} -ts{{end}}
+  - cmd: wails3 generate bindings -f '{{.BUILD_FLAGS}}'{{if .UseTypescript}} -ts{{end}}
+    ignore_error: false

52-62: Add input validation for icon generation.

Consider adding validation for the input image to ensure it meets the requirements for both Windows and macOS icons.

 cmds:
+  - cmd: test -f appicon.png
+    msg: "appicon.png not found in build directory"
   - wails3 generate icons -input appicon.png

63-70: Add default port configuration.

Consider adding a default port value to ensure the task works even if VITE_PORT is not set.

 cmds:
-  - npm run dev -- --port {{.VITE_PORT}} --strictPort
+  - npm run dev -- --port {{.VITE_PORT | default "3000"}} --strictPort
v3/examples/file-association/build/Taskfile.linux.yml (2)

23-31: Consider supporting additional Linux package formats.

The package task currently only creates an AppImage. Consider:

  1. Adding support for .deb and .rpm packages for wider distribution
  2. Adding error checking for the build step before proceeding with packaging

64-66: Enhance run task with validation and dev configuration.

The run task could be improved with:

  1. Binary existence check
  2. Development-specific environment variables
  3. Optional debug flags
 run:
+  deps:
+    - task: build
   cmds:
+    - test -f {{.BIN_DIR}}/{{.APP_NAME}} || (echo "Binary not found. Run build task first." && exit 1)
     - '{{.BIN_DIR}}/{{.APP_NAME}}'
+  env:
+    DEBUG: '{{.DEBUG | default "false"}}'
mkdocs-website/docs/en/API/application_dialogs.md (3)

2-2: Fix macOS capitalization in warning title.

The operating system name should be written as "macOS" according to Apple's branding guidelines.

-!!! warning "MacOS Dialogs and Application Lifecycle"
+!!! warning "macOS Dialogs and Application Lifecycle"
🧰 Tools
🪛 LanguageTool

[grammar] ~2-~2: The operating system from Apple is written “macOS”.
Context: !!! warning "MacOS Dialogs and Application Lifecycle" ...

(MAC_OS)


19-21: Replace hard tabs with spaces for consistent formatting.

The code example contains hard tabs which should be replaced with spaces for better consistency across different editors.

-	app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
-		filename = event.Context().Filename()
-    })
+    app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
+        filename = event.Context().Filename()
+    })
🧰 Tools
🪛 Markdownlint

19-19: Column: 1
Hard tabs

(MD010, no-hard-tabs)


20-20: Column: 1
Hard tabs

(MD010, no-hard-tabs)


17-29: Consider adding error handling to the code example.

The example could be enhanced by demonstrating proper error handling for cases where the filename might be empty or invalid.

 var filename string
 app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
     filename = event.Context().Filename()
 })

 window.OnWindowEvent(events.Common.WindowShow, func(event *application.WindowEvent) {
+    if filename == "" {
+        return
+    }
     application.InfoDialog().
         SetTitle("File Opened").
         SetMessage("Application opened with file: " + filename).
         Show()
 })
🧰 Tools
🪛 Markdownlint

19-19: Column: 1
Hard tabs

(MD010, no-hard-tabs)


20-20: Column: 1
Hard tabs

(MD010, no-hard-tabs)

v3/examples/file-association/main.go (3)

13-19: Consider enhancing the documentation with file association details.

While the current documentation explains the embed functionality well, it would be helpful to add information about which file types are supported for association (e.g., .wails files) since this is a file association example.


51-60: Consider adding platform-specific window configurations for other operating systems.

While the MacOS window configuration is comprehensive, the example would benefit from showing window configurations for other platforms (Windows/Linux) to demonstrate cross-platform file association handling.


85-90: Consider more graceful error handling.

Using log.Fatal immediately terminates the program. Consider implementing more graceful shutdown procedures, especially for cleaning up resources and handling any pending file operations.

-if err != nil {
-    log.Fatal(err)
-}
+if err != nil {
+    log.Printf("Application error: %v", err)
+    // Perform cleanup if necessary
+    os.Exit(1)
+}
v3/examples/file-association/frontend/public/style.css (3)

18-23: Consider a more selective approach to user-select: none.

Applying user-select: none globally might impact accessibility and user experience. Consider applying it only to specific UI elements where text selection should be prevented (e.g., buttons, navigation items) while allowing text selection for content areas.

-* {
+.no-select {
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}

25-31: Optimize font loading strategy.

Consider enhancing the font loading performance and behavior:

  1. Add woff2 format which offers better compression
  2. Include font-display property to control font loading behavior
 @font-face {
     font-family: "Inter";
     font-style: normal;
     font-weight: 400;
+    font-display: swap;
     src: local(""),
-    url("./Inter-Medium.ttf") format("truetype");
+    url("./Inter-Medium.woff2") format("woff2"),
+    url("./Inter-Medium.ttf") format("truetype");
 }

120-133: Improve theme handling with CSS variables and transitions.

Consider enhancing the theme implementation:

  1. Use CSS variables for theme colors
  2. Add smooth transitions for theme switching
 :root {
+    --text-color: rgba(255, 255, 255, 0.87);
+    --bg-color: rgba(27, 38, 54, 1);
+    --link-hover-color: #535bf2;
+    --button-bg: transparent;
+    transition: all 0.3s ease;
 }

 @media (prefers-color-scheme: light) {
     :root {
-        color: #213547;
-        background-color: #ffffff;
+        --text-color: #213547;
+        --bg-color: #ffffff;
+        --link-hover-color: #747bff;
+        --button-bg: #f9f9f9;
     }
-
-    a:hover {
-        color: #747bff;
-    }
-
-    button {
-        background-color: #f9f9f9;
-    }
 }

+body {
+    color: var(--text-color);
+    background-color: var(--bg-color);
+}
+
+a:hover {
+    color: var(--link-hover-color);
+}
+
+button {
+    background-color: var(--button-bg);
+}
v3/internal/commands/build_assets/nsis/project.nsi.tmpl (1)

94-95: Consider adding logging for file association operations.

To improve troubleshooting capabilities, consider adding detailed logging for file association and unassociation operations. This would help diagnose issues if file associations don't work as expected.

Example enhancement:

    !insertmacro wails.associateFiles
+   DetailPrint "Registering file associations..."

    !insertmacro wails.unassociateFiles
+   DetailPrint "Removing file associations..."

Also applies to: 109-110

v3/examples/file-association/build/nsis/project.nsi (1)

99-112: Add user confirmation for data removal.

Consider adding a confirmation dialog before removing user data:

 Section "uninstall" 
     !insertmacro wails.setShellContext
 
+    MessageBox MB_YESNO|MB_ICONQUESTION "Would you like to remove all application data?" IDNO skip_data_removal
     RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath
+    skip_data_removal:
v3/internal/commands/build-assets.go (3)

37-39: Consider reducing duplication between options structs.

The UpdateBuildAssetsOptions duplicates all fields from BuildAssetsOptions. Consider using composition to reduce duplication and maintain consistency.

 type UpdateBuildAssetsOptions struct {
-    Dir                string
-    Name               string
-    BinaryName         string
-    ProductName        string
-    ProductDescription string
-    ProductVersion     string
-    ProductCompany     string
-    ProductCopyright   string
-    ProductComments    string
-    ProductIdentifier  string
+    BuildAssetsOptions
     Config             string
     Silent             bool
 }

Also applies to: 42-54


112-118: Add documentation for FileAssociation fields.

The Role field's purpose and valid values should be documented. Additionally, consider adding validation for the IconName field to ensure the icon file exists.

 type FileAssociation struct {
+    // Ext is the file extension to associate with (e.g., ".txt")
     Ext         string `yaml:"ext"`
+    // Name is the friendly name of the file type
     Name        string `yaml:"name"`
+    // Description appears in file type selection dialogs
     Description string `yaml:"description"`
+    // IconName is the name of the icon file in the assets directory
     IconName    string `yaml:"iconName"`
+    // Role specifies how the application handles this file type
     Role        string `yaml:"role"`
 }

136-145: Add config file path validation.

While error handling is good, consider validating the config file path before attempting to read it.

 if options.Config != "" {
+    if _, err := os.Stat(options.Config); os.IsNotExist(err) {
+        return fmt.Errorf("config file not found: %s", options.Config)
+    }
     bytes, err := os.ReadFile(options.Config)
     if err != nil {
         return err
     }
mkdocs-website/docs/en/learn/guides/file-associations.md (4)

18-24: Add prerequisite information for the configuration steps.

Consider adding a note about prerequisites before the configuration steps, such as:

  • Having Wails v3 installed
  • Having initialized a Wails v3 project
  • Location of the default build directory

28-40: Add validation information for configuration properties.

Consider adding information about:

  • Required vs optional properties
  • Valid values for the role property (e.g., what other roles besides Editor are supported?)
  • File extension format restrictions (e.g., max length, allowed characters)

132-133: Enhance testing instructions.

Consider adding more detailed testing instructions:

  • How to verify file associations are correctly registered
  • How to test file opening from different contexts (e.g., double-click, "Open with" menu)
  • Platform-specific testing considerations
  • Troubleshooting common issues

136-138: Fix list formatting and expand additional notes.

  1. Fix the unordered list indentation.
  2. Consider adding more details about:
  • Supported icon formats and sizes for each platform
  • Best practices for icon design
  • Installation verification steps
  • Uninstallation considerations
-• Icons should be provided in PNG format in the build folder
-• Testing file associations requires installing the packaged application
+- Icons should be provided in PNG format in the build folder
+- Testing file associations requires installing the packaged application
v3/pkg/application/application_darwin_delegate.m (1)

12-17: Consider adding event listener support for consistency.

While the implementation is functionally correct, it differs from the pattern used by other methods in the file. Other application events use the hasListeners check and processApplicationEvent pattern.

Consider refactoring to match the established pattern:

-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
    const char* utf8FileName = filename.UTF8String;
-   HandleOpenFile((char*)utf8FileName);
+   if (hasListeners(EventApplicationOpenFile)) {
+       NSString *filePath = [NSString stringWithUTF8String:utf8FileName];
+       processApplicationEvent(EventApplicationOpenFile, @{@"filename": filePath});
+   }
    return YES;
}
v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts (1)

192-192: Consider adding events for runtime file associations.

While ApplicationOpenedWithFile handles the initial file open scenario, consider adding events for file associations during runtime (e.g., when files are opened with the application while it's already running). This would provide a more complete file association feature.

Suggested additional events:

 Common: {
   // ... existing events ...
   ApplicationOpenedWithFile: string,
+  ApplicationFileOpened: string,         // For files opened while app is running
+  ApplicationFileAssociationChanged: string,  // For dynamic file association changes
 },
v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl (1)

181-217: Consider architectural improvements for robustness.

While the file association implementation is fundamentally sound, consider these architectural improvements:

  1. Add a validation phase before installation to check all required files exist.
  2. Implement rollback functionality in case of failures during association/unassociation.
  3. Consider logging all registry operations to aid in troubleshooting.

Would you like assistance in implementing any of these improvements?

v3/examples/file-association/build/nsis/wails_tools.nsh (3)

10-12: Consider improving default company name.

The default company name "My Company" might be confusing for users. Consider using a more descriptive default or requiring this value to be explicitly set.

-    !define INFO_COMPANYNAME "My Company"
+    !define INFO_COMPANYNAME "Unknown Company"

100-112: Add file existence validation.

The macro should validate that the binary files exist before attempting to copy them.

 !macro wails.files
     !ifdef SUPPORTS_AMD64
         ${if} ${IsNativeAMD64}
+            !tempfile BINARY_CHECK
+            !system 'if not exist "${ARG_WAILS_AMD64_BINARY}" echo !error "AMD64 binary not found: ${ARG_WAILS_AMD64_BINARY}" > "${BINARY_CHECK}"'
+            !include "${BINARY_CHECK}"
             File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}"
         ${EndIf}
     !endif

137-143: Add documentation for shell context settings.

Consider adding comments explaining the implications of different shell contexts for better maintainability.

 !macro wails.setShellContext
+    # Set shell context to 'all users' for admin installs
+    # or 'current user' for non-admin installs
     ${If} ${REQUEST_EXECUTION_LEVEL} == "admin"
         SetShellVarContext all
     ${else}
         SetShellVarContext current
     ${EndIf}
 !macroend
v3/pkg/application/application_options.go (2)

112-115: LGTM! Consider adding validation for file extensions.

The FileAssociations field is well-documented with a clear example. However, consider adding runtime validation to ensure:

  • Each extension starts with a '.'
  • No duplicate extensions
  • Valid characters in extensions

Example validation implementation:

// ValidateFileAssociations validates file extensions
func ValidateFileAssociations(extensions []string) error {
    seen := make(map[string]bool)
    for _, ext := range extensions {
        if !strings.HasPrefix(ext, ".") {
            return fmt.Errorf("file extension must start with '.': %s", ext)
        }
        if seen[ext] {
            return fmt.Errorf("duplicate file extension: %s", ext)
        }
        // Basic validation for valid characters
        if !regexp.MustCompile(`^\.[a-zA-Z0-9]+$`).MatchString(ext) {
            return fmt.Errorf("invalid characters in extension: %s", ext)
        }
        seen[ext] = true
    }
    return nil
}

112-115: Document platform-specific behaviors for file associations.

Since file associations can behave differently across platforms (Windows, macOS, Linux), consider expanding the documentation to cover:

  • Platform-specific file association mechanisms
  • Any limitations or special considerations per platform
  • How the associations are registered with the OS

Example documentation:

// FileAssociations defines the file extensions to associate with this application.
// Platform-specific behavior:
// - Windows: Registers associations in the Windows Registry
// - macOS: Updates the Info.plist CFBundleDocumentTypes
// - Linux: Updates the .desktop file's MimeType entry
// Example: [".txt", ".md"]
// Note: The '.' prefix is required for all extensions
v3/pkg/application/application_windows.go (1)

140-144: Remove debug print statements.

Debug print statements should be replaced with proper logging using the application's logging system.

-println("Checking args")
-println("Got extension: ", ext)
v3/pkg/application/dialogs_darwin.go (1)

32-34: Potential memory leak in icon handling

The NSImage created from the icon data is not being released. While ARC might handle this in modern macOS versions, it's good practice to be explicit about ownership.

Consider managing the image lifecycle:

if (icon != NULL) {
-    NSImage *image = [[NSImage alloc] initWithData:[NSData dataWithBytes:icon length:length]];
-    [alert setIcon:image];
+    @autoreleasepool {
+        NSImage *image = [[NSImage alloc] initWithData:[NSData dataWithBytes:icon length:length]];
+        [alert setIcon:image];
+    }
}
mkdocs-website/docs/en/changelog.md (1)

Line range hint 1-24: Consider enhancing the file association entry with more details.

While the current entry follows the changelog format, consider adding a brief description of the file association feature's key capabilities to help users understand its impact. For example:

-File Association support by [leaanthony](https://github.com/leaanthony) in [#3873](https://github.com/wailsapp/wails/pull/3873)
+File Association support - Enable applications to handle specific file types by [leaanthony](https://github.com/leaanthony) in [#3873](https://github.com/wailsapp/wails/pull/3873)

Also applies to: 24-500

v3/pkg/application/webview_window_darwin.go (1)

Line range hint 1251-1263: Consider setting window properties before showing the window.

The current implementation sets the shadow and always-on-top properties after making the window visible, which could potentially cause brief visual artifacts. While the impact is likely minimal due to the immediate execution, consider this alternative approach for a smoother visual experience:

-					w.parent.Show()
-					w.setHasShadow(!options.Mac.DisableShadow)
-					w.setAlwaysOnTop(options.AlwaysOnTop)
+					w.setHasShadow(!options.Mac.DisableShadow)
+					w.setAlwaysOnTop(options.AlwaysOnTop)
+					w.parent.Show()
v3/pkg/application/webview_window_windows.go (1)

Line range hint 1-1200: Consider breaking down the run() method

The run() method is quite long and handles multiple responsibilities including window creation, chromium setup, theme processing, and more. Consider breaking it down into smaller, focused methods for better maintainability.

Example refactor:

func (w *windowsWebviewWindow) run() {
    w.initializeWindow()
    w.setupChromium()
    w.configureWindowProperties()
    w.finalizeSetup()
}

+func (w *windowsWebviewWindow) initializeWindow() {
+    // Window creation and basic setup
+}

+func (w *windowsWebviewWindow) configureWindowProperties() {
+    // Theme, size constraints, etc.
+}

+func (w *windowsWebviewWindow) finalizeSetup() {
+    // Final visibility and update
+}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e4cfae2 and 8a2d39c.

⛔ Files ignored due to path filters (7)
  • v3/examples/file-association/build/appicon.png is excluded by !**/*.png
  • v3/examples/file-association/build/icon.ico is excluded by !**/*.ico
  • v3/examples/file-association/frontend/package-lock.json is excluded by !**/package-lock.json
  • v3/examples/file-association/frontend/public/Inter-Medium.ttf is excluded by !**/*.ttf
  • v3/examples/file-association/frontend/public/javascript.svg is excluded by !**/*.svg
  • v3/examples/file-association/frontend/public/wails.png is excluded by !**/*.png
  • v3/examples/file-association/go.sum is excluded by !**/*.sum
📒 Files selected for processing (56)
  • mkdocs-website/docs/en/API/application_dialogs.md (1 hunks)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • mkdocs-website/docs/en/learn/guides/file-associations.md (1 hunks)
  • mkdocs-website/docs/en/status.md (2 hunks)
  • mkdocs-website/mkdocs.yml (1 hunks)
  • v3/examples/file-association/.gitignore (1 hunks)
  • v3/examples/file-association/Inter Font License.txt (1 hunks)
  • v3/examples/file-association/README.md (1 hunks)
  • v3/examples/file-association/Taskfile.yml (1 hunks)
  • v3/examples/file-association/build/Info.dev.plist (1 hunks)
  • v3/examples/file-association/build/Info.plist (1 hunks)
  • v3/examples/file-association/build/Taskfile.common.yml (1 hunks)
  • v3/examples/file-association/build/Taskfile.darwin.yml (1 hunks)
  • v3/examples/file-association/build/Taskfile.linux.yml (1 hunks)
  • v3/examples/file-association/build/Taskfile.windows.yml (1 hunks)
  • v3/examples/file-association/build/appimage/build.sh (1 hunks)
  • v3/examples/file-association/build/config.yml (1 hunks)
  • v3/examples/file-association/build/devmode.config.yaml (1 hunks)
  • v3/examples/file-association/build/info.json (1 hunks)
  • v3/examples/file-association/build/nsis/project.nsi (1 hunks)
  • v3/examples/file-association/build/nsis/wails_tools.nsh (1 hunks)
  • v3/examples/file-association/build/wails.exe.manifest (1 hunks)
  • v3/examples/file-association/frontend/bindings/changeme/greetservice.js (1 hunks)
  • v3/examples/file-association/frontend/bindings/changeme/index.js (1 hunks)
  • v3/examples/file-association/frontend/index.html (1 hunks)
  • v3/examples/file-association/frontend/main.js (1 hunks)
  • v3/examples/file-association/frontend/package.json (1 hunks)
  • v3/examples/file-association/frontend/public/style.css (1 hunks)
  • v3/examples/file-association/go.mod (1 hunks)
  • v3/examples/file-association/greetservice.go (1 hunks)
  • v3/examples/file-association/main.go (1 hunks)
  • v3/examples/file-association/test.wails (1 hunks)
  • v3/internal/commands/build-assets.go (6 hunks)
  • v3/internal/commands/build_assets/Taskfile.common.yml (1 hunks)
  • v3/internal/commands/build_assets/appdata.tmpl.yaml (0 hunks)
  • v3/internal/commands/build_assets/config.yml (1 hunks)
  • v3/internal/commands/build_assets/nsis/project.nsi.tmpl (2 hunks)
  • v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl (1 hunks)
  • v3/internal/commands/updatable_build_assets/Info.plist.tmpl (1 hunks)
  • v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl (1 hunks)
  • v3/internal/runtime/desktop/@wailsio/runtime/package.json (1 hunks)
  • v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js (1 hunks)
  • v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts (1 hunks)
  • v3/pkg/application/application_darwin.go (1 hunks)
  • v3/pkg/application/application_darwin_delegate.h (1 hunks)
  • v3/pkg/application/application_darwin_delegate.m (1 hunks)
  • v3/pkg/application/application_options.go (1 hunks)
  • v3/pkg/application/application_windows.go (2 hunks)
  • v3/pkg/application/context_application_event.go (2 hunks)
  • v3/pkg/application/dialogs_darwin.go (1 hunks)
  • v3/pkg/application/webview_window_darwin.go (1 hunks)
  • v3/pkg/application/webview_window_windows.go (1 hunks)
  • v3/pkg/events/events.go (4 hunks)
  • v3/pkg/events/events.txt (1 hunks)
  • v3/tasks/events/generate.go (2 hunks)
  • v3/tasks/events/go.mod (1 hunks)
💤 Files with no reviewable changes (1)
  • v3/internal/commands/build_assets/appdata.tmpl.yaml
✅ Files skipped from review due to trivial changes (12)
  • v3/examples/file-association/.gitignore
  • v3/examples/file-association/build/Info.dev.plist
  • v3/examples/file-association/build/Info.plist
  • v3/examples/file-association/build/info.json
  • v3/examples/file-association/build/wails.exe.manifest
  • v3/examples/file-association/frontend/bindings/changeme/greetservice.js
  • v3/examples/file-association/frontend/bindings/changeme/index.js
  • v3/examples/file-association/frontend/index.html
  • v3/examples/file-association/frontend/package.json
  • v3/examples/file-association/test.wails
  • v3/internal/runtime/desktop/@wailsio/runtime/package.json
  • v3/tasks/events/go.mod
🧰 Additional context used
🪛 LanguageTool
mkdocs-website/docs/en/API/application_dialogs.md

[grammar] ~2-~2: The operating system from Apple is written “macOS”.
Context: !!! warning "MacOS Dialogs and Application Lifecycle" ...

(MAC_OS)

v3/examples/file-association/Inter Font License.txt

[typographical] ~9-~9: If you want to indicate numerical ranges or time ranges, consider using an en dash.
Context: ...------ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 -----------------------...

(DASH_RULE)

🪛 Markdownlint
mkdocs-website/docs/en/API/application_dialogs.md

19-19: Column: 1
Hard tabs

(MD010, no-hard-tabs)


20-20: Column: 1
Hard tabs

(MD010, no-hard-tabs)

mkdocs-website/docs/en/learn/guides/file-associations.md

79-79: Expected: 0; Actual: 3
Unordered list indentation

(MD007, ul-indent)


80-80: Expected: 0; Actual: 3
Unordered list indentation

(MD007, ul-indent)


81-81: Expected: 0; Actual: 3
Unordered list indentation

(MD007, ul-indent)


59-59: Column: 1
Hard tabs

(MD010, no-hard-tabs)


60-60: Column: 1
Hard tabs

(MD010, no-hard-tabs)


62-62: Column: 1
Hard tabs

(MD010, no-hard-tabs)


63-63: Column: 1
Hard tabs

(MD010, no-hard-tabs)


64-64: Column: 1
Hard tabs

(MD010, no-hard-tabs)


66-66: Column: 1
Hard tabs

(MD010, no-hard-tabs)


67-67: Column: 1
Hard tabs

(MD010, no-hard-tabs)


68-68: Column: 1
Hard tabs

(MD010, no-hard-tabs)


69-69: Column: 1
Hard tabs

(MD010, no-hard-tabs)


114-114: Column: 1
Hard tabs

(MD010, no-hard-tabs)


115-115: Column: 1
Hard tabs

(MD010, no-hard-tabs)


116-116: Column: 1
Hard tabs

(MD010, no-hard-tabs)


121-121: Expected: fenced; Actual: indented
Code block style

(MD046, code-block-style)

v3/examples/file-association/README.md

4-4: null
Bare URL used

(MD034, no-bare-urls)

🪛 yamllint
v3/examples/file-association/build/Taskfile.common.yml

[error] 75-75: no new line character at the end of file

(new-line-at-end-of-file)

v3/examples/file-association/build/Taskfile.windows.yml

[error] 52-52: no new line character at the end of file

(new-line-at-end-of-file)

v3/examples/file-association/build/config.yml

[error] 32-32: no new line character at the end of file

(new-line-at-end-of-file)

v3/internal/commands/build_assets/Taskfile.common.yml

[error] 75-75: no new line character at the end of file

(new-line-at-end-of-file)

v3/internal/commands/build_assets/config.yml

[error] 32-32: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (63)
v3/pkg/application/application_darwin_delegate.h (1)

8-8: Verify the impact of changing the base class to NSResponder.

The change from NSObject to NSResponder is appropriate for handling file open events, but this could potentially affect existing applications.

Let's verify the impact:

✅ Verification successful

Let's gather more information about the implementations to understand the impact better.


Let's check the implementation file to fully understand the impact.


Base class change from NSObject to NSResponder is safe and consistent with existing implementation

The verification shows that:

  1. The v2 implementation already uses NSResponder as the base class
  2. The change in v3 is actually maintaining compatibility with v2, not introducing a breaking change
  3. The implementation properly uses NSResponder features for event handling, particularly for file open events
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any custom implementations or extensions of AppDelegate
# that might be affected by the base class change
rg -l "AppDelegate.*:" --type objc

Length of output: 135


Script:

#!/bin/bash
# Check the content of both files to compare implementations
echo "=== v3 AppDelegate Implementation ==="
cat v3/pkg/application/application_darwin_delegate.h

echo -e "\n=== v2 AppDelegate Implementation ==="
cat v2/internal/frontend/desktop/darwin/AppDelegate.h

# Also check for any implementation files (.m)
echo -e "\n=== Implementation files ==="
fd -e m "AppDelegate"

Length of output: 1497


Script:

#!/bin/bash
# Check the v2 implementation to understand how NSResponder is used
cat v2/internal/frontend/desktop/darwin/AppDelegate.m

# Also search for any references to AppDelegate methods in the codebase
rg "AppDelegate.*\]" --type objc -A 2

Length of output: 2998

v3/examples/file-association/README.md (1)

1-3: LGTM!

The title and introduction clearly communicate the purpose of the sample project.

v3/examples/file-association/frontend/main.js (1)

1-2: Verify the import path for bindings

The import path contains a placeholder "changeme" which might need to be updated to the correct package name.

✅ Verification successful

The import path "./bindings/changeme" is correct and valid

The import path is actually correct as the file exists at the expected location and exports the GreetService as required. The "changeme" directory appears to be intentional as it contains the auto-generated bindings with proper exports.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the import path exists and verify its structure
fd --type f "index.js" --exec grep -l "GreetService" {}

Length of output: 14575


Script:

#!/bin/bash
# Let's check the content of the bindings/changeme/index.js file to verify if it's a valid binding
cat v3/examples/file-association/frontend/bindings/changeme/index.js

Length of output: 276

v3/examples/file-association/build/devmode.config.yaml (2)

1-28: Verify integration with file association features.

As this is part of the file association example, we should ensure this development configuration properly supports file association testing.

Let's check for file association configurations in the example:

✅ Verification successful

Development configuration aligns with file association implementation

The development configuration (devmode.config.yaml) is correctly set up to support file association testing:

  • It properly watches Go files for changes (*.go in watched_extension)
  • The execution chain includes all necessary build and run commands
  • The main configuration file (config.yml) in the same directory confirms file association support with proper configuration for .wails files
  • The development mode will properly rebuild and reload the application when file association related code changes are made

The configuration is sufficient for developing and testing file association features in this example project.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify file association configuration presence and structure
# Expected: Find file association configurations and related build settings

# Check for file association configurations in build directory
echo "Checking for file association configurations..."
rg -l "file.*association" build/

# Look for related build settings
echo "Checking for build settings..."
rg -l "build.*assets" .

# Check for platform-specific file association implementations
echo "Checking for platform-specific implementations..."
rg -l "RegisterFileAssociation|HandleFileOpen" .

Length of output: 11924


Script:

#!/bin/bash
# Let's check the file association example directory structure and configuration files

# Check the example's directory structure
echo "File Association Example Structure:"
fd . v3/examples/file-association/

# Check the main configuration file
echo -e "\nMain Configuration File:"
cat v3/examples/file-association/build/config.yml

# Check for file association related code in the example
echo -e "\nSearching for file association related code:"
rg -l "fileAssociation|HandleFile" v3/examples/file-association/

Length of output: 3561


5-17: Verify file watching configuration for file association example.

The current configuration only watches .go files, but for a file association example, we might need to watch additional file types:

  • Frontend changes might be relevant for file handling UI
  • File association configuration files might have different extensions

Let's check what file types are actually used in this example:

✅ Verification successful

Let me gather more information about the actual file types used in this example.

This will help us understand:

  1. All file types actually used in the example
  2. Any code files that handle file associations to determine relevant file types to watch

Let me check the specific files in the file-association example to understand what file types are actually used.

This will help us understand what file types are actually used in this example and what the example is meant to demonstrate.


Current file watching configuration is appropriate for this example

The current configuration watching only .go files is actually correct for this example because:

  • The example demonstrates file association functionality where the app handles .wails files (as shown by test.wails in the example)
  • The file association is configured through build configuration files (.yaml, .yml, .json) which are correctly excluded as they are build-time configurations
  • Frontend files are correctly ignored as they are handled by the frontend build process
  • The core functionality for handling associated files is implemented in the Go files, which are properly watched
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check what file types are used in the example
# Expected: Find files that might need to be watched for the file association example

# Look for potential file association configuration files
fd -e yaml -e json -e toml . | grep -i "assoc"

# Check frontend file types that might need watching
fd . frontend/ -t f 2>/dev/null || echo "Frontend directory not found"

Length of output: 342


Script:

#!/bin/bash
# Check all file types in the file-association example directory
fd . v3/examples/file-association/ -t f -x file {} | sort

# Check if there are any file association related code files
rg -l "fileAssociation|file.*association" -g "!*.{json,yaml}" -A 3

Length of output: 9553


Script:

#!/bin/bash
# List all files in the file-association example directory
fd . v3/examples/file-association/ -t f

# Check the README for any mentions of file types
cat v3/examples/file-association/README.md

Length of output: 2308

v3/examples/file-association/Taskfile.yml (3)

14-29: LGTM! Cross-platform task delegation is well structured.

The build, package, and run tasks are properly delegated to OS-specific implementations using the {{OS}} variable, ensuring consistent behavior across platforms.


1-7: Verify the existence of referenced task files.

The configuration references several task files that should exist in the ./build directory.

#!/bin/bash
# Description: Verify that all referenced task files exist
# Expected: All task files should be present in the build directory

echo "Checking for referenced task files..."
for file in "Taskfile.common.yml" "Taskfile.windows.yml" "Taskfile.darwin.yml" "Taskfile.linux.yml"; do
  if fd -p "build/$file$" v3/examples/file-association/; then
    echo "✓ Found $file"
  else
    echo "✗ Missing $file"
  fi
done

30-33: Verify the devmode config file existence and port configuration.

The dev task references a specific config file and uses the VITE_PORT variable.

✅ Verification successful

Configuration files and port settings are properly set up

The verification shows that:

  • The devmode.config.yaml exists and contains valid configuration
  • VITE_PORT is properly defined in Taskfile.yml with a default value of 9245
  • The port configuration is correctly used in both the dev task and frontend tasks
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the devmode config file exists and check its content
# Expected: Config file should exist and contain valid configuration

echo "Checking for devmode config file..."
if fd -p "build/devmode\.config\.yaml$" v3/examples/file-association/; then
  echo "✓ Found devmode.config.yaml"
  echo "Checking config content..."
  cat v3/examples/file-association/build/devmode.config.yaml
else
  echo "✗ Missing devmode.config.yaml"
fi

Length of output: 1529


Script:

#!/bin/bash
# Let's verify the devmode config file and VITE_PORT variable in a more focused way

# Check for devmode.config.yaml
echo "Checking for devmode config file..."
fd -p "devmode\.config\.yaml$" v3/examples/file-association/

# Check for VITE_PORT variable in any relevant files
echo -e "\nChecking for VITE_PORT variable definition..."
rg "VITE_PORT" v3/examples/file-association/ -A 2

# Check for any other config files that might contain port configuration
echo -e "\nChecking for other config files with port configuration..."
rg "port:" v3/examples/file-association/ --type yaml -A 2

Length of output: 1102


Script:

#!/bin/bash
# Let's check the content of the devmode.config.yaml file since we found it exists

echo "Checking devmode.config.yaml content..."
cat v3/examples/file-association/build/devmode.config.yaml

# Also check the default port value in any environment files
echo -e "\nChecking for default port configurations..."
rg "WAILS_VITE_PORT" v3/examples/file-association/ -A 2

Length of output: 1044

v3/internal/commands/updatable_build_assets/Info.plist.tmpl (1)

9-9: LGTM! Variable rename improves clarity.

The change from {{.Binary}} to {{.BinaryName}} makes the template variable more descriptive and aligns with the broader restructuring of build configurations.

Let's verify that this template variable is consistently used across the codebase:

✅ Verification successful

Based on the search results, I can now generate the final response:

Template variable change is consistently used across the codebase

The change from {{.Binary}} to {{.BinaryName}} is consistently implemented. The search results show:

  • No instances of the old {{.Binary}} template variable remain in the codebase
  • The new {{.BinaryName}} is used in both Info.plist templates:
    • v3/internal/commands/updatable_build_assets/Info.plist.tmpl
    • v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl
  • The variable is also consistently used in various wails.tmpl.json files across different templates
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of the old Binary template variable
# and confirm consistent usage of the new BinaryName variable in template files

# Test 1: Check for any remaining instances of the old Binary template variable
echo "Checking for old Binary template variable..."
rg '{{\.Binary}}' 

# Test 2: Verify consistent usage of new BinaryName template variable
echo "Verifying usage of new BinaryName template variable..."
rg '{{\.BinaryName}}'

Length of output: 441


Script:

#!/bin/bash
# Description: Check for template variables with proper regex escaping
# and confirm consistent usage across the codebase

# Test 1: Check for any remaining instances of the old Binary template variable
echo "Checking for old Binary template variable..."
rg '\{\{\.Binary\}\}'

# Test 2: Verify consistent usage of new BinaryName template variable
echo "Verifying usage of new BinaryName template variable..."
rg '\{\{\.BinaryName\}\}'

# Test 3: Check all template files for context
echo "Checking all template files..."
fd -e tmpl -x cat {}

Length of output: 74890

v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl (1)

9-9: LGTM! Verify template consistency across the codebase.

The change from {{.Binary}} to {{.BinaryName}} aligns with the broader restructuring of configuration options.

Let's verify if all plist templates are consistently using the new variable name:

✅ Verification successful

Template variable change is consistent and correct

The verification shows that the change from {{.Binary}} to {{.BinaryName}} in Info.dev.plist.tmpl is correct and consistent with the codebase structure:

  • The new {{.BinaryName}} variable is used consistently in v3's template files under internal/commands/updatable_build_assets/
  • Other v3 template files use similar naming patterns (e.g., {{.ProjectName}} in base templates)
  • No instances of the old {{.Binary}} variable were found in any plist templates
  • The change aligns with the v3 codebase's template variable naming conventions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of the old Binary variable
# and ensure BinaryName is used consistently across plist templates

# Search for any remaining instances of the old Binary variable in plist templates
rg -l '{{.Binary}}' --glob '*.plist*'

# Show usage of the new BinaryName variable in plist templates for context
rg -l '{{.BinaryName}}' --glob '*.plist*'

Length of output: 1278


Script:

#!/bin/bash
# Let's try a different approach to search for template variables in plist files

# Search for any plist template files first
fd -e plist.tmpl -e plist

# Then examine their content focusing on CFBundleExecutable sections
rg -A 2 -B 2 'CFBundleExecutable' --glob '*.plist*'

# Also search for any template variables with proper escaping
rg '\{\{\..*?\}\}' --glob '*.plist*'

Length of output: 14363

mkdocs-website/docs/en/status.md (1)

3-3: Version update aligns with feature additions.

The increment from Alpha 6 to Alpha 7 appropriately reflects the ongoing development progress, particularly with the addition of file association support as mentioned in the PR objectives.

v3/examples/file-association/build/Taskfile.darwin.yml (3)

1-5: LGTM! Good separation of concerns.

The file structure follows Task best practices by separating common tasks into a separate file.


7-25: Verify minimum macOS version compatibility.

The build configuration sets macOS 10.15 as the minimum deployment target. Ensure this aligns with the project's compatibility requirements and user base needs.

Consider adding code signing configuration.

For macOS applications, especially those with file associations, code signing is crucial for proper functionality and security. Consider adding code signing steps to the build process.

Example addition:

 BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
+SIGN_FLAGS: '--sign "Developer ID Application: Your Name (TEAM_ID)" --options runtime'

26-34: LGTM! Good task organization.

The package task correctly ensures a production build before creating the app bundle.

v3/pkg/application/context_application_event.go (1)

59-73: Verify consistent usage of file association events.

The implementation looks good but let's verify the usage patterns across the codebase to ensure consistency.

✅ Verification successful

Based on the shell script results, I can now provide a final response:

File association implementation is correctly used across the codebase

The implementation aligns well with the codebase usage patterns:

  • Consistent event handling in platform-specific code (Darwin, Windows)
  • Proper event type registration in the events package
  • Documented usage in examples and guides
  • No direct access to the internal data map, ensuring proper encapsulation
  • Consistent usage pattern through event.Context().Filename() in consumer code
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage patterns of file association methods

# Check for event handling implementations
echo "Checking event handling implementations..."
rg -A 5 "ApplicationOpenedWithFile|setOpenedWithFile|Filename\(\)"

# Check for potential direct access to the filename constant
echo "Checking for direct data map access..."
rg "data\[\"filename\"\]|data\['filename'\]"

Length of output: 5869

v3/examples/file-association/build/Taskfile.windows.yml (3)

1-5: LGTM! Well-structured task organization.

Good practice using task includes for common functionality, promoting code reuse and maintainability.


29-36: LGTM! Well-configured Windows resource generation.

The task correctly generates the Windows resource file with all necessary components (icon, manifest, and info).


7-23: Verify CGO requirements for file associations.

The build configuration looks solid, but setting CGO_ENABLED=0 might affect file association functionality on Windows. Some Windows API calls might require CGO.

Let's verify if any CGO-dependent code is used:

v3/internal/commands/build_assets/Taskfile.common.yml (1)

69-70: LGTM: Well-structured Vite development server configuration.

The command correctly uses the --strictPort flag to ensure consistent port binding, which is important for reliable development workflow.

v3/examples/file-association/build/Taskfile.common.yml (1)

1-3: LGTM: File structure and version specification are correct.

v3/examples/file-association/build/Taskfile.linux.yml (3)

1-5: LGTM! Good use of task composition.

The file structure follows best practices by including common tasks from a shared file, promoting code reuse.


51-63: Make desktop file generation more configurable.

Consider these improvements:

  1. Make categories configurable via variables instead of hardcoding "Development"
  2. Add validation for icon file existence
  3. Consider supporting additional .desktop file fields (MimeType, etc.) for file associations

7-22: Verify build configuration and enhance documentation.

While the build task is well-structured, consider the following improvements:

  1. Document why CGO_ENABLED=1 is required
  2. Specify the default ARCH value in the task description
  3. Consider documenting the implications of -trimpath in production builds
✅ Verification successful

Let me analyze the results and generate additional verification scripts to better understand the CGO usage and architecture-specific requirements.

The first script will help understand why CGO is needed on Linux, the second will show architecture-specific build configurations, and the third will look for any existing documentation about CGO requirements.


Based on the results from the shell scripts, I can now provide a complete analysis of the build configuration:

CGO and architecture configuration documented

  1. CGO_ENABLED=1 is required for Linux builds as it uses GTK and WebKit bindings for the native UI components
  2. ARCH parameter is properly handled with a default fallback
  3. -trimpath is used in production builds for better security

The build configuration is well-structured and the CGO requirement is justified by the GTK/WebKit dependencies shown in the Linux-specific files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if any C dependencies are actually used in the project
rg -l 'import "C"'

# Verify architecture-specific code
rg -l 'GOARCH|386|amd64|arm64'

Length of output: 39038


Script:

#!/bin/bash
# Check for CGO dependencies in Linux-specific files
rg -l "import \"C\"" | grep -i "linux" | xargs rg -l "gtk|webkit|x11|xcb"

# Check for architecture-specific code in build files
rg -l "GOARCH|386|amd64|arm64" | grep -i "build" | xargs cat

# Look for documentation about CGO requirements
rg -i "cgo.*required|cgo.*needed" 

Length of output: 185729

v3/examples/file-association/go.mod (4)

7-8: LGTM!

The Wails v3 dependency is correctly specified with an appropriate alpha version for development.


9-50: LGTM!

The indirect dependencies are well-structured with pinned versions, covering all necessary functionality for file associations including crypto, file handling, and UI operations.


52-52: LGTM!

The replace directive correctly points to the local Wails v3 development path, which is appropriate for an example within the repository.


1-5: Consider version consistency and module naming.

  1. There's a mismatch between the Go version (1.22.4) and toolchain version (1.23.0). Consider aligning these versions.
  2. The module name "changeme" appears to be a placeholder. While this might be intentional for an example, consider documenting that users should replace this with their own module name.
mkdocs-website/docs/en/API/application_dialogs.md (1)

4-13: LGTM! Clear explanation with helpful code example.

The warning effectively communicates an important configuration requirement for macOS applications, and the code example clearly demonstrates the proper implementation.

v3/examples/file-association/main.go (2)

3-12: LGTM: Imports are appropriate and well-organized.

The imports include all necessary packages for file association functionality, event handling, and frontend asset embedding.


31-44: Verify GreetService implementation and consider documenting supported file types.

  1. The code references GreetService but its implementation isn't visible in the current context.
  2. The file association is limited to ".wails" files. Consider documenting whether this is intentional or if it should support multiple file types.
✅ Verification successful

Let me gather more information about the GreetService implementation in the file-association example and the file association documentation.


GreetService implementation and file associations are properly configured

The implementation is correct and well-documented:

  1. The GreetService in greetservice.go is properly implemented with a Greet method.
  2. The single .wails file association is intentional as this is an example application demonstrating the feature.
  3. The documentation clearly explains that file associations need to be configured both in config.yml and application options, which is followed in this example.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for GreetService implementation
ast-grep --pattern 'type GreetService struct {
  $$$
}'

# Check for any other file association examples
rg -l "FileAssociations.*\[.*\].*string"

Length of output: 6505


Script:

#!/bin/bash
# Check GreetService implementation in the file-association example
cat v3/examples/file-association/greetservice.go

# Check file association documentation
cat mkdocs-website/docs/en/learn/guides/file-associations.md

# Check application options definition for FileAssociations
cat v3/pkg/application/application_options.go | grep -A 5 "FileAssociations"

Length of output: 5268

v3/internal/commands/build_assets/nsis/project.nsi.tmpl (2)

109-110: Verify the wails.unassociateFiles macro implementation.

The placement of the unassociation macro is correct, being called during cleanup but before removing the uninstaller. This ensures proper cleanup of file associations during uninstallation.

✅ Verification successful

The wails.unassociateFiles macro implementation is correct and properly handles file association cleanup

The macro implementation in wails_tools.nsh.tmpl correctly:

  • Iterates through all registered file associations using the template range construct
  • Uses APP_UNASSOCIATE macro to remove each file association from the registry
  • Cleans up associated icon files from the installation directory

The placement in the uninstall section of project.nsi.tmpl is appropriate, ensuring file associations are removed before the final uninstaller cleanup.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the wails.unassociateFiles macro implementation
# Look for the macro definition in wails_tools.nsh
rg -A 10 "macro wails.unassociateFiles"

Length of output: 3341


94-95: Verify the wails.associateFiles macro implementation.

The placement of the file association macro is correct, being called after file installation but before writing the uninstaller. However, we should verify the implementation of this macro.

✅ Verification successful

The wails.associateFiles macro implementation is correctly ported from v2 to v3

The macro implementation in v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl correctly:

  • Creates file associations using the APP_ASSOCIATE macro
  • Iterates over FileAssociations to set up each association
  • Copies the required icon files
  • Maintains the same functionality as the v2 implementation

The placement in the installation section is also correct, being called after file installation but before writing the uninstaller.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the wails.associateFiles macro implementation
# Look for the macro definition in wails_tools.nsh
rg -A 10 "macro wails.associateFiles" 

Length of output: 5803

v3/pkg/events/events.txt (1)

183-183: LGTM! Consider platform-specific variants if needed.

The new ApplicationOpenedWithFile event under the common namespace is well-placed for cross-platform file association support. The naming is clear and follows conventions.

Let's verify there are no similar existing events and check if platform-specific variants exist:

✅ Verification successful

Event implementation is consistent across platforms

The ApplicationOpenedWithFile event is:

  • Properly defined in events.go with a unique ID (1206)
  • Consistently implemented in both Darwin and Windows platforms
  • No duplicate or conflicting events found (only related but distinct events like WindowFilesDropped exist)
  • Appropriately categorized under common as it's implemented cross-platform
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for similar file-related events and platform-specific variants

# Test 1: Search for similar file-related events
echo "Checking for similar file-related events:"
rg -i "file|open" v3/pkg/events/events.txt

# Test 2: Check if platform-specific variants exist in other files
echo "Checking for platform-specific variants in implementation files:"
rg -l "ApplicationOpenedWithFile" v3/pkg/

Length of output: 701


Script:

#!/bin/bash
# Let's examine the implementation in platform-specific files to ensure consistency

echo "Checking Darwin implementation:"
rg -C 5 "ApplicationOpenedWithFile" v3/pkg/application/application_darwin.go

echo -e "\nChecking Windows implementation:"
rg -C 5 "ApplicationOpenedWithFile" v3/pkg/application/application_windows.go

echo -e "\nChecking event definition:"
rg -C 2 "ApplicationOpenedWithFile" v3/pkg/events/events.go

Length of output: 1383

mkdocs-website/mkdocs.yml (1)

153-153: LGTM! Documentation entry is well-structured.

The new entry for File Associations guide is correctly placed under the Guides section and follows the established documentation structure.

Let's verify that the referenced guide file exists:

✅ Verification successful

✓ File association guide exists at the expected location

The referenced documentation file file-associations.md exists at the correct path under mkdocs-website/docs/en/learn/guides/, confirming that the navigation entry in mkdocs.yml is valid.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence of the file associations guide
# Expected: The guide file should exist at the specified path

fd "file-associations.md" mkdocs-website/docs/en/learn/guides/

Length of output: 119

v3/examples/file-association/build/nsis/project.nsi (4)

1-50: LGTM! Well-structured configuration with proper documentation.

The configuration section follows Windows installer best practices:

  • Unicode support enabled for proper character handling
  • Comprehensive documentation for manual debugging
  • Proper version information structure (4-part version)
  • HiDPI support enabled for modern displays

73-77: LGTM! Installation setup follows Windows conventions.

Good practices implemented:

  • Proper Program Files installation path
  • Architecture-specific installer naming
  • Visible installation details for troubleshooting

78-81: LGTM! Proper architecture validation.

The architecture check in .onInit prevents installation of wrong architecture builds.


51-68: Consider adding EULA for file association feature.

Since this installer handles file associations which integrate deeply with the Windows system, consider uncommenting and implementing the EULA page to inform users about:

  • File types being associated
  • System integration implications
  • Usage terms and conditions
v3/internal/commands/build-assets.go (4)

26-26: LGTM! Improved field naming.

The rename from Binary to BinaryName makes the field's purpose more explicit and self-documenting.


84-88: LGTM! Proper platform-specific binary naming.

The code correctly handles Windows-specific .exe extension while maintaining platform independence for other OS.


91-92: LGTM! Clean config initialization and extraction.

The configuration handling is well-structured with proper error checking.

Also applies to: 101-109


160-162: LGTM! Clean config update and extraction.

The configuration update and extraction process is well-structured.

v3/pkg/application/application_darwin_delegate.m (1)

14-15: Verify memory management of UTF8String conversion.

The UTF8String method returns a C string that's valid only as long as the NSString exists. Since we're passing this to an external function, we should ensure proper memory handling.

✅ Verification successful

Memory management is correctly handled in this case

The implementation is safe because:

  1. The HandleOpenFile Go function immediately converts the C string to a Go string using C.GoString(), which creates a copy of the data
  2. The original NSString and its UTF8String remain valid throughout the Objective-C method call
  3. The conversion and handling happen synchronously within the scope of the application:openFile: method
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for HandleOpenFile implementation to verify string handling
ast-grep --pattern 'void HandleOpenFile(char* filename) {
  $$$
}'

Length of output: 68


Script:

#!/bin/bash
# Search for HandleOpenFile function declaration and implementation using ripgrep
rg -l "HandleOpenFile" --type cpp --type c --type objc

# Then get the content of files containing HandleOpenFile
rg "HandleOpenFile" -B 3 -A 10 --type cpp --type c --type objc

Length of output: 3966


Script:

#!/bin/bash
# Let's search for the actual implementation of HandleOpenFile in C/C++ files
# since we only found declarations and calls so far
rg -g '*.{c,cpp}' "HandleOpenFile" -B 3 -A 10

# Also search for any Go files that might implement this function
# since it appears to be a bridge between Objective-C and another language
rg -g '*.go' "HandleOpenFile" -B 3 -A 10

Length of output: 2096

v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl (1)

204-210: Validate icon files and use absolute paths.

The current implementation has potential issues:

  1. No validation that icon files exist.
  2. Uses relative path "../" which could be unreliable.

Let's verify the icon file handling in the codebase:

v3/examples/file-association/build/nsis/wails_tools.nsh (3)

58-98: LGTM! Robust architecture validation.

The architecture check macro implements comprehensive validation with proper error handling for both silent and interactive installations.


114-135: LGTM! Comprehensive uninstaller setup.

The uninstaller management follows Windows best practices with proper registry handling and cleanup.


145-179: Verify WebView2 bootstrapper integrity.

Consider adding checksum verification for the WebView2 bootstrapper to ensure its integrity.

v3/pkg/application/application_darwin.go (1)

374-377: Verify event handling setup.

The event emission looks correct, but we should verify:

  1. The events.Common.ApplicationOpenedWithFile event type is registered
  2. Event consumers are properly set up to handle this event

Let's verify the event setup:

✅ Verification successful

Let me gather more information to verify the event type definition since it wasn't found in the previous search.


Event handling is properly set up and integrated

The verification shows:

  • The event type ApplicationOpenedWithFile is properly registered in v3/pkg/events/events.go with ID 1206
  • Event consumers are correctly set up as demonstrated in the file association examples
  • The event is properly documented in the guides and API documentation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify event registration and handling

# Test 1: Check if the event type is defined
rg -A 2 "ApplicationOpenedWithFile.*=" 

# Test 2: Check for event handlers
rg -A 5 "OnApplicationEvent.*ApplicationOpenedWithFile"

Length of output: 1825


Script:

#!/bin/bash
# Search for ApplicationOpenedWithFile in events package
rg -A 2 "ApplicationOpenedWithFile" v3/pkg/events/

# Search for event type registration in Common
ast-grep --pattern 'type Common struct {
  $$$
  ApplicationOpenedWithFile $_
  $$$
}'

Length of output: 534

v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js (2)

192-192: Verify consistent implementation across platforms.

Since this is a common event, ensure it's properly implemented and emitted on all supported platforms (Windows, macOS, Linux).

Let's check the implementation across platforms:

#!/bin/bash
# Description: Verify consistent implementation across platforms
# Expected: Implementation should exist for each platform

# Search for ApplicationOpenedWithFile usage in platform-specific files
echo "=== Windows Implementation ==="
rg "ApplicationOpenedWithFile" "**/*_windows.go"

echo "=== macOS Implementation ==="
rg "ApplicationOpenedWithFile" "**/*_darwin.go"

echo "=== Linux Implementation ==="
rg "ApplicationOpenedWithFile" "**/*_linux.go"

192-192: LGTM! Verify documentation coverage.

The new ApplicationOpenedWithFile event follows the established naming convention and is appropriately placed in the Common section for cross-platform support.

Let's verify the documentation coverage:

✅ Verification successful

Documentation coverage for ApplicationOpenedWithFile event is complete

The ApplicationOpenedWithFile event is well documented in both the file associations guide and example implementation:

  • Comprehensive documentation in mkdocs-website/docs/en/learn/guides/file-associations.md
  • Working example in v3/examples/file-association/main.go
  • Additional notes about dialog handling in mkdocs-website/docs/en/API/application_dialogs.md

The documentation covers:

  • Event usage and implementation
  • Configuration requirements
  • Platform-specific considerations
  • Best practices for handling the event
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the new event is properly documented
# Expected: Documentation should exist for the ApplicationOpenedWithFile event

# Search in markdown documentation
rg -i "ApplicationOpenedWithFile" "docs/"

# Search in API documentation
rg -i "ApplicationOpenedWithFile" "**/*.md"

Length of output: 513


Script:

#!/bin/bash
# Let's try a broader search for documentation and implementation
# First, find all potential documentation files
echo "=== Documentation files ==="
fd -e md

# Then search for the event in all files
echo -e "\n=== Implementation search ==="
rg -l "ApplicationOpenedWithFile"

# Look for any Go files that might contain the implementation
echo -e "\n=== Go files with 'file' related functionality ==="
fd -e go | grep -i "file"

Length of output: 8704


Script:

#!/bin/bash
# Let's check the content of the file associations documentation and implementation
echo "=== File Associations Documentation ==="
cat "mkdocs-website/docs/en/learn/guides/file-associations.md"

echo -e "\n=== Event Documentation ==="
cat "mkdocs-website/docs/en/API/application_dialogs.md"

echo -e "\n=== Example Implementation ==="
cat "v3/examples/file-association/main.go"

Length of output: 11087

v3/pkg/application/application_windows.go (2)

7-9: LGTM: Imports are appropriate for file association handling.

The new imports are necessary and well-organized, supporting the file association feature implementation.


141-156: Verify the impact on the application startup time.

The file existence check might impact the application's startup performance. Consider:

  1. Making the file validation asynchronous
  2. Adding a timeout for the file check
v3/pkg/application/dialogs_darwin.go (1)

22-36: Verify main thread execution for NSAlert operations

The removal of dispatch_async block assumes that this code is already running on the main thread. While this might be true due to the InvokeAsync wrapper in Go code, it's crucial to ensure thread safety as UI operations in Cocoa must run on the main thread.

Let's verify the execution context:

Consider adding a runtime assertion to verify main thread execution:

static void showAboutBox(char* title, char *message, void *icon, int length) {
+    // Assert main thread
+    NSCAssert([NSThread isMainThread], @"showAboutBox must be called on main thread");

    NSAlert *alert = [[NSAlert alloc] init];
    // ... rest of the implementation
}
✅ Verification successful

Let me gather more information about the main thread dispatch mechanism.


Based on the gathered information, I can now provide the final response:

Thread safety is properly handled for NSAlert operations

The code is safe as it's already running on the main thread through the InvokeAsync wrapper, which internally uses dispatchOnMainThread. The implementation in mainthread_darwin.go shows that dispatchOnMainThread uses dispatch_async(dispatch_get_main_queue(), ...) to ensure UI operations run on the main thread. The removal of the explicit dispatch_async block is correct as it would be redundant.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for InvokeAsync implementation to confirm main thread dispatch
rg -A 5 "func InvokeAsync"

# Search for other NSAlert usages to compare thread handling
rg "NSAlert" --type c

Length of output: 459


Script:

#!/bin/bash
# Check the implementation of dispatchOnMainThread
rg -A 10 "dispatchOnMainThread"

# Look for the globalApplication definition and initialization
rg "globalApplication"

# Check if there are any other dialog-related functions that might show thread handling patterns
rg "showDialog|showMessage|alert" --type go

Length of output: 45532

mkdocs-website/docs/en/changelog.md (1)

24-24: LGTM! Entry correctly documents the file association feature.

The changelog entry properly documents the addition of File Association support, correctly attributing it to PR #3873. This aligns with the PR objectives of porting the file association feature from v2 to v3.

v3/pkg/events/events.go (6)

32-32: LGTM: New event type for file association support.

The addition of ApplicationOpenedWithFile event type is well-integrated into the common events, following the existing patterns and maintaining sequential event ID numbering.

Also applies to: 60-60


68-73: LGTM: Consistent formatting in Linux events.

The formatting changes align with the codebase's style, improving readability.

Also applies to: 80-85


221-344: LGTM: Consistent formatting in Mac events.

The formatting changes maintain consistency across the large set of Mac-specific events while preserving the event ID sequence.


359-377: LGTM: Consistent formatting in Windows events.

The formatting changes align with the codebase's style while maintaining proper event ID sequencing.

Also applies to: 382-408


599-599: LGTM: Event mapping for file association support.

The new event mapping follows the established pattern and correctly uses the "common" namespace for cross-platform functionality.


32-32: Verify event handling implementation.

Let's verify the implementation of the ApplicationOpenedWithFile event handler in the application files:

Also applies to: 599-599

✅ Verification successful

Event handling implementation is properly implemented across platforms

The ApplicationOpenedWithFile event is correctly implemented:

  • Windows: Handled in application_windows.go through the main event loop
  • macOS: Implemented via HandleOpenFile in application_darwin.go
  • Example usage demonstrated in file-association/main.go showing proper event subscription and handling

The implementation follows consistent patterns across platforms and properly emits events with the required context.

[platform_specific][event_handling]

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for ApplicationOpenedWithFile event handler implementation
echo "Searching for event handler implementation..."
rg -l "ApplicationOpenedWithFile" --type go

# Search for file association related code
echo "Searching for file association related code..."
rg -l "HandleOpenFile|file\s+association" --type go

Length of output: 534


Script:

#!/bin/bash
# Let's examine the implementation details in the found files

echo "Checking v3/examples/file-association/main.go..."
rg "ApplicationOpenedWithFile" -B 5 -A 10 v3/examples/file-association/main.go

echo -e "\nChecking v3/pkg/application/application_windows.go..."
rg "ApplicationOpenedWithFile" -B 5 -A 10 v3/pkg/application/application_windows.go

echo -e "\nChecking v3/pkg/application/application_darwin.go..."
rg "ApplicationOpenedWithFile" -B 5 -A 10 v3/pkg/application/application_darwin.go

echo -e "\nChecking file association handling in application_darwin.go..."
rg "HandleOpenFile" -B 5 -A 10 v3/pkg/application/application_darwin.go

Length of output: 2350

v3/pkg/application/webview_window_windows.go (2)

383-384: LGTM: Improved visibility handling architecture

The change from w.show() to w.parent.Show() is a good architectural improvement that better encapsulates window visibility control at the parent level. This allows the parent window to handle any necessary initialization (like file association) before displaying the window.


Line range hint 1066-1084: Verify file drag & drop security measures

While the drag & drop implementation looks solid, consider adding additional validation for dropped files to prevent potential security risks:

  1. File size limits
  2. File type validation
  3. Path traversal checks
v3/tasks/events/generate.go (1)

5-6: New imports are appropriate for version handling and JSON parsing

The addition of semver and gjson packages is necessary for version management and JSON parsing functionalities introduced in the code.

Comment on lines +4 to +5
const resultElement = document.getElementById('result');
const timeElement = document.getElementById('time');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add null checks for DOM elements

The code assumes these elements exist in the DOM. Consider adding null checks to prevent runtime errors.

-const resultElement = document.getElementById('result');
-const timeElement = document.getElementById('time');
+const resultElement = document.getElementById('result');
+const timeElement = document.getElementById('time');
+
+if (!resultElement || !timeElement) {
+    console.error('Required DOM elements not found');
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const resultElement = document.getElementById('result');
const timeElement = document.getElementById('time');
const resultElement = document.getElementById('result');
const timeElement = document.getElementById('time');
if (!resultElement || !timeElement) {
console.error('Required DOM elements not found');
}

Comment on lines +19 to +21
Events.On('time', (time) => {
timeElement.innerText = time.data;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add file association event handling

This example should demonstrate file association functionality as per PR objectives. Consider:

  1. Add event listeners for file open events
  2. Implement cleanup for event listeners
  3. Add error handling for event data
+// Handle file open events
+Events.On('wails:application:file-open', (event) => {
+    console.log('File opened:', event.data);
+    // Handle the opened file
+});
+
 Events.On('time', (time) => {
     timeElement.innerText = time.data;
 });
+
+// Cleanup function
+function cleanup() {
+    Events.Off('time');
+    Events.Off('wails:application:file-open');
+}
+
+// Register cleanup
+window.addEventListener('unload', cleanup);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Events.On('time', (time) => {
timeElement.innerText = time.data;
});
// Handle file open events
Events.On('wails:application:file-open', (event) => {
console.log('File opened:', event.data);
// Handle the opened file
});
Events.On('time', (time) => {
timeElement.innerText = time.data;
});
// Cleanup function
function cleanup() {
Events.Off('time');
Events.Off('wails:application:file-open');
}
// Register cleanup
window.addEventListener('unload', cleanup);

Comment on lines +18 to +28
executes:
- cmd: wails3 task common:install:frontend:deps
type: once
- cmd: wails3 task common:dev:frontend
type: background
- cmd: go mod tidy
type: blocking
- cmd: wails3 task build
type: blocking
- cmd: wails3 task run
type: primary
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding task dependencies and error handling.

The execute commands look well-structured, but consider these improvements:

  • Frontend tasks might fail if Node.js is not installed
  • go mod tidy might need to run before frontend tasks if there are Go package dependencies

Consider adding pre-flight checks:

 executes:
+    - cmd: command -v node >/dev/null 2>&1 || { echo "Node.js is required but not installed."; exit 1; }
+      type: blocking
     - cmd: wails3 task common:install:frontend:deps
       type: once

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +8 to +9
# Define variables
APP_DIR="${APP_NAME}.AppDir"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add validation for required environment variables.

The script assumes environment variables (APP_NAME, APP_BINARY, ICON_PATH, DESKTOP_FILE) are set but doesn't validate their existence. This could lead to unclear errors later.

Add this validation at the beginning of the script:

 # Define variables
+# Validate required environment variables
+for var in APP_NAME APP_BINARY ICON_PATH DESKTOP_FILE; do
+    if [ -z "${!var}" ]; then
+        echo "Error: $var environment variable is not set"
+        exit 1
+    fi
+done
+
 APP_DIR="${APP_NAME}.AppDir"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Define variables
APP_DIR="${APP_NAME}.AppDir"
# Define variables
# Validate required environment variables
for var in APP_NAME APP_BINARY ICON_PATH DESKTOP_FILE; do
if [ -z "${!var}" ]; then
echo "Error: $var environment variable is not set"
exit 1
fi
done
APP_DIR="${APP_NAME}.AppDir"

Comment on lines +17 to +19
# Download linuxdeploy and make it executable
wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance download security and reliability.

The script downloads LinuxDeploy without verifying its integrity or handling timeouts. This could be a security risk and might fail in unstable networks.

Consider these improvements:

 # Download linuxdeploy and make it executable
-wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
+LINUXDEPLOY_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
+LINUXDEPLOY_SHA256="<known-checksum>"  # Replace with actual checksum
+
+if ! wget --timeout=15 --tries=3 -q -4 -N "$LINUXDEPLOY_URL"; then
+    echo "Error: Failed to download LinuxDeploy"
+    exit 1
+fi
+
+echo "$LINUXDEPLOY_SHA256 linuxdeploy-x86_64.AppImage" | sha256sum -c || {
+    echo "Error: LinuxDeploy checksum verification failed"
+    rm -f linuxdeploy-x86_64.AppImage
+    exit 1
+}
+
 chmod +x linuxdeploy-x86_64.AppImage
+
+# Clean up
+trap 'rm -f linuxdeploy-x86_64.AppImage' EXIT

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +367 to +378
//export HandleOpenFile
func HandleOpenFile(filePath *C.char) {
goFilepath := C.GoString(filePath)
// Create new application event context
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(goFilepath)
// EmitEvent application started event
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation and documentation.

The function needs input validation and documentation to improve robustness and maintainability:

  1. Add input validation for the filePath parameter
  2. Add documentation explaining the function's purpose and usage

Apply this diff:

+// HandleOpenFile is called by the Objective-C runtime when a file is opened with the application.
+// It converts the C string file path to Go string and emits an ApplicationOpenedWithFile event.
 //export HandleOpenFile
 func HandleOpenFile(filePath *C.char) {
+    if filePath == nil {
+        return
+    }
     goFilepath := C.GoString(filePath)
     // Create new application event context
     eventContext := newApplicationEventContext()
     eventContext.setOpenedWithFile(goFilepath)
     // EmitEvent application started event
     applicationEvents <- &ApplicationEvent{
         Id:  uint(events.Common.ApplicationOpenedWithFile),
         ctx: eventContext,
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
//export HandleOpenFile
func HandleOpenFile(filePath *C.char) {
goFilepath := C.GoString(filePath)
// Create new application event context
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(goFilepath)
// EmitEvent application started event
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}
// HandleOpenFile is called by the Objective-C runtime when a file is opened with the application.
// It converts the C string file path to Go string and emits an ApplicationOpenedWithFile event.
//export HandleOpenFile
func HandleOpenFile(filePath *C.char) {
if filePath == nil {
return
}
goFilepath := C.GoString(filePath)
// Create new application event context
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(goFilepath)
// EmitEvent application started event
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}

Comment on lines +141 to +156
if len(os.Args) == 2 {
arg := os.Args[1]
ext := filepath.Ext(arg)
println("Got extension: ", ext)
if slices.Contains(m.parent.options.FileAssociations, ext) {
println("Slices contains")
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(arg)
// EmitEvent application started event
println("sending event")
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add file path validation and improve error handling.

The current implementation has several potential issues:

  1. No validation if the argument is actually a file path
  2. No error handling for filepath.Ext
  3. No verification if the file exists

Consider this improved implementation:

 if len(os.Args) == 2 {
 	arg := os.Args[1]
-	ext := filepath.Ext(arg)
-	println("Got extension: ", ext)
-	if slices.Contains(m.parent.options.FileAssociations, ext) {
-		println("Slices contains")
-		eventContext := newApplicationEventContext()
-		eventContext.setOpenedWithFile(arg)
-		// EmitEvent application started event
-		println("sending event")
-		applicationEvents <- &ApplicationEvent{
-			Id:  uint(events.Common.ApplicationOpenedWithFile),
-			ctx: eventContext,
-		}
-	}
+	// Verify if the argument is a valid file
+	if fileInfo, err := os.Stat(arg); err == nil && !fileInfo.IsDir() {
+		ext := filepath.Ext(arg)
+		if slices.Contains(m.parent.options.FileAssociations, ext) {
+			eventContext := newApplicationEventContext()
+			eventContext.setOpenedWithFile(arg)
+			applicationEvents <- &ApplicationEvent{
+				Id:  uint(events.Common.ApplicationOpenedWithFile),
+				ctx: eventContext,
+			}
+		}
+	}
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if len(os.Args) == 2 {
arg := os.Args[1]
ext := filepath.Ext(arg)
println("Got extension: ", ext)
if slices.Contains(m.parent.options.FileAssociations, ext) {
println("Slices contains")
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(arg)
// EmitEvent application started event
println("sending event")
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}
}
if len(os.Args) == 2 {
arg := os.Args[1]
// Verify if the argument is a valid file
if fileInfo, err := os.Stat(arg); err == nil && !fileInfo.IsDir() {
ext := filepath.Ext(arg)
if slices.Contains(m.parent.options.FileAssociations, ext) {
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(arg)
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}
}
}

panic(err)
}

err = os.WriteFile(packageJsonFilename, []byte(newJSON), 0644)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Check for errors when writing to package.json

The error returned by os.WriteFile is assigned to err but not checked. This could lead to silent failures if the file write operation does not succeed.

Apply this diff to handle the error:

 err = os.WriteFile(packageJsonFilename, []byte(newJSON), 0644)
+if err != nil {
+    panic(err)
+}

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +408 to +425
version := gjson.Get(string(packageJSON), "version").String()
// Parse and increment version
v := semver.MustParse(version)
prerelease := v.Prerelease()
// Split the prerelease by the "." and increment the last part by 1
parts := strings.Split(prerelease, ".")
prereleaseDigits, err := strconv.Atoi(parts[len(parts)-1])
if err != nil {
panic(err)
}
prereleaseNumber := strconv.Itoa(prereleaseDigits + 1)
parts[len(parts)-1] = prereleaseNumber
prerelease = strings.Join(parts, ".")
newVersion, err := v.SetPrerelease(prerelease)
if err != nil {
panic(err)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add checks for versions without a prerelease segment to prevent panics

Currently, the code assumes that the version string in package.json has a prerelease segment. If the version does not have a prerelease segment, v.Prerelease() will return an empty string, leading to potential panics due to index out of range or conversion errors.

Apply this diff to handle versions without a prerelease segment:

 version := gjson.Get(string(packageJSON), "version").String()
 // Parse and increment version
 v := semver.MustParse(version)
 prerelease := v.Prerelease()
+if prerelease == "" {
+    // Set a default prerelease segment if none exists
+    prerelease = "alpha.0"
+}
 // Split the prerelease by the "." and increment the last part by 1
 parts := strings.Split(prerelease, ".")
 prereleaseDigits, err := strconv.Atoi(parts[len(parts)-1])
 if err != nil {
     panic(err)
 }

Alternatively, ensure that the code handles versions without prerelease segments appropriately.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
version := gjson.Get(string(packageJSON), "version").String()
// Parse and increment version
v := semver.MustParse(version)
prerelease := v.Prerelease()
// Split the prerelease by the "." and increment the last part by 1
parts := strings.Split(prerelease, ".")
prereleaseDigits, err := strconv.Atoi(parts[len(parts)-1])
if err != nil {
panic(err)
}
prereleaseNumber := strconv.Itoa(prereleaseDigits + 1)
parts[len(parts)-1] = prereleaseNumber
prerelease = strings.Join(parts, ".")
newVersion, err := v.SetPrerelease(prerelease)
if err != nil {
panic(err)
}
version := gjson.Get(string(packageJSON), "version").String()
// Parse and increment version
v := semver.MustParse(version)
prerelease := v.Prerelease()
if prerelease == "" {
// Set a default prerelease segment if none exists
prerelease = "alpha.0"
}
// Split the prerelease by the "." and increment the last part by 1
parts := strings.Split(prerelease, ".")
prereleaseDigits, err := strconv.Atoi(parts[len(parts)-1])
if err != nil {
panic(err)
}
prereleaseNumber := strconv.Itoa(prereleaseDigits + 1)
parts[len(parts)-1] = prereleaseNumber
prerelease = strings.Join(parts, ".")
newVersion, err := v.SetPrerelease(prerelease)
if err != nil {
panic(err)
}

Comment on lines +410 to +425
v := semver.MustParse(version)
prerelease := v.Prerelease()
// Split the prerelease by the "." and increment the last part by 1
parts := strings.Split(prerelease, ".")
prereleaseDigits, err := strconv.Atoi(parts[len(parts)-1])
if err != nil {
panic(err)
}
prereleaseNumber := strconv.Itoa(prereleaseDigits + 1)
parts[len(parts)-1] = prereleaseNumber
prerelease = strings.Join(parts, ".")
newVersion, err := v.SetPrerelease(prerelease)
if err != nil {
panic(err)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Simplify prerelease version increment using semver's built-in methods

Instead of manually parsing and incrementing the prerelease segment, you can use the semver library's IncPrerelease() method for a more concise and less error-prone implementation.

Apply this diff to simplify the version increment:

 version := gjson.Get(string(packageJSON), "version").String()
 // Parse and increment version
 v := semver.MustParse(version)
-// Existing code manually increments the prerelease segment
+// Increment the prerelease version using semver
+newVersion := v.IncPrerelease()

This approach reduces complexity and leverages the semver library's capabilities.

Committable suggestion skipped: line range outside the PR's diff.

Copy link

sonarcloud bot commented Nov 4, 2024

@leaanthony leaanthony merged commit d18b7bc into v3-alpha Nov 8, 2024
11 checks passed
@leaanthony leaanthony deleted the v3-alpha-feature/file-association-port branch November 8, 2024 21:58
leaanthony added a commit that referenced this pull request Nov 8, 2024
* Update nsis template

* Move app data into config.yml

* mac support

* Add FileAssociations application config option
Support `ApplicationOpenedWithFile` event on Windows
Add docs

* Add FileAssociations application config option
Support `ApplicationOpenedWithFile` event on Windows
Add docs
Add test project

* Update example & docs.
Fix show window bug.

* Fix window show event bug

* Update changelog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant