Git Product home page Git Product logo

accio's People

Contributors

acecilia avatar fredpi avatar jeehut avatar knothed avatar mrylmz avatar revolter avatar tcurdt avatar tonyarnold avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

accio's Issues

Add command to test support of frameworks

Some frameworks might want to test their Accio support on a CI. As of now, there is no command to test if a framework itself is Accio compatible, the only solution is a workaround where one would need to create a Package.swift file which includes the framework to be tested. This is no good solution for a CI, therefore Accio should provide an internal way of testing Accio installation of a framework.

Note though, that in practice a framework that supports SwiftPM and Carthage will always also support Accio. But projects bundling resources can't have real SwiftPM support at the moment, therefore adding a command for testing Accio support definitely is needed for those projects.

Building via Carthage may result in misleading output

Configuration

The Package.swift of a project includes dependency A. A itself has its Package.swift declared, requiring subdependency B. A is also Carthage-compatible, meaning it has a Cartfile referencing B.

Issue

Accio is smart, so it will build B before building A. Now, if A is built via Carthage, Accio will also copy the build result of B into the Carthage/Build/ folder within the A checkout. After that, the carthage build command is invoked, passing the platform to build for. Carthage will now parse the Cartfile of A if it exists (if A is Carthage-compatible, it will exist).

If the parsing goes well, Carthage will build A using the build result of B that was copied into the Carthage/Build/ folder within the A checkout. Yet, if the parsing doesn't go well, e. g. because B doesn't have a specific shared iOS scheme while the platform passed to the Carthage build command is iOS, there will be an output originating from Carthage similar to this one:

✨  Building library RxGesture with Carthage ...
*** xcodebuild output can be found in /var/folders/r6/ylx9g2f91bxcy402jv2w_3fh0000gn/T/carthage-xcodebuild.QYGDy2.log
*** Skipped building RxSwift due to the error:
Dependency "RxSwift" has no shared framework schemes for any of the platforms: iOS

If you believe this to be an error, please file an issue with the maintainers at https://github.com/ReactiveX/RxSwift/issues/new
*** Building scheme "RxGesture-iOS" in RxGesture.xcodeproj
✨  Completed building scheme RxGesture with Carthage.

However, because RxSwift has already been built via Accio before and copied to Carthage/Build/ folder within the A checkout, this doesn't have any effect, but may irritate the user.

Solution

We can simply fix this misleading output by removing the Cartfile and Cartfile.resolved just before invoking the carthage build command:

// remove Cartfile before carthage build as subdependencies have already been built via Accio
try bash("rm -rf '\(framework.projectDirectory)/Cartfile'")
try bash("rm -rf '\(framework.projectDirectory)/Cartfile.resolved'")

This way, Carthage will just build and do nothing else.

No dependencies specified for target ...

Hello!
I'm excited to use Accio and I've started converting a project over to using SwiftPM's Package.swift to be able to.

However one of the dependencies of the project can't be resolved automatically (it doesn't use default folder structure, has targets using overlapping source...). I've tried creating a simple Package.swift to specify custom source folders (and only support one target 🙄) but it seems SwiftPM requires my target have at least one dependency. When I test the dependency's Package.swift file against Accio I get this:

❯ accio install
✨  Reverting any changes in the checkouts directory ...
✨  Resolving dependencies ...
✨  Reading package manifest at /Users/ian/Documents/Adorkable/Eunomia/Package.swift ...
✨  Generating dependency graph ...
⚠️  No dependencies specified for target 'Eunomia-iOS'. Please add at least one dependency scheme to the 'dependencies' array of the target in Package.swift.
Error: The file “Package.resolved” couldn’t be opened because there is no such file.

For reference the dependency can be found here.

This is likely more a lack of understanding of how I should be writing for SwiftPM and me not fully grasping its usage, let me know if this is the right or wrong place to have this discussion.

Error reverting changes in the checkouts directory

In my current configuration (with only 1 package), I somehow managed to break the ✨ Reverting any changes in the checkouts directory ... step. The following problem occurs: An error occurred: Command '/bin/bash -c "git -C '/[MyProjectPath]/.accio/checkouts/PMJSON' reset HEAD --hard --quiet 2> /dev/null"' returned with error code 128.

When I copy this repo to another folder and run the failing command (git -C '[NewPath]/PMJSON' reset HEAD --hard) manually, there's still an error: fatal: Could not parse object 'HEAD'.

Maybe this problem is related to the fact that after initializing accio and then switching to a branch where it wasn't installed yet, I performed a Reset All of the original repo via Sourcetree to reset the .accio folder. Maybe this had an effect on the recursive subrepos (those within .accio/checkouts), so that after switching to the accio branch again, running accio install failed. Still weird, that the checkouts folder survived the git reset... 🤔

Improve init command to fill empty Package.swift file

