Giter Site home page Giter Site logo

swiftdependencymagnet's Introduction

SwiftDependencyMagnet

The Problem

Have you ever thought to youself:

I really want to love the Swift Package Manager. But it's so annoying when Xcode is constantly "Resolving Package Graph" and interrupting my workflow.

Yes, it can be annoying. On a project with a moderate amount of SPM dependencies, Xcode seems to randomly re-resolve the package graph for 15-30 seconds (or more) any time a mote of dust hits your project the wrong way.

Assuming that most of your dependencies are hosted on remote git repos, a fair bit of this time is spent dealing with the latency of checking the state of those remote repos, and resolving the version graph.

The Solution

SwiftDependencyMagnet lets you remove the 'remote' aspect of your SPM dependencies from the perspective of your build tools, and SPM does not require version resolution for local packages.

You declare the top-level dependencies that your project uses. The magnet uses SPM to resolve the graph and put all of your dependencies (and their sub-dependencies) in a local directory. All of their Package.swift contents are relinked so that they refer to the local versions as well.

You now have full control over when package/version resolution occurs.

Installation

Using Package.swift

Add SwiftDependencyMagnet to your Package.swift file:

.package(url: "https://github.com/jmfieldman/SwiftDependencyMagnet.git", from: "<version>")

Swift PM will automatically detect the executable target, so you can now run the executable through your own package:

$ swift run dependency_magnet <params>

Standalone (Mint)

If you want a more streamlined execution experience, try installing SwiftDependencyMagnet using the very nice Mint Package Manager.

Mint builds each Swift executable in its own environment, tracks versions, and supports localized version-pegging through a Mintfile. This avoids continuous, unnecessary rebuild-checks when your own project's Package.swift changes.

# Install mint on your system, e.g.
$ brew install mint

# Install SwiftDependencyMagnet (recommended: bypass this using the Mintfile)
$ mint install jmfieldman/SwiftDependencyMagnet

# Run SwiftDependencyMagnet using Mint. This is the recommended method if you plan
# on using a Mintfile for version-pegging
$ mint run dependency_magnet <..>

# Or run it directly if you have the Mint bin directory in your path
$ dependency_magnet <..>

Using SwiftDependencyMagnet

Create the top-level folder Dependencies and put your dependencies.yml configuration inside it:

Dependencies
    +--- dependencies.yml # contains a list of your dependencies

Your dependencies.yml file will look something like:

dependencies:
  - url: https://github.com/apple/swift-argument-parser
    exact: 1.3.1
  - url: https://github.com/jpsim/Yams.git
    from: 5.0.6    
    
# Each dependency must have a URL and one qualifier.
# Valid qualifiers are: exact, from, range, closedRange, branch, revision

Run the pull command:

$ swift run dependency_magnet pull
<SwiftPM resolution>
🧲 Importing [swift-argument-parser @ 1.3.1]
🧲 Importing [Yams @ 5.1.0]

At which point you will now have the following new files in your directory:

.dependency_magnet        # This is the shadow workspace; safe to .gitignore
    |
    +--- Package.resolved # The Package.resolved file in the shadow workspace
    |                     # This file is pulled from the source-controlled version
    |                     # before every sync.
    |
    +--- Package.swift    # The Package.swift file in the shadow workspace, which
    |                     # is auto-generated based on your dependencies.
    |
    +--- .build           # Where SwiftPM has pulled remote dependencies
    
Dependencies
    +--- dependencies.yml # Your dependencies configuration.
    |
    +--- Package.resolved # A source-controllable location for Package.resolved
    |                     # Make sure this is checked in to ensure that all
    |                     # users get the same versions of your dependencies.
    |
    +--- Packages         # This is where your locally-configured dependencies
         |                # live, and where you will point your Package.swift to.
         |                # Add this to your .gitignore to avoid recommitting all
         |                # of your dependencies to your main repo.
         |
         +--- swift-argument-parser
         +--- Yams
         +--- ...

The package files in Dependencies/Packages are automatically updated to use sub-dependencies that are also in the same directory.

Updating .gitignore

It is recommended that you add the following to .gitignore:

.dependency_magnet
Dependencies/Packages/

Using Package.swift

If are using your own Package.swift file, you can now reference your locally-based dependencies like so:

let package = Package(
  ...
  products: [...],
  dependencies: [
    .package(path: "Dependencies/Package/swift-argument-parser"),
    .package(path: "Dependencies/Package/Yams"),
  ],
  targets: [...]
)

Using Xcode

If you are using an Xcode-based project, you can select File > Add Package Dependencies... and then select the Add Local button to choose your local top-level dependencies.

Using Xcodegen

if you are using the wonderful Xcodegen utility, you can use the packages directive to point to your new local paths:

packages:
  Yams:
    path: Dependencies/Package/Yams
  MyCoolLibrary:
    path: Dependencies/Package/MyCoolLibrary

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.