Shared code between projects as library without a repo? - swift

I've two Swift PM projects, both use some common code which I would like to store perhaps in a separate project, say a library, which then these two would be able to import.
I've used swift init --type library and so on to build a library but is there any other documented way of including it in the other projects without having to submit it to github and providing the link to the repo to the swift package manager?
I'm thinking something around the lines of building the library project and having a script which copy pastes it wherever it needs to be to be accessible to the other projects (in their own directories if need be)

According to the Swift Package Manager Usage documentation a swift package is designed to be used as a git repository.
Simply put: a [Swift] package is a git repository with semantically versioned tags, that contains Swift sources and a Package.swift manifest file at its root.
That said, the dependencies documentation section states that the depedency path can be a local path.
[Dependencies] is the list of packages that the package depends on. You can specify a URL (or local path) to any valid Swift package.
Note that the git tags are useful (needed) to manage which version of a dependent package is included.
// 1.5.8 ..< 2.0.0
.package(url: "path/SharedPackage", .upToNextMajor(from: "1.5.8")),
// Constraint to an arbitrary closed range.
.package(url: "path/SharedPackage", "1.2.3"..."1.2.8"),
// Branch and revision.
.package(url: "path/SharedPackage", .branch("develop")),
Key Points:
Treating the local package as the same local git repository could still align one's workflow with the Swift Package Manager design.
Some remote or additional git repository is not required because local dependency paths of the Swift package(s) can be used.
Basically, using git in a more simplified and streamlined way may be worth considering for the local-only, some-shared-code use case.

Related

Swift Package Manager: shallow clone

The problem:
I'm using the nlohmann/json package with Swift Package Manager. Package.swift manifest file
By looking at the package manifest, it's clear that the library includes just a single file and a header. However, in order to install the package, Swift Package Manager clones the whole repository which is over 300 MB in size.
Potential solution
Using shallow clone will resolve the issue. Is it possible to use shallow clone with Swift Package Manager? Interested in both Xcode and Command line solutions.
Relevant links
Swift Forums discussion
Swift JIRA
Firebase team's solution: fork the "offending" dependency repositories

How to version swift packages

Using Xcode 12.4 and Swift 5.3 I have defined a package using the Package.swift manifest file. After including it in an app I want to update the package. To do that I have changed the link to the new release and updated the checksum; the relevant part of the file looks like this:
let package = Package(
name: "MyPackage",
// omitted platforms and products
targets: [ .binaryTarget( name: "MyPackage",
url: "https://artifactory/mypackage-v1.1.zip",
checksum: "..." ) ] )
However, I get the error message artifact of binary target 'MyPackage' has changed checksum; this is a potential security risk so the new artifact won't be downloaded. This error can be ignored by deleting the entire DerivedData on folder, but that's obviously not updating the version number. Another solution is suggested in this answer, but again it doesn't affect versioning. The official documentation writes extensively about dependent package versions, but I cannot find how to specify the version of the CURRENT package.
How can I legitimately specify and update the version number so the new artifact gets identified as a distinct new version and downloaded properly?
When you want to distribute (privately or publicly) a closed source package using an xcframework file you typically need to create a git repository that only contains the Package.swift file in which you declare the binaryTarget. (or the binaryTargets) Whichever have access to this repository should also have access to the url that you declare in the binaryTarget in order to install your package.
As #Larme and #matt correctly mentioned in the comments, to specify which commit correspond to each version, you have to use tags in the git repository exactly like you do in a cocoapod repository, only you will do this in a repository that contains only the Package.swift file. See "Tag Your Latest Commit" section in the Publishing a Swift Package with Xcode documentation for more details.
You can use as an example the PSPDFKit, which is a known and well maintained closed source package that can be installed using this github repository.

Swift Package Manager - Dependency on active branch doesn’t pull new commits