In some situations, users might create an empty Package.swift file and run the init command afterwards. Accio might want to add a check if the Package.swift file is empty and if it is, it could still fill it with the skeleton contents to provide a place to start. Currently, just nothing happens in such cases.

Is it possible to choose if the generated framework for a dependency is static or dynamic?

Hi :)

Just discovered Accio, sounds very promising.
My question is: is it possible to choose which kind of framework to generate for a dependency, dynamic or static?

Let me add some context to the question. Recently, there is an ongoing conversation in the community about which are better: dynamic or static frameworks (see for example ReactiveX/RxSwift#1960). Seems like static frameworks allow for faster launch times and smaller app bundles (as static linking allows to remove unused symbols). At the moment, when using Carthage, the author of the dependency is the one configuring the Xcode project and selecting how the framework is going to be generated: dynamic or static. Consumers of the dependencies have to rely on hacks in order to generate a static framework.

As mentioned here:

Consumer should decide how they want to consume the library not the library authors. Library authors should decide on the API and code only.

Is this possible with Accio?

Thanks,
Andres

Clarification on Carthage requirement?

HI @Dschee, thank you for this great project!

I'm a bit confused by Carthage being a requirement stated in README. As far as I understand, SwiftPM is used for dependency resolution, but most of the explanation in README focused on comparing Accio to Carthage. My understanding was that Accio is able to replace Carthage fully in a given project?

Hope this can be clarified, I'd be happy to submit a PR that makes this clear in the README as soon as I have a better understanding of this.

Linking problems with apps split into modules

When an app has multiple targets with the same platform, e.g. an „App“ target an an „AppKit“ target and both include the same framework, then Accio currently adds only a single framework to the group properly. It seems to try to add a second link, too, but fails - Xcode is placing the second under „Reconstructed Links“ (or similar).

A workaround is to link the frameworks manually, Accio correctly handles them on updates from then on. But Accio should link them correctly in the first place.

Cache mixes up different Swift versions

When caching frameworks, Accio differentiates between different Swift versions, so that a user having set Xcode 10.2.1 as their command line tools won't get cached frameworks originating from a user that has Xcode 11 set as their command line tools. That's needed, as otherwise, Xcode would complain that the frameworks have been built with Swift 5.1, while the user is still running Xcode 10.2.1 with Swift 5.0.1.

So, it's perfectly valid to separate by Swift version. However, the implementation doesn't work properly, as the Swift version is retrieved on compile time of Accio:

static var swiftVersion: String {
    #if swift(>=6.0)
        return "Swift-6.0"
    #elseif swift(>=5.2)
        return "Swift-5.2"
    #elseif swift(>=5.1)
        return "Swift-5.1"
    #elseif swift(>=5.0)
        return "Swift-5.0"
    #else
        return "Swift-4.2"
    #endif
}

This works quite often, as the Accio-compile-time Swift version is likely to match the current Swift version, but in transition periods (like now, switching from Swift 5.0 to Swift 5.1), this is a real issue: The folder that should store Swift 5.0 builds may now also include Swift 5.1 builds and the other way round.

To get things to work, the swift version should instead be retrieved via the swift --version command during runtime.

dyld: Symbol not found: _$s11ReactiveKit7NoErrorON

For some frameworks with subdependencies like Bond, when running the app in the Demo project, the simulator fails with the following error:

dyld: Symbol not found: _$s11ReactiveKit7NoErrorON
  Referenced from: /Users/Me/Library/Developer/CoreSimulator/Devices/4238123B-BA44-4806-A8CC-A24998F275BA/data/Containers/Bundle/Application/8B87D39E-79A6-43BD-810D-70A2EA4AA6BC/Demo-iOS.app/Frameworks/Bond.framework/Bond
  Expected in: /Users/Me/Library/Developer/CoreSimulator/Devices/4238123B-BA44-4806-A8CC-A24998F275BA/data/Containers/Bundle/Application/8B87D39E-79A6-43BD-810D-70A2EA4AA6BC/Demo-iOS.app/Frameworks/ReactiveKit.framework/ReactiveKit
 in /Users/Me/Library/Developer/CoreSimulator/Devices/4238123B-BA44-4806-A8CC-A24998F275BA/data/Containers/Bundle/Application/8B87D39E-79A6-43BD-810D-70A2EA4AA6BC/Demo-iOS.app/Frameworks/Bond.framework/Bond

This also happens when Moya and a different version of Alamofire are specified with Moya stating that it couldn't find Alamofire. The supposedly missing frameworks are actually existent though. So this might only be a linking issue within the frameworks using them as subdependency. The weird part though is that building works, which shouldn't be possible if the required frameworks are missing ... this needs further investigation and tests.

Can't build package dependent on package

I've a swift package which depends on SwiftSyntax/libsyntax. When I use accio to use my swift package in an macOS app, it fails building my package. It seems that the error is when building with Carthage, where the files from SwiftSyntax is missing (see the attached log).

I've created a sample project, which is a macOS app with only my package as dependency. It can be found at https://github.com/MortenGregersen/accio-bug-sample

I've added a Cartfile to the sample project just to test if I could build the package with Carthage - this also fails.

Can anyone see what I am doing wrong?

Here is the console output:
➜  accio-bug-sample git:(master) accio install
✨  Resolving dependencies ...
Fetching https://github.com/apple/swift-package-manager.git
Fetching https://github.com/apple/swift-syntax.git
Fetching https://github.com/MortenGregersen/SwiftCodeCodable.git
Completed resolution in 4.12s
Cloning https://github.com/apple/swift-syntax.git
Resolving https://github.com/apple/swift-syntax.git at 0.50000.0
Cloning https://github.com/MortenGregersen/SwiftCodeCodable.git
Resolving https://github.com/MortenGregersen/SwiftCodeCodable.git at libsyntax
Cloning https://github.com/apple/swift-package-manager.git
Resolving https://github.com/apple/swift-package-manager.git at 0.3.0
✨  Reading package manifest at /Users/morten/MoGee/Projects/accio-bug-sample/Package.swift ...
✨  Generating dependency graph ...
✨  Resolving dependencies for target 'MyApp' on platform 'macOS' ...
✨  Found cached build products for SwiftSyntax in local cache - skipping build.
✨  Building library SwiftCodeCodable with Carthage ...
*** xcodebuild output can be found in /var/folders/88/94r4q5r907b0t0bj8mj69qth0000gn/T/carthage-xcodebuild.v6jVq9.log
*** Building scheme "SwiftCodeCodable-Package" in SwiftCodeCodable.xcodeproj
Build Failed
	Task failed with exit code 65:
	/usr/bin/xcrun xcodebuild -project /Users/morten/MoGee/Projects/accio-bug-sample/.accio/checkouts/SwiftCodeCodable/SwiftCodeCodable.xcodeproj -scheme SwiftCodeCodable-Package -configuration Release ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/88/94r4q5r907b0t0bj8mj69qth0000gn/T/SwiftCodeCodable SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO (launched in /Users/morten/MoGee/Projects/accio-bug-sample/.accio/checkouts/SwiftCodeCodable)

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/88/94r4q5r907b0t0bj8mj69qth0000gn/T/carthage-xcodebuild.v6jVq9.log
An error occurred: Command '/bin/bash -c "/usr/local/bin/carthage build --project-directory '/Users/morten/MoGee/Projects/accio-bug-sample/.accio/checkouts/SwiftCodeCodable' --platform macOS --no-skip-current --no-use-binaries"' returned with error code 1.

carthage-xcodebuild.v6jVq9.log

Support modularization within app project

Currently, Accio supports modularization of frameworks and using those in App projects. But sometimes one might want to modularize the app itself into several parts, for example consider this:

// swift-tools-version:5.0
import PackageDescription

let package = Package(
    name: "App",
    products: [
        .library(name: "AppKit", targets: ["AppKit"])
    ],
    dependencies: [],
    targets: [
        .target(
            name: "App",
            dependencies: ["AppKit"],
            path: "App"
        ),
        .target(
            name: "AppKit",
            dependencies: [],
            path: "AppKit"
        ),
    ]
)

When we run accio update today with such a setup, we get this error output:

❌  DependencyGraph: Could not find library product with name 'AppKit' in package manifest for project 'App'.

Rebuild dependencies when Swift version changed

#60 introduced a bug that causes dependencies not to be rebuilt or downloaded from cache although the Swift version changed.

To fix this, the Swift versions in the cached manifest should be parsed and compared against the current Swift version. If there's a difference, Accio shouldn't return saying Found all required build products specified in resolved manifest in cache – skipping checkout & integration process ...

install error

Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.6.0
/Applications/Xcode.app/Contents/Developer/usr/bin/lldb "--repl=-enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -color-diagnostics"
Welcome to Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.4).
brew install accio
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
No changes to formulae.

