Find all files named: Package.swift
or find Xcode's project file named: project.pbxproj
.
We will not scan .build
directory if the Package.swift
or Xcode project file is discovered.
Strategy | Direct Deps | Transitive Deps | Edges | Classifies Test Dependencies | Container Scanning |
---|---|---|---|---|---|
Parse dependencies from Package.swift |
✅ | ❌ | ❌ | ❌ | ✅ |
Parse dependencies from Package.swift and Package.resolved |
✅ | ✅ | ❌ | ❌ | ✅ |
Parse dependencies from Xcode's project.pbxproj |
✅ | ❌ | ❌ | ❌ | ✅ |
Parse dependencies from Xcode's project.pbxproj and Package.resolved |
✅ | ✅ | ❌ | ❌ | ✅ |
- Manifest file:
Package.swift
, must begin with// swift-tools-version:
string, followed by version number specifier. - We follow swift package manager's convention and presume properties of the package are defined in a single nested initializer statement and are not modified after initialization.
- Valid Xcode project for swift, is defined by the discovery of
project.pbxproj
file in ASCII plist format with at least oneXCRemoteSwiftPackageReference
object in its content.
- Path dependencies are ignored in the analysis (e.g.
package(path: "./../local-pkg")
) - If the Xcode project dependencies are sourced via a local path, they will be ignored in the analysis.
- Only Xcode project files in ASCII plist format with UTF-8 encoding are supported.
Create Package.swift file in the directory. Add dependencies, targets, products, and source code. Example Package.swift file is shown below. By convention, the properties of a Package are defined in a single nested initializer statement, and not modified after initialization.
// swift-tools-version:5.4.0
import PackageDescription
let package = Package(
name: "Example",
defaultLocalization: "en",
products: [],
dependencies: [
.package(name: "grpc-swift", url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"),
]
)
We can update and resolve dependencies by performing swift package update
. Executing this will create Package.resolved in the directory. An example file is shown below:
{
"object": {
"pins": [
{
"package": "grpc-swift",
"repositoryURL": "https://github.com/grpc/grpc-swift.git",
"state": {
"branch": null,
"revision": "14e1ea3350892a864386517c037e11fb68baf818",
"version": "1.3.0"
}
},
{
"package": "swift-log",
"repositoryURL": "https://github.com/apple/swift-log.git",
"state": {
"branch": null,
"revision": "5d66f7ba25daf4f94100e7022febf3c75e37a6c7",
"version": "1.4.2"
}
}
]
},
"version": 1
}
Note: Only a few pins are shown above for brevity.
When the analysis is performed (e.g. fossa analyze -o
), we will identify the following as direct dependencies:
- https://github.com/grpc/grpc-swift.git with version 1.3.0
If Package.resolved
is discovered, the following transitive dependencies will be identified, however, we will not identify the edges in the dependency graph:
- https://github.com/apple/swift-log.git with version 1.4.2
If Package.resolved
is not discovered, only direct dependencies will be reported.
For Xcode project using swift package manager to manage swift package dependencies, Xcode project file named project.pbxproj
will be analyzed. In the Xcode project file, XCRemoteSwiftPackageReference
objects will be used to identify swift packages that are direct dependencies. For the analysis, at least one such reference must exist in the file. If no such references are found, we will not consider the Xcode project in the swift analysis.
Excerpt from example project.pbxproj
:
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
...
170A463726ECEDEF002DDFB8 /* XCRemoteSwiftPackageReference "example-package-deckofplayingcards" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/example-package-deckofplayingcards";
requirement = {
branch = main;
kind = branch;
};
};
...
};
rootObject = 17874CD926C46B8500D16CA8 /* Project object */;
}
If the Package.resolved
is discovered, transitive dependencies will be identified. If not, only direct dependencies listed in xcode project file will be identified. In either case, no edges among dependencies will be reported.
You can explicitly specify the analysis target in .fossa.yml
file.
The example below will exclude all analysis targets except swift.
# .fossa.yml
version: 3
targets:
only:
- type: swift
Swift packages sourced from local directories are not discovered in the analysis. Is there a workaround?
This is a current limitation. For swift package manager analysis, we only support non-path dependencies at the moment.
To include local dependencies, you can use fossa-deps.yml
file to upload the local package for license scanning and analysis.
# in fossa-deps.yml
vendored-dependencies:
- name: MyLocalPackage
path: /Jenkins/App/Resources/MyLocalPackage # path can be either a file or a folder.
version: 3.4.16 # revision will be set to the MD5 hash of the file path if left unspecified.
Note: License scanning currently operates by uploading the files at the specified path to a secure S3 bucket. All files that do not contain licenses are then removed after 2 weeks. Refer to vendored dependencies for more details.
For swift, we consider the Xcode project to be a valid Xcode project, if and only if it meets the following requirements:
- Xcode project file named:
project.pbxproj
exists in the directory. - Xcode project file must be in ASCII plist format with UTF-8 encoding.
- Xcode project file has at least one object, with isa of
XCRemoteSwiftPackageReference
.