Skip to content

Commit

Permalink
Merge pull request #27 from rockbruno/buck
Browse files Browse the repository at this point in the history
Adding support for Buck logs | TestCountProvider for Buck
  • Loading branch information
rockbruno committed Aug 15, 2019
2 parents 21b37ab + 7ba08be commit 03253b3
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 70 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

## master

## 2.3.5
* Adding support for `buckLogFilePath` for the extraction of Buck Build related rules - Bruno Rocha
* Adding Buck support to `TestCountProvider` - Bruno Rocha

## 2.3.4
* Fixes version string and makes error methods public for custom providers - Bruno Rocha

Expand Down
2 changes: 1 addition & 1 deletion ExampleProject/Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
source "https://rubygems.org"

gem "fastlane", "~> 2.102.0"
gem "fastlane", "2.128.0"
gem "cocoapods"
59 changes: 35 additions & 24 deletions ExampleProject/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ GEM
concurrent-ruby (1.1.5)
declarative (0.0.10)
declarative-option (0.1.0)
domain_name (0.5.20180417)
digest-crc (0.4.1)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.2)
emoji_regex (0.1.1)
dotenv (2.7.5)
emoji_regex (1.0.1)
escape (0.0.4)
excon (0.64.0)
excon (0.66.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
Expand All @@ -66,41 +67,42 @@ GEM
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
fastlane (2.102.0)
fastlane (2.128.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (~> 0.1)
emoji_regex (>= 0.1, < 2.0)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
mini_magick (~> 4.5.1)
multi_json
jwt (~> 2.1.0)
mini_magick (>= 4.9.4, < 5.0.0)
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.2.1, < 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 1.6.2, < 2.0.0)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.5.7, < 2.0.0)
xcpretty (~> 0.2.8)
xcodeproj (>= 1.8.1, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
fourflusher (2.2.0)
fuzzy_match (2.0.4)
Expand All @@ -113,6 +115,15 @@ GEM
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.9)
google-cloud-core (1.3.0)
google-cloud-env (~> 1.0)
google-cloud-env (1.2.0)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
digest-crc (~> 0.4)
google-api-client (~> 0.23)
google-cloud-core (~> 1.2)
googleauth (>= 0.6.2, < 0.10.0)
googleauth (0.6.7)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
Expand All @@ -132,7 +143,7 @@ GEM
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mini_magick (4.5.1)
mini_magick (4.9.5)
minitest (5.11.3)
molinillo (0.6.6)
multi_json (1.13.1)
Expand All @@ -152,7 +163,7 @@ GEM
retriable (3.1.2)
rouge (2.0.7)
ruby-macho (1.4.0)
rubyzip (1.2.2)
rubyzip (1.2.3)
security (0.1.3)
signet (0.11.0)
addressable (~> 2.3)
Expand All @@ -163,29 +174,29 @@ GEM
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (1.8.0)
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-cursor (0.6.1)
tty-screen (0.6.5)
tty-spinner (0.9.0)
tty-cursor (~> 0.6.0)
tty-cursor (0.7.0)
tty-screen (0.7.0)
tty-spinner (0.9.1)
tty-cursor (~> 0.7)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
unicode-display_width (1.5.0)
unicode-display_width (1.6.0)
word_wrap (1.0.0)
xcodeproj (1.8.2)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.2.8)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
Expand All @@ -195,7 +206,7 @@ PLATFORMS

DEPENDENCIES
cocoapods
fastlane (~> 2.102.0)
fastlane (= 2.128.0)

BUNDLED WITH
1.16.5
1.17.3
4 changes: 2 additions & 2 deletions ExampleProject/Infofile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ let output = api.extract(IPASizeProvider.self) +
api.extract(LongestTestDurationProvider.self) +
api.extract(ArchiveDurationProvider.self)

api.sendToSlack(output: output, webhookUrl: "slackUrlHere")

//api.sendToSlack(output: output, webhookUrl: "slackUrlHere")
api.print(output: output)
api.save(output: output)
4 changes: 2 additions & 2 deletions ExampleProject/SwiftInfoExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 4GEC7S6VF4;
DEVELOPMENT_TEAM = U7KHKH9L7R;
INFOPLIST_FILE = SwiftInfoExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -431,7 +431,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 4GEC7S6VF4;
DEVELOPMENT_TEAM = U7KHKH9L7R;
INFOPLIST_FILE = SwiftInfoExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>SwiftInfoExample.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
<integer>0</integer>
</dict>
</dict>
</dict>
Expand Down
Binary file not shown.
4 changes: 2 additions & 2 deletions Formula/swiftinfo.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class Swiftinfo < Formula
desc "📊 Extract and analyze the evolution of an iOS app's code."
homepage "https://github.com/rockbruno/SwiftInfo"
version "2.3.4"
version "2.3.5"
url "https://github.com/rockbruno/SwiftInfo/releases/download/#{version}/swiftinfo.zip"
# TODO: Try something to provide a SHA automatically