==> Installing accio from jamitlabs/accio
==> Cloning https://github.com/JamitLabs/Accio.git
Updating /Users/pynix/Library/Caches/Homebrew/accio--git
==> Checking out tag 0.6.1
HEAD is now at 6b01bd6 Merge branch 'deploy/0.6.1' into productive
HEAD is now at 6b01bd6 Merge branch 'deploy/0.6.1' into productive
==> make install prefix=/usr/local/Cellar/accio/0.6.1
Last 15 lines from /Users/pynix/Library/Logs/Homebrew/accio/01.make:
Resolving https://github.com/kylef/PathKit at 1.0.0
Cloning https://github.com/onevcat/Rainbow.git
Resolving https://github.com/onevcat/Rainbow.git at 3.1.5
Cloning https://github.com/jakeheis/SwiftCLI.git
Resolving https://github.com/jakeheis/SwiftCLI.git at 5.2.2
Cloning https://github.com/kareman/SwiftShell.git
Resolving https://github.com/kareman/SwiftShell.git at 4.1.2
Cloning https://github.com/Flinesoft/HandySwift.git
Resolving https://github.com/Flinesoft/HandySwift.git at 2.8.0
Cloning https://github.com/kylef/Spectre.git
Resolving https://github.com/kylef/Spectre.git at 0.9.0
Cloning https://github.com/tuist/Shell
Resolving https://github.com/tuist/Shell at 2.0.3
'XcodeProj' /private/tmp/accio-20190528-59953-e4mzwa/.build/checkouts/xcodeproj: error: could not find source files for target(s): XcodeProj; use the 'path' property in the Swift 4 manifest to set a custom target path
make: *** [accio] Error 1

