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

Support for errors generated by swift-testing (and other things that don't print file paths) #191

Open
dabrahams opened this issue Dec 24, 2024 · 11 comments

Comments

@dabrahams
Copy link

You might want to add something like this. Without it, I can't get M-x compile to jump to test failures.

@taku0
Copy link
Member

taku0 commented Dec 25, 2024

I couldn't access to the link.

@dabrahams
Copy link
Author

I'm sorry, I forgot that repo was private. You can find the code pasted here.

@taku0
Copy link
Member

taku0 commented Dec 26, 2024

Let me clarify the issue.

  • XCTests (xcodebuild test) prints error messages with the GNU standard sourcefile:lineno:column: message format.
  • Swift Testing (swift test) prints error messages with machine-unfriendly format without directory name, meant only for humans.
  • We have two problems to solve:
    • The format is non-standard.
    • It prints only filename without directory names.
  • The former can be solved with compilation-error-regexp-alist.
  • The latter needs some hack.
  • The developer of Swift Testing proposes showFullPaths/showRelativePaths option to be implemented in the future, but not now.

Am I understanding the issue right?

Then, we have some options:

  • Searching file in an advice for compilation-find-file, as your code does.
  • Parsing JSON output and format it into the compilation buffer.
  • Transforming the stderr of the Swift Testing on compilation-filter-hook.
  • Wrapping swift test to parse JSON output and format the messages into stdout.
  • Setting compilation-search-path locally on compilation-start-hook, up to compilation-smart-find-max-depth.

The last method seems to be the least intrusive. It may impose some delay but it should be negligible nowadays (needs verification).

Parsing the JSON output seems to be the most ambitious, but the _FilePath attribute is private, and the JSON is streamed to a file rather than stdout/stderr.

@dabrahams
Copy link
Author

I think you understand correctly.

@dabrahams
Copy link
Author

Macro expansion has a similar problem (can be fixed just with compilation-error-regexp-alist I think) :

macro expansion #expect:3:14: error: call can throw, but it is not marked with 'try' and it is executed in a non-throwing autoclosure
`- /Users/dave/src/parsing/Tests/parsingTests/EBNFGrammarTests.swift:85:42: note: expanded code originates here

The first line is detected as the error (with the wrong filename) and the second line is not matched.

@taku0
Copy link
Member

taku0 commented Dec 28, 2024

Adding a regexp to compilation-error-regexp-alist is easy but suppressing a match is hard. We could (setq compilation-error-regexp-alist '(swift-testing)) but it affects users using other tools that produce GNU standard error messages.

@dabrahams
Copy link
Author

I think you just need to match it yourself, perhaps grabbing the next line which contains the file name. I have gone so far as to programmatically edit existing regents to do the right thing, FWIW

@dabrahams
Copy link
Author

Also, we need parsing for new "swift-style" errors:

x.swift:6:14: error: conflicting conformance of 'X<T>' to protocol 'Equatable'; there cannot be more than one conformance, even with different conditional bounds
2 | 
3 | 
4 | extension X: Equatable {}
  | `- note: 'X<T>' declares conformance to protocol 'Equatable' here
5 | 
6 | extension X: Equatable where T: Sequence {}
  |              `- error: conflicting conformance of 'X<T>' to protocol 'Equatable'; there cannot be more than one conformance, even with different conditional bounds
7 | 

Emacs does have some mechanism for capturing information in earlier lines and using it in later ones (see support for make's "entering directory foo/bar" messages).

taku0 added a commit that referenced this issue Jan 4, 2025
@taku0
Copy link
Member

taku0 commented Jan 4, 2025

I think you just need to match it yourself, perhaps grabbing the next line which contains the file name. I have gone so far as to programmatically edit existing regents to do the right thing, FWIW

The compilation buffer is asynchronous. When matching regex patterns against the line macro expansion #expect:3:14:, we might not yet have the following line.

I propose a different approach:

  • Add a regexp pattern like [^ \t]+\.swift:[0-9]+:[0-9]+: to the compilation-error-regexp-alist-alist (the actual one is slightly different).
  • Specify a lambda for the FILE component of compilation-error-regexp-alist-alist to resolve filenames dynamically.
    • If the file does not exist, it returns nil, which prevents Emacs from highlighting the filename.
  • This function resolves filenames using the output of swift package describe.
    • The list of filenames is cached during the compilation.
  • Replace compilation-error-regexp-alist with '(swift-testing) (i.e., no default handlers) in compilation-process-setup-function if the compilation command matches swift test (customizable).

I have created a branch implementing my proposal. Could you try it?

I couldn't implement the feature that asks the user to disambiguate multiple matches (i.e. your compilation-smart-find-file-choose function).

Known bug: the error count is doubled. Maybe this is a side-effect of adding ansi-color-compilation-filter to compilation-filter-hook.

@dabrahams
Copy link
Author

dabrahams commented Jan 4, 2025

I will try, thanks. But FWIW using swift package describe will fail with other build systems. I know some people use CMake and bazel to build swift projects and I'm sure others are in use.

@taku0
Copy link
Member

taku0 commented Jan 5, 2025

Can Swift Testing (swift test) be invoked without Package.swift? My code activates only when the compilation command is swift test.

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

No branches or pull requests

2 participants