-
Notifications
You must be signed in to change notification settings - Fork 118
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
[Bug Fix] @Image directive requires an explicit file extension while images described in Markdown do not(SR-15315) #3
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for these changes! It's looking great. I just have one small suggestion regarding the doc comment. Also, we’ll want to add tests to check the new behavior.
Rebase to the updated main branch. |
Thanks for adding the test! It tests the behavior of the API in I’d recommend implementing another test in |
Did not find a file named |
XCTAssertEqual(translator.imageReferences.count, 3) | ||
XCTAssertNotNil(translator.imageReferences["intro.png"]) | ||
XCTAssertNotNil(translator.imageReferences["introposter"]) | ||
XCTAssertNotNil(translator.imageReferences["introposter.png"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should be asserting on the RenderNode
node here, similar to other tests, rather than the state of the translator. I don't think it's expected for us to have separate image references for introposter
and introposter.png
, since they refer to the same asset, right? I think we should use always use the full file name with extension as the key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RenderNode seem to be always true, do you mean we assert the renderNode's references property or something else?
let renderNode = translator.visit(technology) as! RenderNode
guard let introPosterReference = renderNode.references["introposter.png"] as? ImageReference else {
XCTFail("Missing intro poster reference")
return
}
I don't think it's expected for us to have separate image references for introposter and introposter.png, since they refer to the same asset, right?
Yes, they refer to the same asset. But due a implementation detail, they have different key, will try to solve the wrong behavior in the coming commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the test issue, but for the second problem I think we need the resolveAsset(named name: String, in parent: ResolvedTopicReference, ofType type: AssetType? = nil)
method to not only return a DataAsset? but also the queried "full media name"/"file extension" String from the inner bestKey method. Is that OK with you?
/// Finds the best matching storage key for a given asset name.
/// `name` is one of the following formats:
/// - "image" - asset name without extension
/// - "image.png" - asset name including extension
func bestKey(forAssetName name: String) -> String? {
guard !storage.keys.contains(name) else { return name }
// Try the fuzzy index
return fuzzyKeyIndex[name]
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm interesting. If we create a new function in the context, it would need to find the correct DataAssetManager
to query again. Maybe it would be reasonable to add a property in DataAsset
(which resolveAsset
returns) that tracks the identifier that should be used when referring to this asset. That way, we resolve the asset and get its identifier in one call.
Something like this in DataAsset
:
/// The identifier of the asset.
///
/// This is typically the base name of the asset and its extension, for example "`image.png`".
public var identifier: String
We'd deprecate the existing DataAsset
initializer and create a new one that takes an identifier
, and update usages of the DataAsset
initializer to use the new one that takes an identifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is a way to achieve it. But can we wrap and expose the bestKey method like the updated PR? So we'll get the fullname of the asset. Which do you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could expose the bestKey
functionality (which I think we would name differently in DocumentationContext
) but I think starting to store the identifiers in DataAsset
instead makes sense long term. That way, clients don't need to query the context twice (once to resolve, another to get the identifier). I think it's expected that you'd get a canonical identifier for it as part of the resolution process.
Interested in hearing your thoughts though!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think from long term we need such identifier property in DataAsset, I'm currently trying to implement it. But encounter some problems here.
Sure, we can use dataAsset.identifier here to indicate the name.
But in some case the DataAsset(identifier:) seem hard to use/fit the situation.
And sometimes it causes duplication.
Also after the trying, I change my mind and think DataAsset actually don't fit to add a identifier property. Since it is an abstract of "Asset" and should not contain the key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And we can view and discuss the WIP change on the branch here if needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the changes you're showing the screenshot make sense—for the VideoReference
decoder implementation, the identifier we should use is the identifier
value declared a few lines above, since that's the value we're encoding. Regarding the duplication, I'm not too concerned about that, it turns out we're also using the identifier as the key of a dictionary for fast lookups.
Update with the "nit" suggestion |
@swift-ci please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thank you @Kyle-Ye !
Bug fix: SR-15315
https://bugs.swift.org/browse/SR-15315
Summary
Starting a Local Preview Server and set a breakpoint at ResourceReference's path property
Remove the ".png" to trigger the pause.
And find only 2 API get the path property.
One is inside DocumentationContext.swift
swift-docc/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift
Lines 1997 to 2007 in ff972f1
The other is inside RenderNodeTranslator.swift
swift-docc/Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift
Lines 1221 to 1277 in ff972f1
The first will call DataAssetManager and will use inner fuzzyKeyIndex to query which have no problem.
The second is where the bug comes from. It need to get the extension of the media to check if is supported.
My 2 potential fix suggestion:
Dependencies
NO
Testing
Steps:
Checklist
Make sure you check off the following items. If they cannot be completed, provide a reason.
./bin/test
script and it succeeded