A little beautifier tool for xcodebuild

Overview

xcbeautify

Build Status Latest Release License

xcbeautify is a little beautifier tool for xcodebuild.

Similar to xcpretty, but faster.

Features

  • 2x faster than xcpretty.
  • Human-friendly and colored output.
  • Supports the new build system's output.
  • Supports Xcode's parallel testing output.
  • Supports formatting Swift Package Manager output.
  • Supports formatting Bazel output.
  • Supports macOS & Linux.
  • Written in Swift: xcbeautify compiles to a static binary which you can bring anywhere. This also means less Ruby-dependant in your development environment and CI.

Note: xcbeautify does not support generating JUnit or HTML test reports. In fact, you shouldn't rely on xcodebuild's output to generate test reports. We suggest using trainer or XCTestHTMLReport to generate test reports from xcodebuild's generated TestSummaries.plist files.

Fun fact

xcbeautify uses itself to format its CI build logs.

Installation

If you use macOS 10.14.3 or earlier, install Swift 5 Runtime Support for Command Line Tools first:

brew cask install thii/swift-runtime/swift-runtime

Homebrew

brew install xcbeautify

Swiftbrew

swift brew install thii/xcbeautify

Mint

mint install thii/xcbeautify

CocoaPods

pod 'xcbeautify'

The xcbeautify binary will be installed at Pods/xcbeautify/xcbeautify

Build from source

git clone https://github.com/thii/xcbeautify.git
cd xcbeautify
make install

Usage

xcodebuild [flags] | xcbeautify

If you want xcbeautify to exit with the same status code as xcodebuild (e.g. on a CI):

set -o pipefail && xcodebuild [flags] | xcbeautify

For parallel and concurrent destination testing, it helps to use unbuffered I/O for stdout and to redirect stderr to stdout.

NSUnbufferedIO=YES xcodebuild [flags] 2>&1 | xcbeautify
swift test [flags] 2>&1 | xcbeautify

Parse Bazel's building and testing output:

set -o pipefail && bazel build //path/to/package:target 2>&1 | xcbeautify
set -o pipefail && bazel test //path/to/package:target 2>&1 | xcbeautify

Future work

  • Write more tests

Development

Generate Xcode project:

make xcode

Build with Bazel:

bazel build //Sources/xcbeautify

Release a new version, say x.y.z:

make release version=x.y.z

Contributing

Just send a PR! We don't bite ;)

Don't have a GitHub account or prefer old-school patching via email? Send your patch to the project's mailing list.

License

MIT

