Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift package support. #1083

Merged
merged 49 commits into from Sep 30, 2019
Merged

Swift package support. #1083

merged 49 commits into from Sep 30, 2019

Conversation

lolgear
Copy link
Contributor

@lolgear lolgear commented Jul 4, 2019

New Pull Request Checklist

  • I have read and understood the CONTRIBUTING guide

  • I have read the Documentation

  • I have searched for a similar pull request in the project and found none

  • I have updated this branch with the latest master to avoid conflicts (via merge from master or rebase)

  • I have added the required tests to prove the fix/feature I am adding

  • I have updated the documentation (if necessary)

  • I have run the tests and they pass

  • I have run the lint and it passes (pod lib lint)

Pull Request Description

Integration

  • Add Package.swift
  • Move headers to Include folder.
  • Add helper target for tests target ( Tests/Library ).
  • Add Tests targets to package.
  • Fix Xcode project.
  • Fix CocoaPods.
  • Fix tests targets.

Cleanup

  • Cleanup DDLog (?)

@lolgear
Copy link
Contributor Author

lolgear commented Jul 4, 2019

This PR reveals several issues about imports and about structure of project.

DDLog.h contains following:

@class DDLogMessage;
@class DDLoggerInformation;

@protocol DDLogger;
@protocol DDLogFormatter;

@interface DDLog : NSObject

@protocol DDLogger <NSObject>
@protocol DDLogFormatter <NSObject>
@protocol DDRegisteredDynamicLogging

@interface DDLogMessage : NSObject <NSCopying>
@interface DDAbstractLogger : NSObject <DDLogger>
@interface DDLoggerInformation : NSObject

As we can see, it is a blob of various definitions and interfaces.

I suggest to cleanup DDLog (and move protocols and Data structures to appropriate headers) in separate PR.

@OSSPolice
Copy link

OSSPolice commented Jul 4, 2019

3 Warnings
⚠️ Big PR
⚠️ Any changes to library code should be reflected in the CHANGELOG. Please consider adding a note there about your change.
⚠️ Copyright is not valid. See our default copyright in all of our files (Classes, Demos and Benchmarking use different formats).

Invalid copyright: Package.swift

Generated by 🚫 Danger

@lolgear
Copy link
Contributor Author

lolgear commented Jul 4, 2019

Also, it seems that only relative paths are permitted.

In case of Tests target it means that all helpers headers ( or samples / scaffolds / mockings ) should either

  1. be in the same source directory ( Tests )
  2. be in separate target CocoaLumberjackTestsHelper or CocoaLumberjackTestsTool
  3. their imports should have relative paths #import "../Library/File.h"

@codecov-io
Copy link

codecov-io commented Jul 4, 2019

Codecov Report

Merging #1083 into master will decrease coverage by 0.48%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1083      +/-   ##
==========================================
- Coverage   38.43%   37.95%   -0.49%     
==========================================
  Files          27       27              
  Lines        3944     3944              
==========================================
- Hits         1516     1497      -19     
- Misses       2428     2447      +19
Impacted Files Coverage Δ
...ocoaLumberjackTests/DDFileLoggerPerformanceTests.m 0.95% <ø> (ø)
Tests/CocoaLumberjackTests/DDLogMessageTests.m 91.83% <ø> (ø)
Tests/CocoaLumberjackTests/DDLogFileManagerTests.m 94.11% <ø> (ø)
Tests/CocoaLumberjackTests/DDAtomicCounterTests.m 98.14% <ø> (ø)
...umberjack/Extensions/DDDispatchQueueLogFormatter.m 6.62% <ø> (ø)
Tests/CocoaLumberjackTests/DDLogTests.m 97.5% <ø> (ø)
Sources/CocoaLumberjack/DDLog.m 58.97% <ø> (ø)
...oaLumberjack/include/DDDispatchQueueLogFormatter.h 0% <ø> (ø)
...ocoaLumberjack/Extensions/DDFileLogger+Buffering.m 79.16% <ø> (ø)
Tests/CocoaLumberjackTests/DDOSLoggingTests.m 75% <ø> (ø)
... and 21 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b80b87b...f7f03c0. Read the comment docs.

@lolgear
Copy link
Contributor Author

lolgear commented Jul 6, 2019

@CocoaLumberjack/collaborators
Can anybody review?

Package.swift Outdated
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "CocoaLumberjack",
type: .dynamic,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CocoaLumberjack also supports static linking I think. Could remove this and let clients decide?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Swift Package manager supports static linking, then, we should add static library also.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// A library's product can either be statically or dynamically linked. It
/// is recommended to not declare the type of library explicitly to let the
/// Swift Package Manager choose between static or dynamic linking depending
/// on the consumer of the package.

https://github.com/apple/swift-package-manager/blob/master/Documentation/PackageDescription.md
Removing it should be fine?

@lolgear
Copy link
Contributor Author

lolgear commented Jul 19, 2019