depends_on :xcode => ["10.2", :build]
depends_on :xcode => ["10.3", :build]

def install
bin.install Dir["bin/*"]
Expand Down
63 changes: 44 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,33 @@ By default SwiftInfo will assume you're extracting info from a release build and

## Available Providers

| **Type Name** | **Description** | **Requirements** |
|---|:---:|:---:|
| **📦 IPASizeProvider** | Size of the .ipa archive (Not the App Store size!) | Successful xcodebuild archive and build logs |
| **📊 CodeCoverageProvider** | Code coverage percentage | Test logs, Xcode developer tools, Test targets with code coverage reports enabled |
| **👶 TargetCountProvider** | Number of targets (dependencies) | Build logs |
| **🎯 TestCountProvider** | Sum of all test target's test count | Test logs |
| **⚠️ WarningCountProvider** | Number of warnings in a build | Build logs |
| **🧙‍♂️ OBJCFileCountProvider** | Number of OBJ-C files and headers (for mixed OBJ-C / Swift projects) | Build logs |
| **⏰ LongestTestDurationProvider** | The name and duration of the longest test | Test logs |
| **🛏 TotalTestDurationProvider** | Time it took to build and run all tests | Test logs |
| **🖼 LargestAssetCatalogProvider** | The name and size of the largest asset catalog | Build logs |
| **🎨 TotalAssetCatalogsSizeProvider** | The sum of the size of all asset catalogs | Build logs |
| **💻 LinesOfCodeProvider** | Executable lines of code | Same as CodeCoverageProvider. |
| **🚚 ArchiveDurationProvider** | Time it took to build and archive the app | Successful xcodebuild archive and build logs |
| **📷 LargestAssetProvider** | The largest asset in the project. Only considers files inside asset catalogs. | Build logs |
| **Type Name** | **Description** | **Requirements** | **Supported build systems**
|---|:---:|:---:|:---:|
| **📦 IPASizeProvider** | Size of the .ipa archive (not the App Store size!) | .ipa available in the `#{PROJECT_DIR}/build` folder | Xcode/Buck |
| **📊 CodeCoverageProvider** | Code coverage percentage | Test logs, Xcode developer tools, Test targets with code coverage reports enabled | Xcode |
| **👶 TargetCountProvider** | Number of targets (dependencies) | Build logs | Xcode |
| **🎯 TestCountProvider** | Sum of all test target's test count | Test logs (if building with Xcode) or Buck build log (if building with Buck) | Xcode/Buck |
| **⚠️ WarningCountProvider** | Number of warnings in a build | Build logs | Xcode |
| **🧙‍♂️ OBJCFileCountProvider** | Number of OBJ-C files and headers (for mixed OBJ-C / Swift projects) | Build logs | Xcode |
| **⏰ LongestTestDurationProvider** | The name and duration of the longest test | Test logs | Xcode |
| **🛏 TotalTestDurationProvider** | Time it took to build and run all tests | Test logs | Xcode |
| **🖼 LargestAssetCatalogProvider** | The name and size of the largest asset catalog | Build logs | Xcode |
| **🎨 TotalAssetCatalogsSizeProvider** | The sum of the size of all asset catalogs | Build logs | Xcode |
| **💻 LinesOfCodeProvider** | Executable lines of code | Same as CodeCoverageProvider. | Xcode |
| **🚚 ArchiveDurationProvider** | Time it took to build and archive the app | Successful xcodebuild archive and build logs | Xcode |
| **📷 LargestAssetProvider** | The largest asset in the project. Only considers files inside asset catalogs. | Build logs | Xcode |

## Usage