If reporting this issue please do so to (not Homebrew/brew or Homebrew/core):
  jamitlabs/accio

/usr/local/Homebrew/Library/Homebrew/utils/github.rb:258:in `raise_api_error': Validation Failed: [{"message"=>"The listed users and repositories cannot be searched either because the resources do not exist or you do not have permission to view them.", "resource"=>"Search", "field"=>"q", "code"=>"invalid"}] (GitHub::ValidationFailedError)
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:212:in `open_api'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:357:in `search'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:265:in `search_issues'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:278:in `issues_for_formula'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:374:in `fetch_issues'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:370:in `issues'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:424:in `dump'
	from /usr/local/Homebrew/Library/Homebrew/brew.rb:141:in `rescue in <main>'
	from /usr/local/Homebrew/Library/Homebrew/brew.rb:38:in `<main>'

Performance improvments on re-runs without updates

Currently, when the "install" command is run for a second time, all dependency resolution and framework copying is redone and takes quite some time. Instead, we could save a hash of the Package.resolved to the cache with a file named after the hash (e.g. abcd.json) which could contain the hashes of all the .framework and .dsym files required, including the commit hash and framework name (info needed for the cache lookup).

Now when the hash file already exists, we could simply check if the existing .framework and .dsym files in the folder already have the correct hash and skip any copying steps (this can also improve performance of the update command). Also since the hash file exists, we can completely skip the dependency resolution if all dependencies are already cached (only useful for the install command).

This should be implemented after performance tests are written with some example project for the following situations:

  • run "install", then re-run "install"
  • run "update", then re-run "update"
  • run "update", change one libraries version requirement, then re-run "update"

All three cases should have performance improvements. The last example is expected to have only small performance improvements while the first two cases should be nearly twice as fast.

New Option: Use SwiftPM for building when possible