@ffried
I would like to put .xcproj to Xcode/ also. And...
I am not sure that Xcode/ directory has greater discoverability than Framework/ and vice versa.

@ffried
Copy link
Member

ffried commented Jul 19, 2019

@lolgear It's less about the discoverability (although I find Xcode is better discoverable than Framework, because I'd expect binaries in the latter), more about breaking existing projects.

@ffried
Copy link
Member

ffried commented Jul 19, 2019

@lolgear I'd suggest to put the .xcodeproj also in Xcode and then simply create a symlink from /Lumberjack.xcodeproj to /Xcode/Lumberjack.xcodeproj and mention the deprecation of the /Lumberjack.xcodeproj location in the release notes. I think, with that change, the addition of SwiftPM support is completely non-breaking.

@ffried
Copy link
Member

ffried commented Jul 19, 2019

@lolgear I've also just verified this with one of the bigger projects I'm using CocoaLumberjack in. Switched the dependency to your branch and it still builds just fine!

I've also tried the symlink solution above - works just fine, too.

@sushichop
Copy link
Member

sushichop commented Jul 29, 2019

Great works!
I also confirmed swift test works fine(including swift build). And CocoaPods and Carthage integration work fine as before🙂

But... I could not confirm the following steps work fine(I could not build using Xcode and I needed to add AppKit.framework for CocoaLumberjack.framework target to build it using Xcode...😢).
Is this a limitation or do I need Xcode 11 for SwiftPM to work completely?
My Xcode version is 10.3.

swift package init 
swift build
swift package generate-xcodeproj
open Dependencies.xcodeproj
(Try to build using Xcode.)

Package.swift

// 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: "Dependencies",
    products: [
        // Products define the executables and libraries produced by a package, and make them visible to other packages.
        .library(
            name: "Dependencies",
            targets: ["Dependencies"]),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "git@github.com:lolgear/CocoaLumberjack.git", .branch("swift_package")),
    ],
    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: "Dependencies",
            dependencies: ["CocoaLumberjackSwift"]),
        .testTarget(
            name: "DependenciesTests",
            dependencies: ["Dependencies"]),
    ]
)

And I drag-and-dropped the above Dependencies.xcodeproj to some macOS app project.
Then I could import CocoaLumberjack.framework, but I could not import CocoaLumberjackSwift.framework...😰

As a whole, am I wrong with how to use SwiftPM?

@ffried
Copy link
Member

ffried commented Jul 29, 2019

@sushichop Wow, thanks for testing this. I totally missed that one. I only tested building CocoaLumberjack directly... 😨

Just to clarify: Building your own package on the terminal (using swift build) works fine, but the generated Xcode project doesn't build? If so, that's most likely a bug in SwiftPM. swift build and xcodebuild -project {GENERATED_XCODEPROJ} build should yield the same result.

We could work around it by conditionally linking AppKit (conditional, since we cannot link it on non-macOS targets).

Can you test Xcode 11? If it's fixed there, I'd simply declare SPM support as of Xcode 11.

I'd say drag-and-dropping the project is not really a valid SPM case. You'd be creating another package and declaring a dependency there.

@dehlen
Copy link

dehlen commented Jul 29, 2019

I tested on Xcode 11 beta 4 by adding https://github.com/lolgear/CocoaLumberjack.git, branch: swift_package as a new Swift Package dependency. The imports work fine for me.

@ffried
Copy link
Member

ffried commented Jul 29, 2019

@dehlen So the generated Xcode project builds fine, too?

@dehlen
Copy link

dehlen commented Jul 29, 2019

When I right click the package -> Show in Finder -> and open the Lumberjack.xcodeproj in Xcode 11 beta 4 the CocoaLumberjack and CocoaLumberjackSwift Target build succeeds.

@bpoplauschi
Copy link
Member

You guys had a very good conversation here, including testing.
Any blockers for merging the PR?

@lolgear
Copy link
Contributor Author

lolgear commented Jul 31, 2019

@bpoplauschi
I think we are ready, but we should add new Integration/demos projects, I suppose?
Here we have exactly the same situation as with CocoaPods.
pod lib lint feels good, so, we don't integrate anything to test deployment in CocoaPods environment.
swift test feels good... and we should do something else?
Maybe Demos projects need another entry.

@ffried
Copy link
Member

ffried commented Jul 31, 2019

@lolgear I'd say for the initial support we don't need any new samples. SPM is pretty straightforward. I'd only include it in the README for now and add samples as necessary.

Apart from that I'd really like to move the .xcodeproj into the Xcode folder and (for now) provide a symlink) to prevent confusion with the SPM generated xcodeproj - which should also be added in the .gitignore as /*.xcodeproj.

@sushichop
Copy link
Member

sushichop commented Aug 1, 2019

Hi guys!
I confirmed SwiftPM works fine using Xcode 11 Beta 5!🙂

I created Package.swift from Xcode menu.
(However I want to avoid taking screenshots because, IMHO, it may violate Apple license agreement😎)