SwiftInfo extracts information by analyzing the logs that logs that Xcode generates when you build and/or test your app. Because it requires these logs to work, SwiftInfo is meant to be used alongside a build automation tool like [fastlane](https://github.com/fastlane/fastlane). The following topics describe how you can retrieve these logs and setup SwiftInfo itself.
SwiftInfo extracts information by analyzing the logs that your build system generates when you build and/or test your app. Because it requires these logs to work, SwiftInfo is meant to be used alongside a build automation tool like [fastlane](https://github.com/fastlane/fastlane). The following topics describe how you can retrieve these logs and setup SwiftInfo itself.

We'll show how to get the logs first as you'll need them to configure SwiftInfo.

**Note:** This repository contains an example project. Check it out to see the tool in action!

### Retrieving raw logs with [fastlane](https://github.com/fastlane/fastlane)
### If building with Xcode

#### Retrieving raw logs with [fastlane](https://github.com/fastlane/fastlane)

If you use fastlane, you can expose the raw logs by adding the `buildlog_path` argument to `scan` (test logs) and `gym` (build logs). Here's a simple example of a fastlane step that runs tests, submits an archive to TestFlight and runs SwiftInfo (be sure to edit the folder paths to what's being used by your project):

Expand Down Expand Up @@ -72,16 +74,26 @@ lane :beta do
end
```

### Retrieving raw logs manually
#### Retrieving raw logs manually

An alternative that doesn't require fastlane is to simply manually run `xcodebuild` / `xctest` and pipe the output to a file. We don't recommend doing this in a real project, but it can be useful if you just want to test the tool without having to setup fastlane.

```
xcodebuild -workspace ./Example.xcworkspace -scheme Example &> ./build/build_log/Example-Release.log
```

### If building with Buck

If you're building with Buck, you can pipe the output to a file similarly to the Xcode example.

```
buck build //SwiftRocks:SwiftRocksPackage &> ./build/buck_log/SwiftRocks.log
```

## Configuring SwiftInfo

### If building with Xcode

SwiftInfo itself is configured by creating a `Infofile.swift` file in your project's root. Here's an example one:

```swift
Expand Down Expand Up @@ -119,13 +131,24 @@ if isInPullRequestMode {
}
```

- 1: Use `FileUtils` to configure the path of your logs. If you're using fastlane and don't know what the name of the log files are going to be, just run it once to have it create them.
- 1: Use `FileUtils` to configure the path of your logs. If you're retrieving them with fastlane and don't know what the name of the log files are going to be, just run it once to have it create them.
- 2: Create a `SwiftInfo` instance by passing your project's information.
- 3: Use `SwiftInfo`'s `extract()` to extract and append all the information you want into a single property.
- 4: Lastly, you can act upon this output. Here, I print the results to a pull request if [danger-SwiftInfo](https://github.com/rockbruno/danger-SwiftInfo) is being used, or send it to Slack / save it to the repo if this is the result of a release build.

You can see `SwiftInfo`'s properties and methods [here.](Sources/SwiftInfoCore/SwiftInfo.swift)

### If building with Buck

The setup for Buck projects is similar to the Xcode one, with the difference being that Buck rules use `FileUtils.buckLogFilePath` instead. If you're using a rule that isn't exclusive to Buck, you should also pass the `buildSystem: .buck` argument to the rule.

```swift
FileUtils.buckLogFilePath = "./build/buck_log/SwiftRocks.log"
// ...
let output = api.extract(TestCountProvider.self, args: .init(buildSystem: .buck))
// ...
```

## Available Arguments

To be able to support different types of projects, SwiftInfo provides customization options to some providers. Click on each of them to see their documentation!
Expand All @@ -136,6 +159,8 @@ To be able to support different types of projects, SwiftInfo provides customizat

[📊 CodeCoverageProvider](Sources/SwiftInfoCore/Providers/CodeCoverageProvider.swift#L11)

[🎯 TestCountProvider](Sources/SwiftInfoCore/Providers/TestCountProvider.swift#L9)

## Output

After successfully extracting data, you can call `api.save(output: output)` to have SwiftInfo add/update a json file in the `{Infofile path}/SwiftInfo-output` folder. It's important to add this file to version control after the running the tool as this is what SwiftInfo uses to compare new pieces of information.
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftInfo/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public struct Main {
static func run() {
let fileUtils = FileUtils()
let toolchainPath = getToolchainPath()
log("SwiftInfo 2.3.4")
log("SwiftInfo 2.3.5")
if ProcessInfo.processInfo.arguments.contains("-version") {
exit(0)
}
Expand Down
6 changes: 6 additions & 0 deletions Sources/SwiftInfoCore/BuildSystem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation

public enum BuildSystem {
case xcode
case buck
}
15 changes: 15 additions & 0 deletions Sources/SwiftInfoCore/FileUtils/FileUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public struct FileUtils {
public static let supportedInfofilePaths = ["./", "../", "../../", "../../../"]
public static var buildLogFilePath = ""
public static var testLogFilePath = ""
public static var buckLogFilePath = ""

public let outputFileName = "SwiftInfoOutput.json"
public let infofileName = "Infofile.swift"
Expand Down Expand Up @@ -53,6 +54,20 @@ public struct FileUtils {
}
}

public func buckLog() throws -> String {
let folder = try infofileFolder()
let url = URL(fileURLWithPath: folder + FileUtils.buckLogFilePath)
do {
return try fileOpener.stringContents(ofUrl: url)
} catch {
throw SwiftInfoError.generic("""
Buck's log not found!
Expected path: \(FileUtils.buckLogFilePath)
Thrown error: \(error.localizedDescription)
""")
}
}

public func buildLog() throws -> String {
let folder = try infofileFolder()
let url = URL(fileURLWithPath: folder + FileUtils.buildLogFilePath)
Expand Down
Loading

0 comments on commit 03253b3

Please sign in to comment.