Currently this projects uses Carthage for building frameworks. While this especiallly is a great solution for frameworks specifically written for iOS etc. (#18 being an improvement which drops the Carthage requirement), some libraries were written for SwiftPM usage only and might not integrate well with the current approach in Accio.

For example, when I tried adding NIOTransportServices to an iOS application, it build all just fine with Accio but then when running the app, I got linker errors and the app crashed.

Maybe the approach described in this article or used by this tool might work better in such cases.

Therefore investigating other approaches of building and integrating frameworks could bring Accio another step forward. This doesn't mean we should remove the current behavior though, I more feel like this would be an option one might choose for specific libraries or Accio could even figure out itself, which libraries this approach should be applied to.

Integrate Swift library with mixed dependencies

Thank you for your work on Accio!

I'm considering adding Accio support to Telegraph, but I have a few questions.

  1. Telegraph itself is 100% Swift, but it has dependencies that contain Objective-C and C. Will I be able to use Accio for Telegraph?

  2. Should the dependent projects (HTTPParserC and CocoaAsyncSocket) also have a Package.swift file?

  3. Telegraph has a workspace with separate OS targets (iOS, macOS, tvOS), some tests and an examples project. Will there be additional steps required for people to try out the examples when I switch to Accio (I'm now using Carthage)? Is there perhaps a similar library that is already using Accio that I can have a look at?

  4. Does Accio play well with Travis?

Unable to install Accio via brew

I tried to install Accio on my company Mac and stumbled upon an issue installing it.

I‘m not quite sure if it relates to Accio directly, though.

Current configuration:

  • macOS Mojave 10.14.4 (18E226)
  • Xcode 10.2.1 (freshly installed from the App Store)
  • Fresh installation of brew
  • Swift 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)

Running brew install accio results in:

rion$ brew install accio
Updating Homebrew...
==> Installing accio from jamitlabs/accio
==> Cloning https://github.com/JamitLabs/Accio.git
Updating /Users/abraun/Library/Caches/Homebrew/accio--git
==> Checking out tag 0.6.1
HEAD is now at 6b01bd6 Merge branch 'deploy/0.6.1' into productive
HEAD is now at 6b01bd6 Merge branch 'deploy/0.6.1' into productive
==> make install prefix=/usr/local/Cellar/accio/0.6.1
Last 15 lines from /Users/rion/Library/Logs/Homebrew/accio/01.make:
2019-04-29 15:13:48 +0200


make
install
prefix=/usr/local/Cellar/accio/0.6.1


dyld: Library not loaded: @rpath/llbuild.framework/Versions/A/llbuild
  Referenced from: /Library/Developer/CommandLineTools/usr/bin/swift-build
  Reason: image not found
make: *** [accio] Abort trap: 6


If reporting this issue please do so to (not Homebrew/brew or Homebrew/core):
  jamitlabs/accio


/usr/local/Homebrew/Library/Homebrew/utils/github.rb:253:in `raise_api_error': Validation Failed: [{"message"=>"The listed users and repositories cannot be searched either because the resources do not exist or you do not have permission to view them.", "resource"=>"Search", "field"=>"q", "code"=>"invalid"}] (GitHub::ValidationFailedError)
from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:207:in `open_api'
from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:352:in `search'
from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:260:in `search_issues'
from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:273:in `issues_for_formula'
from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:372:in `fetch_issues'
from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:368:in `issues'
from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:422:in `dump'
from /usr/local/Homebrew/Library/Homebrew/brew.rb:136:in `rescue in <main>'
from /usr/local/Homebrew/Library/Homebrew/brew.rb:36:in `<main>'

Add Accio to Homebrew Core

Now that Accio has passed the 50 stars, before everyone gets used to installing Accio via its Tap too much, we should try adding it to Homebrew Core. That also seems reasonable now given that Accio has stabilized a lot lately.

Project with mixed languages is not supported?

It seems that the framework may not support a (Swift based) project containing one or more Obj-c files. All dependencies could be resolved but the dependency graph not.

Log:

✨ Resolving dependencies ...
⏳ Executing 'swift package --package-path '/Users/.../Project-iOS' --build-path '/Users/.../Project-iOS/.accio' resolve'
✨ Reading package manifest at /Users/.../Project-iOS/Package.swift ...
✨ Generating dependency graph ...
❌ 'Project-iOS' /Users/.../Project-iOS: error: target at '/Users/.../Project-iOS/App' contains mixed language source files; feature not supported
An error occurred: dependencyGraphGenerationFailed

Improve init command to detect test targets as such

Currently, when I run something like this:

accio init --project-name "Demo" --target-name "Demo,DemoTests"

Accio will create a Package.swift manifest file with to .targets, but what I actually expect is that it automatically detects that the second target actually is of .testTarget type and automatically initializes it like that.

Leverage Swift 5.1 module stability

An idea originating from #62, if the Swift version, let it be v, is greater than 5.1 (the Swift version where module stability is introduced), the cache should also be looked up for versions built with a version w, v ≥ w ≥ 5.1. If a cached build product with version w is found, then it can be used, even with Swift version v.

Drop Carthage requirement by replicating the `build` command

As a consequence of #17 it could make sense to integrate the used parts of Carthage right into Accio to prevent having Carthage as a dependency. This could also fix any issues that might arise in the future due to any changes in Carthage or people using Accio with an old version of Carthage. Also, we could fix any issues within the build command faster than Carthage does if such a situation arises.

Use FileManager for file operations

An idea originating from #40 is to use FileManager for file operations instead of using commands like

try! bash("mkdir '\(path)'")
try! bash("rm -rf '\(path)'")

I benchmarked the rm -rf command against FileManager.default.removeItem(atPath:) and noticed that for folders only containing a few files FileManager.default.removeItem(atPath:) is roughly 2 times faster than rm -rf (0.06s vs 0.025s). However, when I copied a large iOS project into the folder whose deletion I benchmarked, rm -rf performed better (average of 1.6s) vs. FileManager.default.removeItem(atPath:) (average of 1.9s).

Speed-wise, rm -rf is probably the better approach, yet style-wise I prefer FileManager.

What are your thoughts on this?

Add Firebase SDKs to AccioSupport

It is really common that the firebase SDKs are used inside iOS Projects to improve the migration experience we could add Accio support for every Firebase Project targeting iOS.

Be excellent to each other

I found the rambling hit piece on the maintainers of Carthage in your read me to be pretty confronting.

I believe you're doing your own OSS project & contributions a disservice by dunking on other unpaid OSS maintainers.

Your justification for building this tool stands up without needing to take a swipe at Carthage's maintainers — I'd urge you to think about rewording your readme to make it about the positive aspects of why your project is a good choice.

Unable to successfully compile the sample project

# OS
ProductName:    Mac OS X
ProductVersion: 10.14.5
BuildVersion:   18F132

# Xcode
Xcode 10.2.1
Build version 10E1001
iOS SDK 12.2

# Swift
Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.6.0

Procedure

  1. Create the sample project
$ mkdir -p SwiftDemo && cd SwiftDemo && swift package init --type library

(structures) =>
.
├── Package.swift
├── README.md
├── Sources
│   └── SwiftDemo
│       └── SwiftDemo.swift
└── Tests
    ├── LinuxMain.swift
    └── SwiftDemoTests
        ├── SwiftDemoTests.swift
        └── XCTestManifests.swift

4 directories, 6 files
  1. Add Alamofire as dependency
// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
	name: "SwiftDemo",
	products: [
		// Products define the executables and libraries produced by a package, and make them visible to other packages.
		.library(
			name: "SwiftDemo",
			targets: ["SwiftDemo"]),
	],
	dependencies: [
		// Dependencies declare other packages that this package depends on.
		// .package(url: /* package url */, from: "1.0.0"),
		.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.0.0-beta.5"),
	],
	targets: [
		// Targets are the basic building blocks of a package. A target can define a module or a test suite.
		// Targets can depend on other targets in this package, and on products in packages which this package depends on.
		.target(
			name: "SwiftDemo",
			dependencies: ["Alamofire"]),
		.testTarget(
			name: "SwiftDemoTests",
			dependencies: ["SwiftDemo"]),
	]
)
  1. Generate the Xcode project