Package.swift is here.

// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "MyLibrary",
    platforms: [.iOS(.v8)],
    products: [
        .library(
            name: "MyLibrary",
            targets: ["MyLibrary"]),
    ],
    dependencies: [
        .package(url: "https://github.com/lolgear/CocoaLumberjack.git", .branch("swift_package"))
    ],
    targets: [
        .target(
            name: "MyLibrary",
            dependencies: ["CocoaLumberjackSwift"]),
        .testTarget(
            name: "MyLibraryTests",
            dependencies: ["MyLibrary"]),
    ]
)

On the other hand, swift package generate-xcodeproj did not work fine yet.
It may be because it is still beta version... I'm not sure, but I think this is NOT a problem🙂

So I'm glad that we can say CocoaLumberjack will completely support SwiftPM with Xcode 11(Sep. this year?)🎉

Can I add README to this PR or create another PR for it?
It may be enough to add the description of Pakcage.swift and Xcode version to README😅

@lolgear
Copy link
Contributor Author

lolgear commented Aug 1, 2019

@suchichop
I suggest to add full setup with even “In Xcode choose menu item File -> choose add repository -> insert github link to this repository” and etc.
For me it was a big surprise that I didn’t know how to start with SPM in Xcode 11 beta 1.

About PR..
I also suggest to PR into this PR.

Also, if you like to complete final steps... Do you dare to move Xcode project to subdirectory? I don’t know if Apple have plans to release migration tool which allows to move Xcode project and repair relative paths of files in it.

@ffried
Copy link
Member

ffried commented Aug 1, 2019

@sushichop @lolgear IMHO it's not our job to provide an intro on "how to use SPM with Xcode". That's Apple's job. If you don't know how to use SPM, first learn that, then come back and include CocoaLumberjack as dependency.

Most SPM projects (including Apple's own Swift NIO) simply list their dependency-line and I think this is fine. E.g. we also don't provide instructions on how to install Carthage oder how to setup CocoaPods:

Regarding the move of the Xcode project: Since our package is named "CocoaLumberjack", SPM will generate a "CocoaLumberjack.xcodeproj". The Xcode project we currently have is named "Lumberjack.xcodeproj". This means that for now it would work, but I assume it could cause irritation on what is what... Given all the custom settings we have with the xcconfig files, I'd rather not rely on the SPM generated project.
But maybe that's a topic for a different PR altogether. So let's just put this aside for now.

@sushichop
Copy link
Member

@ffried @lolgear
Thanks for sharing your idea. I'm agree with @ffried .
Then can you add CHANGELOG before we merge this PR to master branch?

@amayers
Copy link

amayers commented Aug 27, 2019

I think there is something slightly wrong with the SPM support as it is currently. Here is a sample project that uses it, and it builds/runs fine when running the app, but when trying to build the app's unit tests it will throw <unknown>:0: error: missing required modules: 'CocoaLumberjack', 'CocoaLumberjackSwiftSupport'. The strange thing is that this error is thrown on the app's test target, not in the framework that consumes Cocoalumberjack. I just created a new app in Xcode 11, created a new dynamic framework target, and use Xcode's SPM support to link Cocoalumberjack to the dynamic framework. The app target/test target does not ever touch Cocoalumberjack directly.

SPM_Test.zip

@ffried
Copy link
Member

ffried commented Aug 27, 2019

@amayers I'd say this is an Xcode issue. I'd bet this issue also occurs with any other SPM project that has several sub-dependencies.
Actually, I'd even say this is a longer lasting issue with unit tests. I know from some of our bigger projects that we need to explicitly embed all frameworks in the main app (and / or the unit tests target) so that the unit tests build and run fine.

To prove this, you can simply link your "FrameworkSomething" target into the "SPM_TestTests" target by adding it to the "Link Binary With Libraries" build phase. This is all it takes for the Unit Tests to build fine.

@amayers
Copy link

amayers commented Aug 27, 2019

@ffried ok that worked. Although in my main project Cocoalumberjack was the only package out of 6 that had this issue.

@ffried
Copy link
Member

ffried commented Aug 27, 2019

@amayers Do the other packages have internal dependencies? CocoaLumberjackSwiftSupport is an internal target that is not exposed via a product. I assume this is what is still causing issues with Xcode.

@amayers
Copy link

amayers commented Aug 27, 2019

@ffried No, it doesn't look like any of them do.

@ffried
Copy link
Member

ffried commented Aug 27, 2019

@amayers Thanks for the confirmation. I'll try to create a small reproduction project that is not using any external dependencies and file a radar with Apple about that.

@ffried
Copy link
Member

ffried commented Sep 30, 2019

I'll update the Changelog on master directly.

@ffried ffried merged commit 8a9fc91 into CocoaLumberjack:master Sep 30, 2019
@bpoplauschi bpoplauschi added this to the 3.6.0 milestone Apr 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants