SE-0318: Package Creation

The review of SE-0318: Package Creation, begins now and runs through June 29, 2021.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager or direct message in the Swift forums).

What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thank you for helping improve the Swift programming language and ecosystem.

Tom Doron
Review Manager

9 Likes

I'm ambivalent about the new command, but the template feature is important and it should absolutely be added!

I would like to suggest though that the location of the config directory itself be configurable, probably with an environment variable. Alternatively, or additionally, perhaps the --template argument could accept either a name or a path to a template.

  1. Could you add some comparisons with what other popular package managers do here (e.g. npm, yarn, pip, cargo etc.)? I understand the motivation to improve defaults and make things ergonomic for beginners, but having two similarly named commands init and create might create more confusion instead of being helpful (especially if newcomers are expecting the command they want to be named init).
  2. Will there be a warning on not specifying a --type with init so that in the future it also defaults to executable instead of library? It seems a bit odd to have these two similarly commands have different defaults.
  3. In the spirit of improving ergonomics, was the option of having an additional --interactive flag for init considered but rejected for some reasons? I can imagine something like that being useful where you are slowly guided through selecting things one-by-one. I've certainly found that helpful when getting acquainted with a new tool. (Or maybe, it doesn't need to be a new flag if swift package init --interactive is considered too long, maybe it just shows up if you type swift package?)
  4. +1 for project templates.
3 Likes

Overall, I like the general direction - I think it would be very nice to separate the concerns of create/import as proposed and definitely would like to see templates.

I would suggest a few things to be considered in the context of making it more usable for teams who shares templates:

  1. Instead of storing templates in the local file system and then supporting importing them from an URL creating a local template copy, I would suggest support configuring an URL "search path" (either as an environment variable, or as a configuration file, but its basically a list of URL:s each one containing a template, these would always be git repos either on remote server or on disk)

This set of URL:s would be used to directly download the latest version of a given template at package creation time, so local file system copies don't go stale. Basically just pull it from the server/disk with git each time as needed from the URL.

In the best of worlds, one would just configure a single additional URL (which would be either pointing to a server or to a local file) which in turns provides the list of template-URL:s that should be searched in e.g. JSON or similar.

This way, an organization can provide one simple configuration setting, which would dynamically pull in the appropriate templates in use by the organization.

Template names could be specified by the final path component of the URL.

  1. The built-in templates provided by SPM in the toolchain would always be appended to this search path and be part of the toolchain distro. These would be picked up from the file system. One could then have e.g. 'application' and 'library' default templates shipped with the toolchain.

  2. Have 'swift package create' list the templates available if no arguments were provided displaying both the ones found from the URL and the built-in ones.

  3. Consider conflating type with the template, this would give a nice ergonomic for creation:

swift package create <templatename> packageName

swift package create application myApp
swift package create library myLib

or custom for an organisation that defined a new template:

swift package create company-standard-app myCompanyApp
swift package create company-standard-lib myCompanyLib

The downside is that the default SPM templates "application" or "library" in this example would be duplicated in terms of structure, but it would be easier for the end users IMO to simply skip extra arguments and instead have a consistent workflow where a template always is used.

Could still allow overriding the defined type with e.g. --type if desired.

2 Likes
  • What is your evaluation of the proposal?
    I think the proposed change will improve user experience, especially for beginners.
  • Is the problem being addressed significant enough to warrant a change to Swift?
    Yes. I mostly use Xcode to create packages, so when I use the command line, I don’t remember if package init will also create a directory.
  • Does this proposal fit well with the feel and direction of Swift?
    I think it eases the learning curve for beginners and clarifies the package commands, so yes.
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
    I read the proposal and the thread replies.

I have just one suggestion: request user verification when invoking package init in a non-empty directory. Then, after some time with both init and create, if people seem to correctly recognize the difference between the two commands, we could drop this extra step in package initialization. For now, though, I think it’s important to damage-control the non-obvious function of init.


Would these support caching, for things like offline package creation?

Cache for offline package creation would be one option, the easier way would be to have a local folder with those git repos on your ssd and then have a configuration file that points there instead of fetching the live data.

Perhaps that would be another option - to have a local copy of the templates that is the git clone of the original template repo and provide a simple way to refresh all templates local git repos from upstream. Perhaps could even warn if local copy is out of date and suggest refresh if network is available. My main point is to get less steps to keep a set of up-to-date templates with a minimum amount of manual steps after initial setup (preferably zero).

1 Like
  • What is your evaluation of the proposal?

-1 as it stands now. I don't think this should be a separate command. init should simply be improved. Ideally, this would include both options as well as an (default) interactive mode, like @typesanitizer suggested. Take a look a NPM's package creation workflow. Complain all you want about the ecosystem, but it's super easy to up and running with a new package. If init could be improved with the create capabilities described here, as well as an interactive mode, it would be much easier for people to get started.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes. But the improvement provided is somewhat offset by leaving the init command intact. That duplication will only confuse users.

  • Does this proposal fit well with the feel and direction of Swift?

Yes, in that makes package creation easier, no in that it creates a command that's very similar to what init already does while leaving init intact.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Yes, I've used CocoaPods for package creation a bit, as well as NPM.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Reading of the pitch and proposal, as well as the review thread to date.

4 Likes

Without belaboring the point, I agree with @woolsweater, @typesanitizer, and @Jon_Shier's concerns about having two similarly named commands; it is not clear that there has been sufficient exploration of how to improve the existing command as suggested by these reviewers to reject such an approach. I am broadly sympathetic to the overall impetus to improve the experience of making a new package, however. Fortunately, we are not operating a vacuum here: as has been pointed out, npm and other tools exist which provide examples that can be learned from--this proposal would benefit from a survey of how these tools have tackled the problem and their pros and cons.

4 Likes

This first review for SE-0318 has concluded and the proposal was returned for revision.

Thank you to everyone for the feedback and contributions to this proposal.

1 Like