$ swift package generate-xcodeproj
  1. Initialize Accio
$ accio init -p SwiftDemo -t SwiftDemo

(outputs) =>
⚠️  A non-empty Package.swift file already exists, skipping template based creation.
✨  Adding .gitignore entries for build & dependencies directories.
✨  Successfully initialized project.
  1. Install or update using Accio
$ accio install

(outputs) =>
Fetching https://github.com/Alamofire/Alamofire.git
Completed resolution in 40.34s
Cloning https://github.com/Alamofire/Alamofire.git
Resolving https://github.com/Alamofire/Alamofire.git at 5.0.0-beta.6
✨  Reading package manifest at ~/SwiftDemo/Package.swift ...
✨  Generating dependency graph ...
✨  Resolving dependencies for target 'SwiftDemo' on platform 'macOS' ...
✨  Found cached build products for Alamofire in local cache - skipping build.
✨  Resolving dependencies for target 'SwiftDemoTests' on platform 'macOS' ...
❌  DependencyGraph: Could not find library product with name 'SwiftDemo' in package manifest for project 'SwiftDemo'.
An error occurred: libraryNotFound

Solutions:

// Remove `SwiftDemo` from `SwiftDemoTests`'s dependencies

...
targets: [
	// Targets are the basic building blocks of a package. A target can define a module or a test suite.
	// Targets can depend on other targets in this package, and on products in packages which this package depends on.
	.target(
		name: "SwiftDemo",
		dependencies: ["Alamofire"]),
	// .testTarget(
	// 	name: "SwiftDemoTests",
	// 	dependencies: ["SwiftDemo"]),
]
...

OR

#  Start over and change target to SwiftDemoPackageDescription
$ accio init -p SwiftDemo -t SwiftDemoPackageDescription
  1. Install or update using Accio again
$ accio update

(outputs) =>
✨  Reverting any changes in the checkouts directory ...
✨  Updating dependencies ...
Updating https://github.com/Alamofire/Alamofire.git
Completed resolution in 2.66s
Everything is already up-to-date
✨  Reading package manifest at ~/SwiftDemo/Package.swift ...
✨  Generating dependency graph ...
✨  Resolving dependencies for target 'SwiftDemo' on platform 'macOS' ...
✨  Found cached build products for Alamofire in local cache - skipping build.
✨  Copying build products of target 'SwiftDemo' into folder 'Dependencies' ...
✨  Adding frameworks ["Alamofire"] to project navigator group 'Dependencies/SwiftDemo' & linking with target 'SwiftDemo' ...
✨  Creating new copy build script phase 'Accio' for target 'SwiftDemo'...
✨  Updating input paths in copy build script phase 'Accio' for target 'SwiftDemo' ...
✨  Removing frameworks ["Package.swift"] from project navigator group 'Dependencies/Alamofire 5.0.0-beta.6' ...
✨  Removing empty groups ["Alamofire 5.0.0-beta.6"] from project navigator group 'Dependencies' ...
✨  Successfully updated dependencies.

Wanted

  1. Where can I find the SwiftDemo.Framework?
    (Or does the swift command line not support creating frameworks?)

  2. How do I compile for multiple platforms (iOS, watchOS and etc.) at once? (
    If I don't manually modify the generated Xcode project.)

Thanks!

Trouble adding XcodeProj to macOS app

I'm having trouble adding XcodeProj to a new project built with Accio. The problem seems to be with PathKit.

✨  Building library PathKit with Carthage ...
⚠️  No shared scheme(s) found matching library name 'PathKit' – can't remove potentially unnecessary shared schemes, keeping all
*** xcodebuild output can be found in /var/folders/3g/s__pcjg96s7ghq56p393hc140000gn/T/carthage-xcodebuild.7dLiEd.log
*** Skipped building PathKit due to the error:
Dependency "PathKit" has no shared framework schemes for any of the platforms: Mac
cp: /Code/Limerick/Demo/.accio/checkouts/PathKit/Carthage/Build/Mac/PathKit.framework: No such file or directory
An error occurred: Command '/bin/bash -c "cp -R '/Code/Limerick/Demo/.accio/checkouts/PathKit/Carthage/Build/Mac/PathKit.framework' '/var/folders/3g/s__pcjg96s7ghq56p393hc140000gn/T/Accio/BuildProducts/macOS/PathKit.framework'"' returned with error code 1.

Mint support

Mint is package manager targeting command line tools written in swift. https://github.com/yonaskolb/Mint. Adding support should not be difficult I think and this tools is quite convenient compared to brew to manage those kind of tools.

Provide a Global Cache for popular Frameworks

While there's already a local and a shared cache option available, both of these are not particularly useful when installing dependencies (the first time) on a CI. CI build times can be very long (especially on first run) for dependencies. While some might opt to configure their shared cache on the CI as well, this can be a hassle dependending on the service used for the shared cache.

A global cache could be tackled in various ways:

  1. Everybody using Accio worldwide could opt to upload any build products to the global cache. Advantages: High availability of frameworks. Disadvantages: Security concerns and too much space taken by build products.
  2. Only GitHub Open Source frameworks with at least 100 stars and only versioned releases could be uploaded by everyone using Accio to the global cache. Advantages: Relatively high availability of frameworks & managable space taken by build products. Disadvantages: Security concerns.
  3. A CI/Backend is provided specifically for building products and each instance of Accio can ask it to build a specific Open Source project – only versioned releases and at least 100 stars needed so it's actuallly built. Advantages: Better security (depending on CI/backend), relatively high availability of frameworks & managable space taken. Disadvantages: Framework availability delayed, costs for CI/backend.

These are the ways I think this could be tackled. I personally prefer point 3 most since XcodeGhost could always happen again and I don't want to be responsible for malware. I'm also very open to other ideas from the community – this will probably not be tackled until I feel we have found the best possible way dealing with a global cache.

Although I have only CI builds as a use case this feature was mainly designed for, I'm pretty sure that if we provide this feature, some developers will always use it regardless of any security concerns of warnings we might mention in the README.

Accio attempts to build the same dependency multiple times

Hi,

When I set RxCocoa as a dependency (version 5.0.1) I see that Accio attempts to build RxSwift twice. From the logs:

✨  Found cached build products for RxSwift in local cache - skipping build.
✨  Found cached build products for RxRelay in local cache - skipping build.
✨  Found cached build products for RxSwift in local cache - skipping build.
✨  Found cached build products for RxCocoa in local cache - skipping build.

Seems like this is because RxCocoa depends on RxSwift and RxRelay, and RxRelay depends on RxSwift. Is this intended behaviour? Shouldn't Accio, after dependency resolution, only attempt to build the necessary dependencies once?

Thanks,
Andres

Add ability to disallow adding accio script to targets

The Accio script causes several "not permitted" and "directory not found" issues when building a project with extensions, e.g. NotificationContentExtensions.

When adding extensions to an Xcode project Xcode creates a new target for each extension. In some cases, we need to access some functionality of the app, e.g. accessing a Realm Database within a Notification Extension requires to include the Realm Framework to the Extension Target.
By doing this and running accio install Accio automatically adds the Accio script to the target. This will cause problems while building the project because several scripts are executed at build time. Therefore I propose to add a flag or possibility to disallow adding the Accio script to a specific target.

error: repository 'dependency' has uncommited changes

Sometimes errors like this appear when running accio update:

error: repository '/path/to/Demo/.accio/checkouts/DependencyName' has uncommited changes

Running accio clean before running accio update solves the issue, but Accio should handle the issue in the first place instead of requiring this workaround.

Unable to build a command line target

Accio 0.6 and Xcode 10.2.1 on macOS 10.14.4

Hi, this may just be user error, I've only just started trying to use Accio and don't have much experience with SPM/Carthage.

I want to add SwiftyJSON to a command line target for macOS, and have it be self-contained, so I expect the right approach is for the framework to be embedded like this https://iosdevcenters.blogspot.com/2015/12/realm-error-dyld-library-not-loaded.html

I'm seeing this when I try to build BIAdapter in Xcode after generating a Package.swift and running accio install

Environment variable not set: FRAMEWORKS_FOLDER_PATH                                                                                                                                                                                                                      
Command PhaseScriptExecution failed with a nonzero exit code

If I export FRAMEWORKS_FOLDER_PATH=$HOME/Library/Frameworks and xcodebuild -workspace X.xcworkspace -scheme BIAdapter it builds, but then the framework isn't embedded:

$ otool -L BIAdapter
BIAdapter:
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
	@rpath/SwiftyJSON.framework/Versions/A/SwiftyJSON (compatibility version 1.0.0, current version 1.0.0)
        ...

$ ./BIAdapter
dyld: Library not loaded: @rpath/SwiftyJSON.framework/Versions/A/SwiftyJSON
  Referenced from: $HOME/Library/Developer/Xcode/DerivedData/Defendpoint-fgbftiezftkbbebxeuagglvuyrtr/Build/Products/Debug/./BIAdapter
  Reason: image not found

Here's my Package.swift

// swift-tools-version:5.0
import PackageDescription

let package = Package(
    name: "BIAdapter",
    products: [],
    dependencies: [
        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", .upToNextMajor(from: "5.0.0")),
    ],
    targets: [
        .target(
            name: "BIAdapter",
            dependencies: [
                "SwiftyJSON"
            ],
            path: "BIAdapter"
        ),
        .testTarget(
            name: "BIAdapterTests",
            dependencies: [
                "SwiftyJSON"
            ],
            path: "BIAdapterTests"
        ),
    ]
)

Test target name conflict

We have a test target i.e. named "Tests" in our project und define it like this:

targets: [
    .target(...),
    .testTarget(name: "Tests", dependencies: [SomeTestDependency], path: "Tests")
]

Then we import a framework via Accio. This framework contains a test target with the same name as we do:

targets: [
    .target(...),
    .testTarget(name: "Tests", dependencies: [TestDependencyA, TestDependencyB])
]

As a result, Accio does not work anymore:

✨  Generating dependency graph ...
❌  error: multiple targets named 'Tests' in: SomeTestDependency, MyProject

Dependencies cannot be resolved when the target is in the same Package.swift

I have an issue where i try to add a local library product as dependency to the main target.
It seems that we are looking into the dependencies of the Package.swift file but for local targets there won't be an entry in dependencies so this always fails to resolve.

DependencyGraph: Could not find library product with name 'Target' in package manifest for project 'ProjectName'.

Build error: 'Type' is only available on iOS 10.0 or newer

when trying to do an install/update I am running into an error which comes up in the build logs.

```error: 'StringMeasurement' is only available on iOS 10.0 or newer``
the Project was set to 10.0 as minimum and even if I set it to 11 it still fails with these errors in the log file.

Issues with SwiftEntryKit

Issue

In one of our projects, we use the SwiftEntryKit dependency. With the current version of Accio (0.6.1), building it doesn't work, but strangely it works with version 0.6.0.

Reason

The commit that broke things for this dependency is 779e3fc. This commit is actually a fix not to destroy the Xcode project generated using Swift PM right after creating it – so it's definitely valid. Still, with this commit, Accio now creates an XcodeProject using SwiftPM for the SwiftEntryKit dependency. When opening this project manually, one can easily see why it doesn't build: Many import statements are missing (~ import UIKit), in files such as Source/Model/EntryAttributes/EKAttributes+FrameStyle.swift.

So far, so good. But why does it build when the XcodeProject isn't generated?!

The reason is that Carthage isn't as smart as Accio in excluding folders like Example and Demo from a scheme / xcodeproj search. This is why it finds a Xcode Workspace within the Example folder and is actually able to build this workspace correctly; it however includes the example project as a side result... Opening up this workspace manually, there are no such issues with import statements as with the SPM-generated xcodeproj, although the files are the very same. I don't understand this by now...

Further Steps

This mostly sounds like an issue with the project itself that can be solved by fixing theimport statements. However, it poses the question whether such project configurations are more common than expected and whether Accio should do something to detect them and act accordingly.

Also, how the hack are those missing import statements within the Xcode workspace even valid?!

Framework targets have Carthage copy script

I‘m not sure if this is a problem at all, but currently when an app has the targets, say „App“ and „AppKit“ where AppKit is a framework used within the app, then the Carthage copy build script is added to the framework target, too.

This might be correct behavior after all, but I feel like I already ran into double linking problems during App store upload in such cases. This should be double checked and fixed if necessary.

Integration with XcodeGen

Hi,

I'm using XcodeGen to manage my Xcode project and Carthage for dependencies. I'm trying to reduce my CI builds time with some cache but I don't want to introduce Rome.
I like your approach targeting SPM for the long run. So I'll be soon looking at a solution to integrate XcodeGen and Accio. I saw you have commands related to the .xcproject file do you think the two tools are complementary or not ?

Test Coverage: Migrate some open source Apps to Accio

Currently, only a few project structures and sets of dependencies are tested with Accio. While most should be usable as is, it would make sense to migrate several open source iOS apps from Carthage to Accio to find edge cases (or confirm there are none). Here's a repo with many such projects.

Bigger and wider known app projects could be started with, like Firefox.

Support prebuilt binaries

There should be support to include prebuilt binaries. While the actual implementation will probably be quite straightforward, it is unclear how those binaries should best be specified in the Package.swift.

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.