Comments
  • Swift argument parser

    Swift argument parser

    Resolves #34

    Changes: No short option for --version (default in swift-argument-parser, can only be added back as a separate option), only outputs the number, without "Version: " (This can be easily changed back to the original behaviour) Added -qq for quieter as mentioned in #37 ~~--is-ci gets the default value from the CI environment variable used by most CI solutions.~~ (This would mean that specifying the --is-ci option sets it to false) XcbeautifyLib doesn't depend on the argument parser, only xcbeautify depends on it

    Todo: Update other package managers/build tools, I only updated Package.swift

    output of xcbeautify -h:

    OVERVIEW: Format the output of `xcodebuild` and `swift`
    
    EXAMPLE: xcodebuild test -project MyApp.xcodeproj -scheme MyApp -destination
    'platform=iOS Simulator,OS=12.0,name=iPhone X' | xcbeautify
    
    USAGE: xcbeautify [--quiet] [-qq] [--is-ci]
    
    OPTIONS:
      -q, --quiet             Only print tasks that have warnings or errors. 
      -qq, --quieter          Only print tasks that have errors. 
      --is-ci                 Print test result too under quiet/quieter flag. 
      --version               Show the version.
      -h, --help              Show help information.
    
    opened by Cyberbeni 9
  • Support multiple versions of MacOS and Xcode

    Support multiple versions of MacOS and Xcode

    Update:

    I have noticed xcbueatify cannot properly handle output from Xcode 11.2.1. So it may be a good idea to support different format of Xcode.

    #################################

    Could xcbeautify support different versions of OS and Xcode? If not yet, could these be implemented as new command line options?

    Thanks!

    opened by greensky01 8
  • Speedup Xcbeautify by applying frequency-based pattern matching.

    Speedup Xcbeautify by applying frequency-based pattern matching.

    The current implementation of xcbeautify performs regex checking for each line of the xcodebuild output. Due to the big amount of possible regexes, each line on average is checked for about N/2 times. which is a lot

    Suggested implementation holds an array of 'inner parser' and try to reuse 'line parser/matchers' using frequency based array (basically, last matcher regex will be checked first). Due to the non-random structure of xcodebuil output, this approach allows to decrease xcbeautify running time from 160 s to 9 seconds when used on the xcodebuild output of size 240Mb

    | Implementation | time | Log Size | |-|-|-| | xcbeautify-main | 209s | 256M | | xcbeautify-speedup | 8s | 256M | | xcpretty | 23s | 256M |

    Testing approach: time cat LOGFILE | xcbeauitify

    Possible 'bugs'

    If there are multiple regexes which can match same line, this approach could return different results, depending on the order of the commands, appeared in log

    Xcbeautify Speed

    It seems that xcbeautify is waaaay slower than xcpretty. This PR will actually make xcbeautify faster

    opened by PaulTaykalo 6
  • Maintainer wanted

    Maintainer wanted

    This was a weekend hack a few years ago to work around the parallel testing feature in Xcode 9 not being supported by xcpretty. Even though I don't use this anymore, it seems like there are still people that depends on it. I don't have time in maintaining this project for much longer, but also don't want to break anyone's builds. If you're interested in taking it over, please contact me.

    help wanted 
    opened by thii 6
  • Add GitHub Actions integration

    Add GitHub Actions integration

    Resolves https://github.com/thii/xcbeautify/issues/17.

    • adds "CI" workflow
      • build release version
      • run tests and pipe output into release version just built
    • adds some status badges on Readme 🙂
    opened by ealeksandrov 6
  • Supression of warnings

    Supression of warnings

    Hi, thanks for the great project.

    One thing I'm missing from it is the warnings suppression - Travis cancel jobs after 4MB of logs and building React Native projects for IOS often generates many warnings for the third party libraries.

    Using some flag like --errors-only would be very helpful in that case

    opened by jakub-gonet 6
  • Update `JunitReporter` to parse parallel tests

    Update `JunitReporter` to parse parallel tests

    • Change JunitComponent to capture the Regex used to create the component
    • Relies on capture groups being consistent between parallel and non-parallel output
    • Add unit test
    opened by welshm 5
  • Fix summary with multiple test plans and skipped tests

    Fix summary with multiple test plans and skipped tests

    Motivation

    Fixes https://github.com/fastlane/fastlane/pull/19629#issuecomment-1013511227

    The test summary printed after a run was showing wrong results if:

    • Multiple test suites were being run
    • Any tests were skipped

    Expected: Tests Passed: 0 failed, 955 total (12.187 seconds) Actual: Tests Passed: 0 failed, 56 total (0.324 seconds)

    The issue was because the test summary line parser assumed that there was only one line summary being printed. The line looks like 👇

    Executed 8 tests, with 4 failures (0 unexpected) in 0.154 (0.155) seconds
    

    However... this line gets printed multiple times after each suite gets run 👇

    Test Case '-[Tests_iOS.Tests_iOS testExample5ThatSometimesFails]' failed (0.019 seconds).                                                              
    Test Suite 'Tests_iOS' failed at 2022-01-15 21:31:49.073.                                                                                              
             Executed 8 tests, with 4 failures (0 unexpected) in 0.154 (0.155) seconds                                                                     
    Test Suite 'Tests iOS.xctest' failed at 2022-01-15 21:31:49.073.                                                                                       
             Executed 8 tests, with 4 failures (0 unexpected) in 0.154 (0.155) seconds                                                                     
    Test Suite 'All tests' failed at 2022-01-15 21:31:49.073.                                                                                              
             Executed 8 tests, with 4 failures (0 unexpected) in 0.154 (0.156) seconds
    

    There is also a case that was unaccounted when tests were skipped 👇

    Executed 56 tests, with 3 tests skipped and 0 failures (0 unexpected) in 1.019 (1.029) seconds 
    

    Description

    • Introduced 2 new line matchers for when a suite is finished for "All tests"
    • Introduced 1 new line matcher for "Executed with skipped tests"

    Previously, the testSummary in Parser would get override by the latest summary which was the root cause of this issue.

    Now, a testSummary will only get parsed when it follows either Test Suite 'All tests' passed at or Test Suite 'All tests' failed at. There can also be multiple summaries so this will also add all the summaries together for:

    • test count
    • skipped count
    • failure count
    • unexpected count
    • time

    It also adds logic now for parsing the two different variation of the "executed" lines:

    • Executed 8 tests, with 4 failures (0 unexpected) in 0.154 (0.155) seconds
    • Executed 56 tests, with 3 tests skipped and 0 failures (0 unexpected) in 1.019 (1.029) seconds
    opened by joshdholtz 5
  • how can we use xcbeautify with fastlane?

    how can we use xcbeautify with fastlane?

    Fastlane ships with xcpretty but when running tests in parallel, it doesnot create correct output. Hence we want to use xcbeautify with fastlane. Is there any way we can use that with action run_tests? https://docs.fastlane.tools/actions/run_tests/

    question 
    opened by ykhandelwal913 5
  • Command line option to output issue only

    Command line option to output issue only

    Is it possible to add a command line options to display warnings or errors only? Because for a huge project, most of output "[XXX] Compiling YYY.cpp" are of less importance and they would hide real issues.

    enhancement good first issue 
    opened by greensky01 5
  • main thread dead lock

    main thread dead lock

        NSArray *lines  = [log componentsSeparatedByString:@"\n"];
        Parser *parser = [[Parser alloc] init];
        for (NSString *line in lines) {
            NSString *beautyLog = [parser parseWithLine:line colored:NO];
            if (beautyLog.length) {
                DDLogInfo(@"%@", beautyLog);
            }
        }
    
    ibsystem_kernel.dylib         0x7fff6c5b4afe read$NOCANCEL + 10
    libsystem_c.dylib              0x7fff6c500b25 __srefill1 + 24
    libsystem_c.dylib              0x7fff6c4fd017 getdelim + 251
    libswiftCore.dylib             0x7fff6bc18903 swift_stdlib_readLine_stdin + 35
    libswiftCore.dylib             0x7fff6b9a9465 $ss8readLine16strippingNewlineSSSgSb_tF + 37
    OCObfuscator                   0x10004497a $sSS12OCObfuscatorE8beautify7pattern7coloredSSSgAA7PatternO_SbtF + 7242
    OCObfuscator                   0x1000396d2 $s12OCObfuscator6ParserC5parse4line7coloredSSSgSS_SbtF + 1826
    OCObfuscator                   0x10003ae9c $s12OCObfuscator6ParserC5parse4line7coloredSSSgSS_SbtFTo + 92
    OCObfuscator                   0x10000b2cd -[ObfuscatorTool receivedData:] + 1101
    CoreFoundation                 0x7fff34d9a35f __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    CoreFoundation                 0x7fff34d9a2f3 ___CFXRegistrationPost1_block_invoke + 63
    CoreFoundation                 0x7fff34d9a268 _CFXRegistrationPost1 + 372
    CoreFoundation                 0x7fff34d99ebe ___CFXNotificationPost_block_invoke + 97
    CoreFoundation                 0x7fff34d697e2 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1575
    CoreFoundation                 0x7fff34d68c82 _CFXNotificationPost + 1351
    Foundation                     0x7fff373eea22 -[NSNotificationCenter postNotificationName:object:userInfo:] + 59
    Foundation                     0x7fff375271f3 _performFileHandleSource + 1106
    CoreFoundation                 0x7fff34da4b21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    CoreFoundation                 0x7fff34da4ac0 __CFRunLoopDoSource0 + 103
    CoreFoundation                 0x7fff34da48d4 __CFRunLoopDoSources0 + 209
    CoreFoundation                 0x7fff34da3740 __CFRunLoopRun + 1272
    CoreFoundation                 0x7fff34da2bd3 CFRunLoopRunSpecific + 499
    HIToolbox                      0x7fff338f865d RunCurrentEventLoopInMode + 292
    HIToolbox                      0x7fff338f82a9 ReceiveNextEventCommon + 356
    HIToolbox                      0x7fff338f8127 _BlockUntilNextEventMatchingListInModeWithFilter + 64
    AppKit                         0x7fff31f68ba4 _DPSNextEvent + 990
    AppKit                         0x7fff31f67380 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
    AppKit                         0x7fff31f5909e -[NSApplication run] + 658
    AppKit                         0x7fff31f2b465 NSApplicationMain + 777
    OCObfuscator                   0x100017e1f main + 47
    libdyld.dylib                  0x7fff6c4727fd start + 1
    

    then i get the dead lock code

        private func formatCompileWarning(pattern: Pattern) -> String? {
            let groups = capturedGroups(with: pattern)
            let filePath = groups[0]
            let reason = groups[2]
    
            // Read 2 additional lines to get the warning line and cursor position
            let line: String = readLine() ?? "" // ===>this is the dead lock !!!!!!!!!!!!!
            let cursor: String = readLine() ?? ""
            ....
           .....
    }
    
    opened by fenglh 4
  • A more detailed 'Usage guide'?

    A more detailed 'Usage guide'?

    Where can i find more information on the usage of xcbeautify?

    For e.g. xcodebuild [flags] | xcbeautify

    • what are the different flags that can be used here?

    How to generate a JUnit report from xcbeautify?

    opened by venkat2789 0
  • Tests in parallel don't output junit results

    Tests in parallel don't output junit results

     xcodebuild test -project "MyApp.xcodeproj" -scheme "MyApp" -sdk iphonesimulator -destination "OS=16.0,name=iPhone 13 mini,platform=iOS Simulator" -derivedDataPath "~/temp2" -destination-timeout 300 -parallel-testing-worker-count 4 -parallel-testing-enabled YES |  ~/.mint/bin/xcbeautify --is-ci --quiet --report junit --junit-report-filename junitresult.xml --report-path . 
    

    The resulting file junitresult.xml shows 0 tests run :(

    opened by welshm 0
  • xcodebuild stock at some error

    xcodebuild stock at some error

    My project in xcode14 would build with some error like this:

    ❌  error: Dependency for P1:target-MyApp-fce55c0e14fedcc57d73ec039f604d040bdc1e3e5eb2ad770e53e15b1d5e91df-:Ad-Hoc-Mirror:SwiftDriver Compilation Requirements xiaoheihe normal arm64 com.apple.xcode.tools.swift.compiler is not absolute (Pods/Headers/Public/ActionSheetPicker_3_0/ActionSheetPicker-3.0.modulemap). (in target 'MyApp' from project 'MyApp')
    

    And xcbeautify will stock after encounter such error.

    bug 
    opened by mlch911 7
  • [Chore] Inject `Matching` instead of depending on `Regex` implementation

    [Chore] Inject `Matching` instead of depending on `Regex` implementation

    This PR mainly refactors how Regex implementation is used. We now have a Matching protocol, ideally, in the near future, we could experiment with different implementations dynamically.

    opened by adellibovi 0
  • Emacs cannot go to error

    Emacs cannot go to error

    I am writing a package for compiling and running apps using Emacs and I pipe the output from xcodebuild to xcbeautify but Emacs wont recognize the errors when this tool adds warning/info and error emojis. Is it possible to disable them somehow for just when an error occurs?

    opened by konrad1977 0
Releases(0.16.0)
Owner
Thi Doãn
Thi Doãn
Command line tool for exporting resources and generating code from your Figma files

Fugen Fugen is a command line tool for exporting resources and generating code from your Figma files. Currently, Fugen supports the following entities

Almaz Ibragimov 69 Dec 17, 2022
A Swift command line tool for generating your Xcode project

XcodeGen XcodeGen is a command line tool written in Swift that generates your Xcode project using your folder structure and a project spec. The projec

Yonas Kolb 5.9k Jan 9, 2023
Swift sample app for running privileged operations on macOS using a helper tool

SwiftAuthorizationSample demonstrates how to run privileged operations on macOS using a helper tool managed by launchd. This sample was created with t

null 31 Dec 20, 2022
Open-source jailbreaking tool for many iOS devices

Open-source jailbreaking tool for many iOS devices *Read disclaimer before using this software. checkm8 permanent unpatchable bootrom exploit for hund

null 0 Nov 6, 2021
A GUI based virtualisation tool for running Linux on macOS Big Sur (x86 or arm64)

Project Mendacius GUI based virtualization tool to run Linux, based on the Virtualization framework introduced by Apple for macOS Big Sur with support

Praneet 113 Nov 18, 2022
A command line tool for managing Swift Playground projects on your Mac.

swift-playground-tools A command line tool for managing Swift Playground projects on your Mac. Generate Xcode Project $ playground-tools generate-xcod

Liam Nichols 0 Dec 31, 2021
FocusSpace - A time-management tool to help you stay focus with your friends

FocusSpace ?? ElleHacks2022 - (Telus) First Place ?? Developers Manyi Cheng(@man

Manyi Cheng 1 Feb 13, 2022
Apple SMC library & tool

SMCKit An Apple System Management Controller (SMC) library & command line tool in Swift for Intel based Macs. The library works by talking to the Appl

Omeed 415 Dec 10, 2022
ExpoMod - a small application tool that lets you quickly setting up your computer for presentations / exhibitions

ExpoMod is a small application tool that lets you quickly setting up your computer for presentations / exhibitions. Or simply having useful shortcut to not being distract and keep awake your computer.

Niemes 10 Jun 29, 2022
A tool to read the binarycookie format of Cookies on iOS applications

BinaryCookieReader Cloned from http://securitylearn.net/wp-content/uploads/tools/iOS/BinaryCookieReader.py ##Usage Python BinaryCookieReader.py [Cooki

Murphy 77 Nov 15, 2022
Cocoapods project gen tool.

cocoapods-project-gen A gem which can gen cocoapods project. Installation Add this line to your application's Gemfile: gem 'cocoapods-project-gen' And

Cat1237 8 Oct 28, 2022
A little beautifier tool for xcodebuild

xcbeautify xcbeautify is a little beautifier tool for xcodebuild. Similar to xcpretty, but faster. Features 2x faster than xcpretty. Human-friendly an

Tuist 650 Dec 30, 2022
Convert xcodebuild plist and xcresult files to JUnit reports

trainer This is an alternative approach to generate JUnit files for your CI (e.g. Jenkins) without parsing the xcodebuild output, but using the Xcode

fastlane Community 247 Dec 13, 2022
An adorable little framework and command line tool for interacting with SourceKit.

SourceKitten An adorable little framework and command line tool for interacting with SourceKit. SourceKitten links and communicates with sourcekitd.fr

JP Simard 2.1k Jan 5, 2023
DevTool - A simple UI and powerful Mac OS application, Such as JSON-Formatting tool, JSON-to-model tool, AppIcon generator, Network-Request tool...

?? ?? ?? A simple UI and powerful Mac OS application. It is a collection of tools commonly used in my development work. Such as JSON-Formatting tool, JSON-to-model tool, AppIcon generator, Network-Request tool...

渠晓友 3 Dec 21, 2022
A little arcade game that uses SwiftUI as a game engine.

SwiftUI Game A little arcade game that uses SwiftUI as a game engine :) Just copy the code into the Blank playgroundbook in Swift Playgrounds app on i

Roman Gaditskiy 10 Sep 30, 2022
Little Go. An iOS application that lets you play the game of Go on the iPhone or iPad.

Introduction Little Go is a free and open source iOS application that lets you play the game of Go on the iPhone or iPad. You can play against another

Patrick Näf 121 Nov 26, 2022
A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.

A little and powerful iOS framework for intercepting HTTP/HTTPS Traffic.

Proxyman 867 Dec 29, 2022
A wrapper for NavigationView and NavigationLink that makes programmatic navigation a little friendlier.

NavigatorKit A wrapper for NavigationView and NavigationLink that makes programmatic navigation a little friendlier. NavigatorKit is an opinionated wr

Gyuri Grell 2 Jun 16, 2022
This little app aims to help teach me how to implement more then one API in one single application in a reusable and properly structured manner.

LilAPI App News & Weather This little API app combines two of Jordan Singers Lil Software API's into one app. The goal with this app was to learn how

hallux 1 Oct 13, 2021