I'm writing a Swift Package that relies on another package that I manage (Netswift). I've setup a bleeding_edge branch there, where I commit every few hours (i.e when I notice access control is wrong, or any other minor edit).
Now my current package has a dependency on the github repo for Netswift, with that bleeding_edge branch, as pictured below:
dependencies: [
.package(url: "https://github.com/MrSkwiggs/Netswift", .branch("bleeding_edge")),
]
Unfortunately, resolving the dependency graph by any of the following means (updating Package.swift with an empty space somewhere, running swift package update) does not pull new commits from that branch.
The only way I found to force-update is to specify a different branch, resolve dependency graph, then revert back to the branch I actually need, then resolve dependency graph again.
Is there a better way to force-update the dependency graph?
I also don't want to add a target with an absolute path to this other local package, as colleagues will also need to rely on this at some point in the future.
You need to use XCode's built-in package update functionality, which can be found under:
File -> Swift Packages -> Update to Latest Package Versions
Running swift package update only works when the package is being worked on as a standalone; if the package is being edited through an existing XCode project/workspace then you need to let XCode handle it.

Swift Package Manager dependency in a repository subdirectory

I have a Swift package in a subdirectory of a git repository inside GitHub. The tree looks something like this:
.
├── swift-package
│ ├── Package.swift
│ └── Sources
│ └── SomeLibrary
│ └── Library.swift
└── some-other-files
I want to add swift-package as a dependency to another project.
But the only way of specifying a dependency using Swift Package Manager I know is when the package is at the top level of the repository:
dependencies: [
.package(url: "http://github.com/Some/Repository", from: "1.2.3"),
],
What I would need would be something along the lines of .package(url: "http://github.com/Some/Repository, dir: "swift-package"...).
I have no way of moving out the package to a separate repository.
Is there any way to achieve something like this using Swift Package Manager? If not, what are my options? Also, what is the best way to submit a feature request to Swift Package Manger developers?
You can not have two Swift packages in the same git repository. The Swift Package manager defines a package as:
Packages are Git repositories, tagged with semantic versions, containing a Package.swift file at their root. Initializing the
package created a Package.swift file, but to make it a usable package
we need to initialize a Git repository with at least one version tag.
Your options are to either have separate repositories/packages for your dependencies, or use one repository and move the code in separate modules/targets.
If you need to submit a feature I would first start a discussion in the Swift forums describing your goals and requesting feedback from the community. The code for the Swift PM is hosted in github you can always submit a pull request with a new feature. More information about the process is described here.
Not exactly the proper answer, but I wonder if, as a workaround, we could add the corresponding repo as Git submodule, and then integrate the package as a local package from the corresponding subdirectory. We would lose the ability to update (or change the version of) the package via SPM, though. On the other hand, we would still be able to control the version of the package, by pinning the Git submodule to version tags (or branches/commits/whatever), that should be there in Git repository anyway for SPM, if I recall it correctly.

How to use git master of gst-omx (gstreamer1) for the buildroot package?

I'm testing the current buildroot 2016.02-rc2 release. It contains gstreamer1 packages for version 1.6.3, but I would like to build 1.7.2 instead. I successfully updated package definitions for gstreamer1 and the most important plugins to use 1.7.2. However gst-omx has only a 19 months old release archive for the version 1.2.0 for the direct download (https://gstreamer.freedesktop.org/src/gst-omx/) and it fails to compile. So I would like to use the latest version from git repo.
How can I do it? git repository contains a "common" submodule which buildroot's build system cannot handle as it seems. I thought about creating a new release tar.xz package, that would contain everything for building it like all other gstreamer packages, but couldn't find out how those tar.xz packages on the server are generated...
There is indeed no support for submodule in Buildroot, since most of the time, submodules should be packaged as separate packages.
So, for your own testing, you have two options:
1/ You can do a quick test by creating yourself a tarball that contains all the gst-omx source code (including the contents of the common/) subdirectory.
2/ You can package the gstreamer common stuff as a separate package, make your gst-omx package depend on it, and in a pre-configure hook, create a symlink $(#D)/common -> $(GSTREAMER_COMMON_DIR)