Add license information to Swift Package Manager and expose it to dependent projects

Proposal: SPM License Information

Hi, I propose to add license information to Package.swift and expose that information to packages/projects which depend on the Package.

Most Swift packages already have license information available in their GitHub repo. For application development, it‘s often necessary/a good thing to somehow display the license information to the end-user inside the application.
For this to happen, the developer has to copy the license information (often repetitive text) inside their code and display it in the App.

With my proposal, you can add license information to your swift package.


// swift-tools-version:5.5

import PackageDescription

let package = Package(
    name: "dealer",
    products: [
        .library(name: "Dealer", targets: ["Dealer"]),
    ],
    dependencies: [
        .package(url: "https://github.com/apple/example-package-deckofplayingcards.git", from: "3.0.0"),
    ],
    targets: [
        .target(
            name: "Dealer",
            dependencies: ["DeckOfPlayingCards"]),
    ],
    license: .MIT(maintainers: [„flexlixrup“, „swiftlang“])
)

As this information alone isn’t really helpful to the developer, we would also need a way to access the information in code dependent on this package. E.g. Dealer.Metadata.license could return a preformatted String with the license information already built (or a license struct, whatever the community prefers).

I suppose that would mean that we need to start to expose the Package.swift information to the dependant of the package. This is currently not the case. IMO this would mean that it is necessary to use macros for this, to create the necessary information at build time, but I’m happy to hear other implementation ideas.

If we develop a way to expose this information, that would open a large amount of new metadata, that can be added to the Package.swift file and be accessible during compile time, like package versions, etc. I think this could be a good baseline to bring SPM forward. Looking forward to hearing your opinions on this pitch.

6 Likes

I like it!

Especially as some package’s licenses mandate that the product you use the package in is provided using the same language.

Maybe we could do a form of “license checking at build time”?

Or you get a warning if you use packages with incompatible licenses.

Simplifying licensing is important for scaling.

But I wouldn't have the goal of automating license obligations (e.g., displaying required notices) because it's too hard to get right and too important to mess up. Nor would I recommend license scanning/verification based on Package.swift annotations because they're too easy to be discordant with reality.

The complexity of features and prior art here - binary packages, multiple license schemes, SPDX license declarations and scanners, companies built from open-source management - should be a cautionary warning.

Another key stakeholder would be the Swift package indexing folks.

Still, what could be done?

A simple thing is to have Package.swift support a single field with a URL to further information. People can then evolve their own conventions for that field without tangling SPM in design issues. If you can promote conventions where the URL is itself a license reference, or points to something with package legal metadata, power to you.

Or perhaps for the official Swift/SPM project, there might be a sweet spot for permissive licenses. If it's just MIT or Apache (which seem to be the standard of care), say that. Or perhaps also include the major viral licenses (GPL), as a warning. So the Swift/SPM-support community convention would aim only to be a first-cut filter that triggers rejection or consideration (i.e., where discordant/false positives and negatives have only search costs).

The operative question for SPM is whether when declaring a package dependency, you can restrict it to certain license classes. This would fault if e.g., on version upgrade a permissive license went viral, perhaps transitively.

1 Like

@wes1 your first suggestion would be an URL field which would contain a license link by convention as far as I understand. But I’m not sure I understand what

this means. Providing some standard licenses and support for a custom link and warn the user of the package if the license changed/is not in some filter condition?

Sorry: v1 is convention but no automated warning.

Rewriting:

People can then evolve their own conventions for that field
...
Or perhaps ... the official Swift/SPM project
...
would recommend values for 3 license classes: MIT, Apache, and GPL

Then (v2) the automation question is whether to additionally support a basic transitive license check using (only) these license classes. Balking (as I originally suggested) could be hard. Most likely that would just translate to including the license field in the output of the dependency-tree command (as an added field it should be backward compatible), so users could build their own tooling based on that.

Sounds like a good middle ground for me and is considerably easier to implement. User then could build the automatic creation based on that output if desired.

This is a use case that could provide real value, if it can be implemented in a reliable way. One of my biggest concerns in using OSS software in our company is if a license changes and we become non compliant overnight. Not that a warning solves everything (it doesn’t help if we need to migrate to another package), but at least it should lower the risk of using something that is no longer suitably licensed.

I don’t know if package manifest is the best place to do this, or perhaps having scanners in a pipeline is better. But it is an interesting idea.

Versions are somewhat accessible since Set `-user-module-version` for any version-based package by neonichu · Pull Request #6781 · swiftlang/swift-package-manager · GitHub