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

Added the ability to specify options, or default arguments, for plugin invocations #899

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

SomeRandomiOSDev
Copy link

What does this PR do?

This PR fills in a gap that is currently present when using the Package/Xcode Plugins to perform source code generation, either manually using the RswiftGenerateResourcesCommand, or automatically using the RswiftGeneratePublicResources or RswiftGenerateInternalResources plugins. The gap to which I speak is that if any customization is needed, i.e. rswift arguments, that can only be done when manually running the RswiftGenerateResourcesCommand plugin and the arguments must be specified each time the plugin is used.

This is obviously not an ideal scenario, so this PR seeks to alleviate this issue by adding support for an "options" file. The way in which this works is slightly different for Xcode Plugins vs. SPM Plugins, but the premise and formatting is the same:

  1. A .rswiftoptions file is declared in your sources root (Xcode Plugins can create an additional file in the root of the project as well)
  2. When either of the plugins mentioned above the options are loaded from this options file, validated, and then combined with any defaults and options provided via the plugin invocation and including those in the options provided to the rswift utility.
  3. That's it!

The .rswiftoptions file is a JSON file that has a very simple schema:

{
  "generators": ["..."],
  "omit-main-let": true/false,
  "imports": ["..."],
  "access-level": "public"/"internal",
  "rswiftignore": "...",
  "bundle-source": "finder"/"module",
  "output-path": "...",
  "additional-arguments": ["..."]
}

All of the fields in this JSON object are optional and are applied in a systemic and deterministic way when executing the plugins:

  1. Create an options structure any arguments passed in from the plugin invocation parsed out. Options provided to the plugin invocation always take precedent since they have to be passed in for each execution, indicating that the intent is to override any preset or default values.
  2. (For Xcode Plugins) Attempt to load a .rswiftoptions file that is located in the same directory as the project file invoking the plugin. These options are combined with the options in the previous step in such a way to where the previous options will not be overridden by the new options, should a particular option already be set.
  3. Attempt to load a .rswiftoptions file that is located in the root directory containing the source files for the given target. These options are combined with the options in the previous step in such a way to where the previous options will not be overridden by the new options, should a particular option already be set.
  4. Lastly, apply any "fallback" options, i.e. options that should be used should the options not be specified by any other means.

When done in this manner, this allows for one to use these options files to specify the arguments that should always be provided, but allows for those values to be overridden if invoking the plugin directly.

How are these changes implemented?

The way in which the implementation is done is multifaceted:

  1. First, a new library target was created called RswiftShared to contain code that should be shared between the rswift executable target as well as the plugin targets. The AccessLevel, BundleSource, and ResourceType types were all moved into this new target.
  2. Next, symbolic links were created in the plugin sources directories to reference the RswiftShared sources directory. This is done to get around an issue where plugin targets cannot have a dependency on a library target so the sources are brought into each of the plugin targets via this symbolic link.
  3. An additional type was created to mimic the structure of the JSON options file with a conformance to Decodable for easy parsing.
  4. Lastly, the implementation of each plugin was updated to attempt to load these .rswiftoptions files and combine these options with any provided from the plugin invocation, if relevant.

Any testing done?

Yes, testing was performed locally using an Xcode project and a Swift Package, each of which was tested by using various combinations of the aforementioned plugins, options files, and options provided when manually invoking the RswiftGenerateResourcesCommand. All results of this testing align with the deterministic manner in which those options should have been applied, as described above

@SomeRandomiOSDev
Copy link
Author

@tomlokhorst Could I get a review on this PR?

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