Interested in bringing configurable package templates to SwiftPM

Hi everyone!

I’m Jakub, a last year high school student from Poland interested in GSoC participation. I have some experience working with Swift mainly through mobile app development. I worked with Swift Packages as well though, that’s why the customizable package templates project caught my attention.

Here’s a brief overview of my idea. I was thinking mainly about trying to make existing packages easy to convert to configurable templates with help of a built-in tool.

Configurations

A configuration would be a predefined by creator option that would include or exclude some selected pieces of code or whole files. Configurations would be later chosen by user, during package initialization.

  • All unmarked files and code would be included in all configurations by default
  • INCLUDED means the marked code or file would be included only in the specified configuration(s)
  • EXCLUDED means the marked code or file would be excluded only from the specified configuration(s)

To mark some code as either included or excluded from a certain configuration creator would have to use appropriate (highly inspired by Swift compiler directive syntax :upside_down_face:) comments:

// CODE INCLUDED in [Onboarding]
print("Hello") // This line will be added to the initialized package only if the "Onboarding" configuration is selected by a user.
// CODE INCLUDED end
// CODE EXCLUDED from [Onboarding]
print("Good bye") // This line will be added to the initialized package only if the "Onboarding" configuration is NOT selected by a user.
// CODE EXCLUDED end

Same goes for files (with the comments preferably on top of a file):

// FILE INCLUDED in [Onboarding]
// This file will be added to the initialized package only if the "Onboarding" configuration is selected by a user.
print("Hello") 
// Code...
// FILE EXCLUDED from [Onboarding]
// This file will be added to the initialized package only if the "Onboarding" configuration is NOT selected by a user.
print("Good bye")
// Code...

Template.json

This file would be sitting in package directory next to Package.swift. It would contain all available configurations with appropriate descriptions (alternatively, maybe it would be actually a good idea to include configurations’ details inside package manifest?):

[
   {
      "tag": "Onboarding",
      "description": "Includes all required code for seamless onboarding"
   }
]

Creating a template

For that we could create an API that would scan through code of a package seeking for INCLUDED/EXCLUDED comments to ask creator for additional description for each one of them to automatically generate a Template.json file (Potentially, it could also ask to create additional configurations with typed in file names and/or specific code lines to include or exclude):

> swift package mktemplate /template/directory
Do you want to include configuration „Onboarding”? (y/n) y
Describe configuration „Onboarding”: Includes all required code for seamless onboarding
Successfully created template at /template/directory

Using a template

User would simply use the existing swift package init with the option --type /template/directory. The URL would lead to either a local template or a template hosted remotely via e.g. GitHub. Afterwards, user would be asked to select configuration(s) from available ones. The resulting package would be stripped from all INCLUDED/EXCLUDED comments and Template.json file:

> swift package init —type https://github.com/MAJKFL/really-cool-package-template
Available configurations:
 - Onboarding - Includes all required code for seamless onboarding
Select configurations: Onboarding
Successfully created package

Potential problems:

  • Conflicts within configurations - What would happen if creator excluded a file from a configuration and included some code in that file to the same configuration? I think it would be a good idea to establish some rules of priority e.g. FILE INCLUDED > FILE EXCLUDED > CODE INCLUDED > CODE EXCLUDED.
  • Nested CODE INCLUDED/EXCLUDED comments - A possible solution would be to just ignore inner comments
  • Conflicts between certain configurations - What if user chose two configurations and one of them excludes a file that has some included code for the other configuration? Well… I’m not sure about this one. Possibly my best idea would be to make a quick check during Template.json generation and/or package initialization. SwiftPM could for example show a prompt like WARNING - Selected configurations x and y conflict with each other. Do you want to proceed? (y/n)

I hope it wasn’t too chaotic, and it gives an overall idea of my initial plan. I think it would be quite straightforward for creators as well as users to use this system. Especially the format, slightly modified Swift Package with some clear comments and configuration descriptions, would make the templates easily discoverable and fun to use :slightly_smiling_face:

I would love to hear feedback, any changes and recommendations from you @NeoNacho!

Thanks in advance!
Jakub

4 Likes