Full Code of venmo/slather for AI

master 4dba0321f81f cached
95 files
348.6 KB
100.6k tokens
284 symbols
1 requests
Download .txt
Showing preview only (376K chars total). Download the full file or copy to clipboard to get everything.
Repository: venmo/slather
Branch: master
Commit: 4dba0321f81f
Files: 95
Total size: 348.6 KB

Directory structure:
gitextract_cr8xe6x0/

├── .coveralls.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── assets/
│   ├── highlight.pack.js
│   └── slather.css
├── bin/
│   └── slather
├── lib/
│   ├── cocoapods_plugin.rb
│   ├── slather/
│   │   ├── command/
│   │   │   ├── coverage_command.rb
│   │   │   ├── setup_command.rb
│   │   │   └── version_command.rb
│   │   ├── coverage_file.rb
│   │   ├── coverage_info.rb
│   │   ├── coverage_service/
│   │   │   ├── cobertura_xml_output.rb
│   │   │   ├── coveralls.rb
│   │   │   ├── gutter_json_output.rb
│   │   │   ├── hardcover.rb
│   │   │   ├── html_output.rb
│   │   │   ├── json_output.rb
│   │   │   ├── llvm_cov_output.rb
│   │   │   ├── simple_output.rb
│   │   │   └── sonarqube_xml_output.rb
│   │   ├── coveralls_coverage.rb
│   │   ├── profdata_coverage_file.rb
│   │   ├── project.rb
│   │   └── version.rb
│   └── slather.rb
├── slather.gemspec
└── spec/
    ├── fixtures/
    │   ├── FixtureFramework/
    │   │   ├── FixtureFramework.h
    │   │   ├── FlashExperiment.swift
    │   │   └── Info.plist
    │   ├── FixtureFrameworkTests/
    │   │   ├── FixtureFrameworkTests.swift
    │   │   ├── FlashExperimentTests.swift
    │   │   └── Info.plist
    │   ├── fixtures/
    │   │   ├── Fixtures.swift
    │   │   ├── Supporting Files/
    │   │   │   └── fixtures-Prefix.pch
    │   │   ├── fixtures.h
    │   │   ├── fixtures.m
    │   │   ├── fixtures_cpp.cpp
    │   │   ├── fixtures_cpp.h
    │   │   ├── fixtures_m.h
    │   │   ├── fixtures_m.m
    │   │   ├── fixtures_mm.h
    │   │   ├── fixtures_mm.mm
    │   │   ├── more_files/
    │   │   │   ├── Branches.h
    │   │   │   ├── Branches.m
    │   │   │   ├── Empty.h
    │   │   │   ├── Empty.m
    │   │   │   ├── peekaview.h
    │   │   │   └── peekaview.m
    │   │   └── other_fixtures.m
    │   ├── fixtures.xcodeproj/
    │   │   ├── project.pbxproj
    │   │   ├── project.xcworkspace/
    │   │   │   └── contents.xcworkspacedata
    │   │   └── xcshareddata/
    │   │       └── xcschemes/
    │   │           ├── aggregateFixturesTests.xcscheme
    │   │           ├── fixtures.xcscheme
    │   │           ├── fixturesTests.xcscheme
    │   │           ├── fixturesTestsSecond.xcscheme
    │   │           └── fixturesTwo.xcscheme
    │   ├── fixtures.xcworkspace/
    │   │   ├── contents.xcworkspacedata
    │   │   └── xcshareddata/
    │   │       ├── IDEWorkspaceChecks.plist
    │   │       └── xcschemes/
    │   │           └── fixturesTestsWorkspace.xcscheme
    │   ├── fixturesTests/
    │   │   ├── BranchesTests.m
    │   │   ├── Supporting Files/
    │   │   │   ├── en.lproj/
    │   │   │   │   └── InfoPlist.strings
    │   │   │   └── fixturesTests-Info.plist
    │   │   ├── fixturesTests.m
    │   │   ├── fixturesTestsSecond.m
    │   │   └── peekaviewTests💣.m
    │   ├── fixturesTwo/
    │   │   ├── fixturesTwo.h
    │   │   └── fixturesTwo.m
    │   ├── fixtures_html/
    │   │   ├── Branches.m.html
    │   │   ├── BranchesTests.m.html
    │   │   ├── fixtures.m.html
    │   │   ├── fixturesTests.m.html
    │   │   ├── index.html
    │   │   └── peekaviewTests💣.m.html
    │   ├── gutter.json
    │   └── sonarqube-generic-coverage.xml
    ├── slather/
    │   ├── cocoapods_plugin_spec.rb
    │   ├── coverage_file_spec.rb
    │   ├── coverage_service/
    │   │   ├── cobertura_xml_spec.rb
    │   │   ├── coveralls_spec.rb
    │   │   ├── gutter_json_spec.rb
    │   │   ├── hardcover_spec.rb
    │   │   ├── html_output_spec.rb
    │   │   ├── json_spec.rb
    │   │   ├── llvm_cov_spec.rb
    │   │   ├── simple_output_spec.rb
    │   │   └── sonarqube_xml_spec.rb
    │   ├── profdata_coverage_spec.rb
    │   └── project_spec.rb
    └── spec_helper.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .coveralls.yml
================================================
service_name: travis-ci

================================================
FILE: .gitignore
================================================
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
*.bundle
*.so
*.o
*.a
mkmf.log
.vendor
.ruby-version
cobertura.xml
.gutter.json
html
*.gcda
*.gcno

# Xcode
#
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
*.DS_Store

# VSCode IDE
.vscode/
.rdbgrc*

# python
.venv/

# JetBrains IDE
.idea/

# Test output
report.llcov
report.json

# VSCode
.vscode
.rdbgrc*

================================================
FILE: .travis.yml
================================================
language: objective-c
script: bundle exec rake
osx_image: xcode12.2

cache: bundler

before_install:
  - curl http://curl.haxx.se/ca/cacert.pem -o /usr/local/share/cacert.pem
  - gem install bundler -v "~> 2.0" --no-document

install:
  - bundle install --without=documentation


================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG

## v2.8.5

* Update xcodeproj to 1.27.1 to support Xcode 16 folder references
  [authiatr](https://github.com/authiatr)
  [#574](https://github.com/SlatherOrg/slather/pull/574)

## v2.8.4

* Don't crash when 0% coverage is causing empty JSON
  [jarrodlombardo-EventBase](https://github.com/jarrodlombardo-EventBase)
  [#570](https://github.com/SlatherOrg/slather/pull/570)

* Xcode 16 compatibility (as of beta 5)
  [ksuther](https://github.com/ksuther)
  [#568](https://github.com/SlatherOrg/slather/pull/568)

## v2.8.3

* Fix coverage_file.source_file_pathname
  [alfredofernandes](https://github.com/alfredofernandes)
  [#565](https://github.com/SlatherOrg/slather/pull/565)

* update cobertura DTD to a working URL.
  [jarrodlombardo-EventBase](https://github.com/jarrodlombardo-EventBase)
  [#564](https://github.com/SlatherOrg/slather/pull/564)

## v2.8.2

* coverage_info.include_files? needs a default true return value for when source_files is empty.
  [jarrodlombardo-EventBase](https://github.com/jarrodlombardo-EventBase)
  [#563](https://github.com/SlatherOrg/slather/pull/563)

## v2.8.1

* cobertura.sourceforge.net should use https instead of http
  [jarrodlombardo-EventBase](https://github.com/jarrodlombardo-EventBase)
  [#559](https://github.com/SlatherOrg/slather/pull/559)

* Handle include globs
  [dnedrow](https://github.com/dnedrow)
  [#553](https://github.com/SlatherOrg/slather/pull/553)

## v2.8.0

* Add `--ymlfile` option to override `.slather.yml`
  [jarrodlombardo-EventBase](https://github.com/jarrodlombardo-EventBase)
  [#550](https://github.com/SlatherOrg/slather/pull/550)

* Update list.js
  [AndriiZakhliupanyi](https://github.com/AndriiZakhliupanyi)
  [#546](https://github.com/SlatherOrg/slather/pull/546)

## v2.7.5

* Add `--cdn-assets` flag
  [sushant-here](https://github.com/sushant-here)
  [#537](https://github.com/SlatherOrg/slather/pull/537)

* Update nokogiri version

## v2.7.4

* Support Ruby 3.2.0
  [crazymanish](https://github.com/crazymanish)
  [#532](https://github.com/SlatherOrg/slather/pull/532)

## v2.7.3

* Support Coveralls parallel runs
  [paulz](https://github.com/paulz)
  [#523](https://github.com/SlatherOrg/slather/pull/523)

* Update nokogiri version
  [anil291987](https://github.com/anil291987)
  [#518](https://github.com/SlatherOrg/slather/pull/518)
  [#524](https://github.com/SlatherOrg/slather/pull/524)

## v2.7.2

* Update xcodeproj version
  [adamyanalunas](https://github.com/adamyanalunas)
  [#502](https://github.com/SlatherOrg/slather/pull/502)

* Update nokogiri version
  [jwelton](https://github.com/jwelton)
  [#503](https://github.com/SlatherOrg/slather/pull/503)

* Support alternate CI systems in coveralls output
  [fermoyadrop](https://github.com/fermoyadrop)
  [#504](https://github.com/SlatherOrg/slather/pull/504)

* Add Bitrise support to coveralls output
  [fermoyadrop](https://github.com/fermoyadrop)
  [#504](https://github.com/SlatherOrg/slather/pull/505)

## v2.7.1

* Support generating coverage for framework targets
  [onato](https://github.com/onato)
  [#482](https://github.com/SlatherOrg/slather/pull/482)

* Show number of lines in HTML report
  [SiemianHS](https://github.com/SiemianHS)
  [#494](https://github.com/SlatherOrg/slather/pull/494)

* Fixed issues with HTML report generation
  [fchiba](https://github.com/fchiba)
  [#483](https://github.com/SlatherOrg/slather/pull/483)
  [#484](https://github.com/SlatherOrg/slather/pull/484)

* Don't fail if a source file doesn't exist
  [chillpop](https://github.com/chillpop)
  [#492](https://github.com/SlatherOrg/slather/pull/492)

## v2.7.0

* Add Branch Coverage data for ProfData coverage files
  [hborawski](https://github.com/hborawski)
  [#477](https://github.com/SlatherOrg/slather/pull/477)

* Fixed 'Argument list too long' when running 'xcrun llvm-cov'
  [samuelsainz](https://github.com/samuelsainz)
  [#476](https://github.com/SlatherOrg/slather/pull/476)

## v2.6.1

* Update nokogiri to 1.11
  [ashin-omg](https://github.com/ashin-omg)
  [#473](https://github.com/SlatherOrg/slather/pull/473)

## v2.6.0

* Added GitHub actions support
  [martin-key](https://github.com/martin-key), [troyfontaine](https://github.com/troyfontaine)
  [#468](https://github.com/SlatherOrg/slather/pull/468)

## v2.5.0

* Fixed activesupport and cocoapods dependencies
  [daneov](https://github.com/daneov)
  [#456](https://github.com/SlatherOrg/slather/pull/467)

* Fixed typo in documentation
  [descorp](https://github.com/descorp)
  [#456](https://github.com/SlatherOrg/slather/pull/463)

## v2.4.9

* Added support for Sonarqube output
  [adellibovi](https://github.com/adellibovi)
  [#456](https://github.com/SlatherOrg/slather/pull/456)

## v2.4.8

* Optimize performance for many binaries
  [cltnschlosser](https://github.com/cltnschlosser)
  [#455](https://github.com/SlatherOrg/slather/pull/455)

* Don't generate line 0 in profdata_coverage_file.rb from line with error
  [tthbalazs](https://github.com/tthbalazs)
  [#449](https://github.com/SlatherOrg/slather/pull/449)

* coveralls dependency update
  [GRiMe2D](https://github.com/GRiMe2D)
  [#448](https://github.com/SlatherOrg/slather/pull/448)

## v2.4.7

* Update dependencies
  [dnedrow](https://github.com/dnedrow)

* Fixed errors when llvm-cov argument length exceeds ARG_MAX
  [weibel](https://github.com/weibel)
  [#414](https://github.com/SlatherOrg/slather/pull/414)

* Show "No coverage directory found." instead of "implicit conversion nil into String"
  [phimage](https://github.com/phimage)
  [#381](https://github.com/SlatherOrg/slather/pull/381) [#341](https://github.com/SlatherOrg/slather/issues/341)

## v2.4.6

* Fix .dSYM and .swiftmodule files filtering in find_binary_files()
  [krin-san](https://github.com/krin-san)
  [#368](https://github.com/SlatherOrg/slather/pull/368)

* Fixed loading coverage for a single source file
  [blackm00n](https://github.com/blackm00n)
  [#377](https://github.com/SlatherOrg/slather/pull/377) [#398](https://github.com/SlatherOrg/slather/pull/398)

* Fixed truncated file list in HTML export
  [miroslavkovac](https://github.com/miroslavkovac)
  [#402](https://github.com/SlatherOrg/slather/pull/402) [#261](https://github.com/SlatherOrg/slather/issues/261)

## v2.4.5

* Support for specifying a specific binary architecture
  [ksuther](https://github.com/ksuther), [nickolas-pohilets](https://github.com/nickolas-pohilets)
  [#367](https://github.com/SlatherOrg/slather/pull/367)

* Added absolute statement count to simple output (instead of showing just a percentage)
  [barrault01](https://github.com/barrault01), [ivanbrunel](https://github.com/ivanbruel)
  [#365](https://github.com/SlatherOrg/slather/pull/365)

* Updated nokogiri dependency version
  [#363](https://github.com/SlatherOrg/slather/issues/363), [#366](https://github.com/SlatherOrg/slather/pull/366)

* slather now requires ruby 2.1 or later (10.13 ships with 2.3.3)

## v2.4.4

* Added llvm-cov output format
  [sgtsquiggs](https://github.com/sgtsquiggs) [#354](https://github.com/SlatherOrg/slather/pull/354)

* Exclude swiftmodule from product search
  [lampietti](https://github.com/lampietti) [#352](https://github.com/SlatherOrg/slather/pull/352)

## v2.4.3

* Initial Xcode 9 support
  [ksuther](https://github.com/ksuther) [#339](https://github.com/SlatherOrg/slather/pull/339), [ivanbrunel](https://github.com/ivanbruel) [#321](https://github.com/SlatherOrg/slather/pull/321), [FDREAL](https://github.com/FDREAL) [#338](https://github.com/SlatherOrg/slather/pull/338)

* Add `--json` output option for basic JSON format not specific to any particular service.
  [ileitch](https://github.com/ileitch)
  [#318](https://github.com/SlatherOrg/slather/pull/318)

## v2.4.2

* Restored support for Xcode 7  
  [ButkiewiczP](https://github.com/ButkiewiczP)
  [#304](https://github.com/slatherOrg/slather/pull/308)

* Added Jenkins Pipeline support for Coveralls  
  [daneov](https://github.com/daneov)
  [#304](https://github.com/slatherOrg/slather/pull/304)

## v2.4.1

* Add `--configuration` option  
  [thasegaw](https://github.com/thasegaw)
  [#294](https://github.com/slatherOrg/slather/pull/294)

* Fix misdetection of Xcode version if Spotlight hasn't indexed Xcode yet  
  [ksuther](https://github.com/ksuther)
  [#298](https://github.com/slatherOrg/slather/pull/298)

* Better verbose message when no binaries are found  
  [ksuther](https://github.com/ksuther)
  [#300](https://github.com/slatherOrg/slather/pull/300)

## v2.4.0

* Xcode 8.3 support.
  [ksuther](https://github.com/ksuther)
  [#291](https://github.com/SlatherOrg/slather/pull/291)

* Automatically ignore headers in Xcode platform SDKs.  
  [ksuther](https://github.com/ksuther)
  [#286](https://github.com/SlatherOrg/slather/pull/286)

* Automatically handle schemes with multiple build or test targets  
  [serges147](https://github.com/serges147)
  [#275](https://github.com/SlatherOrg/slather/pull/275)

* Added TeamCity as a CI service option  
  [joshrlesch](https://github.com/joshrlesch)
  [#279](https://github.com/SlatherOrg/slather/pull/279)

* Handle UTF-8 characters correctly in HTML reports  
  [0xced](https://github.com/0xced)
  [#259](https://github.com/SlatherOrg/slather/pull/259)

* Fix hanging `xcodebuild` invocation when getting derived data path.  
  [arthurtoper](https://github.com/arthurtoper)
  [#238](https://github.com/SlatherOrg/slather/pull/238), [#197](https://github.com/SlatherOrg/slather/issues/197), [#212](https://github.com/SlatherOrg/slather/issues/212), [#234](https://github.com/SlatherOrg/slather/issues/234)

## v2.3.0

* Fixes broken fallback value of `input_format` inside `configure_input_format`  
  [sbhklr](https://github.com/sbhklr)
  [#233](https://github.com/SlatherOrg/slather/pull/233), [#232](https://github.com/SlatherOrg/slather/issues/232)

* Add `--travispro` flag  
  [sbhklr](https://github.com/sbhklr)
  [#223](https://github.com/SlatherOrg/slather/pull/223), [#219](https://github.com/SlatherOrg/slather/issues/219)

* Fixes silent failure in case of unsuccessful upload to Coveralls  
  [sbhklr](https://github.com/sbhklr)
  [#222](https://github.com/SlatherOrg/slather/pull/222), [#217](https://github.com/SlatherOrg/slather/issues/217)

## v2.2.1

* Make `project.coverage_files` public  
* Add docs attribute reader to `project.rb`  
  [bootstraponline](https://github.com/bootstraponline)
  [#209](https://github.com/SlatherOrg/slather/pull/209)

* Add `--decimals` flag  
  [bootstraponline](https://github.com/bootstraponline)
  [#207](https://github.com/SlatherOrg/slather/pull/207)

* Add `slather version` command  
  [bootstraponline](https://github.com/bootstraponline)
  [#208](https://github.com/SlatherOrg/slather/pull/208)

## v2.2.0

* Fix nil crash in `project.rb` derived_data_path  
  [bootstraponline](https://github.com/bootstraponline)
  [#203](https://github.com/SlatherOrg/slather/pull/203)

* Fix for correct line number for lines that are hit thousands or millions of time in llvm-cov.  
  [Mihai Parv](https://github.com/mihaiparv)
  [#202](https://github.com/SlatherOrg/slather/pull/202), [#196](https://github.com/SlatherOrg/slather/issues/196)

* Generate coverate for multiple binaries by passing multiple `--binary-basename` or `--binary-file` arguments, or by using an array in `.slather.yml`  
  [Kent Sutherland](https://github.com/ksuther)
  [#188](https://github.com/SlatherOrg/slather/pull/188)

* Support for specifying source file patterns using the `--source-files` option or the source_files key in `.slather.yml`  
  [Matej Bukovinski](https://github.com/matej)
  [#201](https://github.com/SlatherOrg/slather/pull/201)

* Improve getting schemes. Looks for user scheme in case no shared scheme is found.  
  [Matyas Hlavacek](https://github.com/matyashlavacek)
  [#182](https://github.com/SlatherOrg/slather/issues/182)

* Search Xcode workspaces for schemes. Workspaces are checked if no matching scheme is found in the project.  
  [Kent Sutherland](https://github.com/ksuther)
  [#193](https://github.com/SlatherOrg/slather/pull/193), [#191](https://github.com/SlatherOrg/slather/issues/191)

* Fix for hit counts in thousands or millions being output as floats intead of integers  
  [Carl Hill-Popper](https://github.com/chillpop)
  [#190](https://github.com/SlatherOrg/slather/pull/190)

## v2.1.0

* Support for Xcode workspaces. Define `workspace` configuration in `.slather.yml` or use the `--workspace` argument if you build in a workspace.
* Improved slather error messages  
  [Kent Sutherland](https://github.com/ksuther)
  [#178](https://github.com/SlatherOrg/slather/issues/178)

* Re-add Teamcity support  
  [Boris Bügling](https://github.com/neonichu)
  [#180](https://github.com/SlatherOrg/slather/pull/180)

* Show lines that are hit thousands or millions of time in llvm-cov  
  [Kent Sutherland](https://github.com/ksuther)
  [#179](https://github.com/SlatherOrg/slather/pull/179)

* Fix for setting scheme/workspace from configuration file.  
  [Boris Bügling](https://github.com/neonichu)
  [#183](https://github.com/SlatherOrg/slather/pull/183)

## v2.0.2

* Escape the link to file names properly  
  [Thomas Mellenthin](https://github.com/melle)
  [#158](https://github.com/SlatherOrg/slather/pull/158)

* Product info is now read from schemes. Specify a scheme in `.slather.yml` or with the `--scheme` argument to ensure consistent results. Automatically detect the derived data directory from `xcodebuild`  
  [Kent Sutherland](https://github.com/ksuther)
  [#174](https://github.com/SlatherOrg/slather/pull/174)

* Xcode 7.3 compatibility (updated path returned by `profdata_coverage_dir`)  
  [Kent Sutherland](https://github.com/ksuther)
  [#125](https://github.com/SlatherOrg/slather/issues/125), [#169](https://github.com/SlatherOrg/slather/pull/169)

* Improve matching of xctest bundles when using `--binary-basename`  
  [Kent Sutherland](https://github.com/ksuther)
  [#167](https://github.com/SlatherOrg/slather/pull/167)

* Build Statistic Reporting for TeamCity  
  [Michael Myers](https://github.com/michaelmyers)
  [#150](https://github.com/SlatherOrg/slather/pull/150)

* Use named classes for subcommands in bin/slather  
  [bootstraponline](https://github.com/bootstraponline)
  [#170](https://github.com/SlatherOrg/slather/pull/170)

## v2.0.1

* Fixes how `profdata_coverage_dir` is created.  
  [guidomb](https://github.com/guidomb)
  [#145](https://github.com/SlatherOrg/slather/pull/145)

## v2.0.0
* Correct html rendering when using profdata format   
  [cutz](https://github.com/cutz)
  [#124](https://github.com/SlatherOrg/slather/pull/124)

* Making HTML directory self contained   
  [Colin Cornaby](https://github.com/colincornaby)
  [#137](https://github.com/SlatherOrg/slather/pull/137)

* Add `binary_basename` configuration option   
  [Boris Bügling](https://github.com/neonichu)
  [#128](https://github.com/SlatherOrg/slather/pull/128)

* Add support to profdata file format   
  [Simone Civetta](https://github.com/viteinfinite)
  [Olivier Halligon](https://github.com/AliSoftware)
  [Matt Delves](https://github.com/mattdelves)
  [Pierre-Marc Airoldi](https://github.com/petester42)
  [#92](https://github.com/venmo/slather/pull/92)

## v1.8.3
* Add buildkite support to coveralls   
  [David Hardiman](https://github.com/dhardiman)
  [#98](https://github.com/venmo/slather/pull/98)
* Update to xcodeproj 0.28.0 to avoid collisions with Cocoapods 0.39.0   
  [Julian Krumow](https://github.com/tarbrain)   
  [#106](https://github.com/venmo/slather/pull/106)/[#109](https://github.com/venmo/slather/pull/109)

## v1.8.1
* Fixed dependency conflict with CocoaPods v0.38
* Updated usage of cocoapods plugin API since it has changed in v0.38   
  [Julian Krumow](https://github.com/tarbrain)
  [#95](https://github.com/venmo/slather/pull/95)

## v1.7.0
* Objective-C++ support  
  [ben-ng](https://github.com/ben-ng)
  [#63](https://github.com/venmo/slather/pull/63)

## v1.6.0
* Add CircleCI support  
  [Jonathan Hersh](https://github.com/jhersh)
  [#55](https://github.com/venmo/slather/pull/55)

## v1.5.4

* Fix calculation of branch coverage when a class has no branches  
  [Julian Krumow](https://github.com/tarbrain)
  [#40](https://github.com/venmo/slather/pull/40)

* Always consider empty files as 100% tested  
  [Boris Bügling](https://github.com/neonichu)
  [#45](https://github.com/venmo/slather/pull/45)

## v1.5.2

* Add an option to define the output directory for cobertura xml reports  
  [Julian Krumow](https://github.com/tarbrain)
  [#37](https://github.com/venmo/slather/pull/37)

## v1.5.1

* Avoid crashes when coverage data is empty
* Fix bug which prevented source files without coverage data to be included in Cobertura xml report  
  [Julian Krumow](https://github.com/tarbrain)
  [#34](https://github.com/venmo/slather/pull/34)

## v1.5.0

* Add support for Cobertura  
  [Julian Krumow](https://github.com/tarbrain)
  [#30](https://github.com/venmo/slather/pull/30)

## v1.4.0

* Implement a CocoaPods plugin  
  [Kyle Fuller](https://github.com/kylef)
  [#25](https://github.com/venmo/slather/pull/25)

* Avoid getting 'Infinity' or 'NaN' when dividing by 0.0  
  [Mark Larsen](https://github.com/marklarr)

* Ignore exceptions about files not existing by using 'force'  
  [Mark Larsen](https://github.com/marklarr)

## v1.3.0

* Add Gutter JSON output  
  [Boris Bügling](https://github.com/neonichu)
  [#24](https://github.com/venmo/slather/pull/24)

## v1.2.1

* Fix typo --simple-output description  
  [Ayaka Nonaka](https://github.com/ayanonagon)
  [#19](https://github.com/venmo/slather/pull/19)

* Remove broken travis pro support  
  [Mark Larsen](https://github.com/marklarr)
  [#22](https://github.com/venmo/slather/pull/22)

* Fix exception for files without `@interface` or `@implementation`  
  [Piet Brauer](https://github.com/pietbrauer)
  [#23](https://github.com/venmo/slather/pull/23)

## v1.2.0

* Remove duplicate coverage files, favoring the file with higher coverage.  
  [Ayaka Nonaka](https://github.com/ayanonagon)
  [#16](https://github.com/venmo/slather/pull/16)

* Add support for access token and Travis Pro  
  [Chris Maddern](https://github.com/chrismaddern)
  [#17](https://github.com/venmo/slather/pull/17)

## v1.1.0

* Support for code coverage of pods  
  [Mark Larsen](https://github.com/marklarr)

## v1.0.1

* Fix coverage search for files that contain spaces  
  [Mark Larsen](https://github.com/marklarr)

## v1.0.0

* beautified README  
  [Ayaka Nonaka](https://github.com/ayanonagon)
  [#4](https://github.com/venmo/slather/pull/4)  
  [Kyle Fuller](https://github.com/kylef)
  [#5](https://github.com/venmo/slather/pull/5)

* Add Travis automated builds  
  [Mark Larsen](https://github.com/marklarr)
  [#6](https://github.com/venmo/slather/pull/6)

* Use `||=` instead of `unless`  
  [Ayaka Nonaka](https://github.com/ayanonagon)
  [#7](https://github.com/venmo/slather/pull/7)

## v0.0.31

* find source files via pbx proj rather than file system  
  [Mark Larsen](https://github.com/marklarr)

## v0.0.3

* Initial Release  
  [Mark Larsen](https://github.com/marklarr)


================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'

# Specify your gem's dependencies in slather.gemspec
gemspec


================================================
FILE: LICENSE.txt
================================================
Copyright (c) 2014 Mark Larsen

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================


![Slather Logo](https://raw.githubusercontent.com/SlatherOrg/slather/master/docs/logo.jpg)

[![Gem Version](https://badge.fury.io/rb/slather.svg)](http://badge.fury.io/rb/slather)
[![Build Status](https://travis-ci.org/SlatherOrg/slather.svg?branch=master)](https://travis-ci.org/SlatherOrg/slather)
[![Coverage Status](https://coveralls.io/repos/SlatherOrg/slather/badge.svg?branch=master)](https://coveralls.io/r/SlatherOrg/slather?branch=master)

Generate test coverage reports for Xcode projects & hook it into CI.

### Projects that use Slather

| Project | Coverage |
| ------- |:--------:|
| [Parsimmon](https://github.com/ayanonagon/Parsimmon) | [![Parsimmon Coverage](https://coveralls.io/repos/ayanonagon/Parsimmon/badge.svg?branch=master)](https://coveralls.io/r/ayanonagon/Parsimmon?branch=master) |
| [VENCore](https://github.com/venmo/VENCore) | [![VENCore Coverage](https://coveralls.io/repos/venmo/VENCore/badge.svg?branch=master)](https://coveralls.io/r/venmo/VENCore?branch=master) |
| [DAZABTest](https://github.com/dasmer/DAZABTest) | [![DAZABTest Coverage](https://coveralls.io/repos/dasmer/DAZABTest/badge.svg?branch=master)](https://coveralls.io/r/dasmer/DAZABTest?branch=master) |
| [TBStateMachine](https://github.com/tarbrain/TBStateMachine) | [![TBStateMachine Coverage](https://coveralls.io/repos/tarbrain/TBStateMachine/badge.svg?branch=master)](https://coveralls.io/r/tarbrain/TBStateMachine?branch=master) |

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'slather'
```

And then execute:

```sh
$ bundle
```

Or install the gem:

```sh
gem install slather
```

## Usage

Enable test coverage by ticking the *"Gather coverage data"* checkbox when editing a scheme:

![](README_Images/test_scheme.png)

To verify you're ready to generate test coverage, run your test suite on your project, and then run:

```sh
$ slather coverage -s --scheme YourXcodeSchemeName path/to/project.xcodeproj
```

If you use a workspace in Xcode you need to specify it: 

```sh
$ slather coverage -s --scheme YourXcodeSchemeName --workspace path/to/workspace.xcworkspace path/to/project.xcodeproj
```

If you use a different configuration for your tests: 

```sh
$ slather coverage -s --scheme YourXcodeSchemeName --configuration YourBuildConfigurationName path/to/project.xcodeproj
```

If your configuration produces a universal binary you need to specify a specific architecture to use: 

```sh
$ slather coverage -s --arch x86_64 --scheme YourXcodeSchemeName --configuration YourBuildConfigurationName path/to/project.xcodeproj
```

### For multiple modules

If you want to run some modules, but not all (like modules created by CocoaPods) you can do it like this:

```sh
$ slather coverage --binary-basename module1 --binary-basename module2 path/to/project.xcodeproj
```
You can also add it to the `.slather.yml` file as an array:
```yml
binary_basename:
  - module1
  - module2
```

### Setup for Xcode 5 and 6

Run this command to enable the `Generate Test Coverage` and `Instrument Program Flow` flags for your project:

```sh
$ slather setup path/to/project.xcodeproj
```
## General Usage Notes
### Commandline Arguments Win
When using both a config file (`.slather.yml`) and providing arguments via the commandline,
the arguments will take precedence over the matching setting in the config file.

### `ignore` always wins over `source-files`
When defining both files that should be ignored (`--ignore`, ignore) and source files to include (`--source-files`, source_files),
the ignore list is checked first. If the file being scanned matches a glob in the ignore list, it will not be included. In this case, the
source_file list is not checked.

If the file being scanned is not in the ignore list, and source_file has been defined, the source_file list is
checked. If the source file matches a glob, it will be included.

## CI Integration
### Usage with Codecov

Login to [Codecov](https://codecov.io/) (no need to activate a repository, this happens automatically). Right now, `slather` supports Codecov via **all** supported CI providers [listed here](https://github.com/codecov/codecov-bash#ci-providers).

Make a `.slather.yml` file:

```yml
# .slather.yml

coverage_service: cobertura_xml
xcodeproj: path/to/project.xcodeproj
scheme: YourXcodeSchemeName
configuration: TestedConfiguration
source_directory: path/to/sources/to/include
output_directory: path/to/xml_report
ignore:
  - ExamplePodCode/*
  - ProjectTestsGroup/*
```

And then in your `.travis.yml`, `circle.yml` (or after test commands in other CI providers), call `slather` after a successful build:

```yml
# .travis.yml

before_install: rvm use $RVM_RUBY_VERSION
install: bundle install --without=documentation --path ../travis_bundle_dir
after_success: 
  - slather
  - bash <(curl -s https://codecov.io/bash) -f path/to/xml_report/cobertura.xml -X coveragepy -X gcov -X xcode
```

```yml
# circle.yml

test:
  post:
    - bundle exec slather
    - bash <(curl -s https://codecov.io/bash) -f path/to/xml_report/cobertura.xml -X coveragepy -X gcov -X xcode
```

> Private repo? Add `-t :uuid-repo-token` to the codecov uploader. Read more about uploading report to Codecov [here](https://github.com/codecov/codecov-bash)

### Usage with Coveralls

Login to [Coveralls](https://coveralls.io/) and enable your repository. Right now, `slather` supports Coveralls via [Travis CI](https://travis-ci.org), [CircleCI](https://circleci.com), [Jenkins](https://www.jenkins.io/), [Teamcity](https://www.jetbrains.com/teamcity/), [Buildkite](https://buildkite.com/), and [Bitrise](https://bitrise.io/).

Make a `.slather.yml` file and specify the CI Service you're using:

```yml
# .slather.yml

ci_service: circleci | travis_ci | travis_pro | jenkins | buildkite | teamcity
coverage_service: coveralls
xcodeproj: path/to/project.xcodeproj
scheme: YourXcodeSchemeName
ignore:
  - ExamplePodCode/*
  - ProjectTestsGroup/*
```

And then in your `.travis.yml` or `circle.yml` or `github-action.yml`, call `slather` after a successful build:

```yml
# .travis.yml

before_install: rvm use $RVM_RUBY_VERSION
install: bundle install --without=documentation --path ../travis_bundle_dir
after_success: slather
```

```yml
# circle.yml

test:
  post:
    - bundle exec slather

```

```yml
# github-action.yml
  myjob:
    steps:
      - run: |
          bundle config path vendor/bundle
          bundle install --without=documentation --jobs 4 --retry 3
      - name: Extract branch name
        shell: bash
        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
        id: get_branch
      - run: bundle exec slather
        env:
          GIT_BRANCH: ${{ steps.get_branch.outputs.branch }}
          CI_PULL_REQUEST: ${{ github.event.number }}
          COVERAGE_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}

```

#### Usage with Travis CI Pro

To use Coveralls with Travis CI Pro (for private repos), add following lines along with other settings to `.slather.yml`:

```yml
# .slather.yml

ci_service: travis_pro
coverage_access_token: <YOUR ACCESS TOKEN>
```

The coverage token can be found at [Coveralls](https://coveralls.io/) repo page. Or it can be passed in via the `COVERAGE_ACCESS_TOKEN` environment var.

### Cobertura

To create a Cobertura XML report set `cobertura_xml` as coverage service inside your `.slather.yml`. Optionally you can define an output directory for the XML report:

```yml
# .slather.yml

coverage_service: cobertura_xml
xcodeproj: path/to/project.xcodeproj
scheme: YourXcodeSchemeName
source_directory: path/to/sources/to/include
output_directory: path/to/xml_report
ignore:
  - ExamplePodCode/*
  - ProjectTestsGroup/*
```

Or use the command line options `--cobertura-xml` or `-x` and `--output-directory`:

```sh
$ slather coverage -x --output-directory path/to/xml_report
```

### Static HTML

To create a report as static html pages, use the command line options `--html`:

```sh
$ slather coverage --html --scheme YourXcodeSchemeName path/to/project.xcodeproj
```

This will make a directory named `html` in your root directory (unless `--output-directory` is specified) and will generate all the reports as static html pages inside the directory. It will print out the report's path by default, but you can also specify `--show` flag to open it in your browser automatically.

By default, the generated HTML will reference locally hosted assets (js, css). You can specify the `--cdn-assets` to specify that you prefer for the generated HTML to use externally hosted assets. This can be useful if publishing the HTML file as a build artifact. 

### TeamCity Reporting

To report the coverage statistics to TeamCity:

```sh
$ slather coverage --teamcity -s --scheme YourXcodeSchemeName
```

### Coverage for code included via CocoaPods

If you're trying to compute the coverage of code that has been included via
CocoaPods, you will need to tell CocoaPods to use the Slather plugin by
adding the following to your `Podfile`.

```ruby
plugin 'slather'
```

You will also need to tell Slather where to find the source files for your Pod.

```yml
# .slather.yml

source_directory: Pods/AFNetworking
```

### Custom Build Directory

Slather will look for the test coverage files in `DerivedData` by default. If you send build output to a custom location, like [this](https://github.com/erikdoe/ocmock/blob/7f4d22b38eedf1bb9a12ab1591ac0a5d436db61a/Tools/travis.sh#L12), then you should also set the `build_directory` property in `.slather.yml`

### Building in a workspace

Include the `--workspace` argument or add `workspace` to `.slather.yml` if you build your project in a workspace. For example:

```sh
$ slather coverage --html --scheme YourXcodeSchemeName --workspace path/to/workspace.xcworkspace path/to/project.xcodeproj
```

## Contributing

We’d love to see your ideas for improving this library! The best way to contribute is by submitting a pull request. We’ll do our best to respond to your patch as soon as possible. You can also submit a [new GitHub issue](https://github.com/SlatherOrg/slather/issues/new) if you find bugs or have questions. :octocat:

Please make sure to follow our general coding style and add test coverage for new features!

## Contributors

* [@tpoulos](https://github.com/tpoulos), the perfect logo.
* [@ayanonagon](https://github.com/ayanonagon) and [@kylef](https://github.com/kylef), feedback and testing.
* [@jhersh](https://github.com/jhersh), CircleCI support.
* [@tarbrain](https://github.com/tarbrain), Cobertura support and bugfixing.
* [@ikhsan](https://github.com/ikhsan), html support.
* [@martin-key](https://github.com/martin-key) and [@troyfontaine](https://github.com/troyfontaine), Github Actions support.


================================================
FILE: Rakefile
================================================
require "bundler/gem_tasks"
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)

task default: :spec


================================================
FILE: assets/highlight.pack.js
================================================
!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/no-?highlight|plain|text/.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:"start"==r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}f+="<"+t(e)+Array.prototype.map.call(e.attributes,r).join("")+">"}function u(e){f+="</"+t(e)+">"}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":w.classPrefix,i='<span class="'+a,o=t?"":"</span>";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(B);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(B);r;){e+=n(B.substr(t,r.index-t));var a=g(L,r);a?(y+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(B)}return e+n(B.substr(t))}function d(){if(L.sL&&!x[L.sL])return n(B);var e=L.sL?f(L.sL,B,!0,M[L.sL]):l(B);return L.r>0&&(y+=e.r),"continuous"==L.subLanguageMode&&(M[L.sL]=e.top),h(e.language,e.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,B=""):e.eB?(k+=n(t)+r,B=""):(k+=r,B=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(B+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(B+=t),k+=b();do L.cN&&(k+="</span>"),y+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),B="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"<unnamed>")+'"');return B+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,L=i||N,M={},k="";for(R=L;R!=N;R=R.parent)R.cN&&(k=h(R.cN,"",!0)+k);var B="",y=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),R=L;R.parent;R=R.parent)R.cN&&(k+="</span>");return{r:y,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||w.languages||Object.keys(x);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return w.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,w.tabReplace)})),w.useBR&&(e=e.replace(/\n/g,"<br>")),e}function h(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;w.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){w=o(w,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){R[e]=n})}function N(){return Object.keys(x)}function E(e){return x[e]||x[R[e]]}var w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},x={},R={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="\\b(0[xX][a-fA-F0-9]+|(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",bK:"TODO FIXME NOTE BUG XXX",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\w+"},i={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:i,l:o,i:"</",c:[t,e.CLCM,e.CBCM,e.CNM,e.QSM,{cN:"string",v:[{b:'@"',e:'"',i:"\\n",c:[e.BE]},{b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"}]},{cN:"preprocessor",b:"#",e:"$",c:[{cN:"title",v:[{b:'"',e:'"'},{b:"<",e:">"}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:o,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"[a-z\\d_]*_t"},r={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","cc","h","c++","h++","hpp"],k:r,i:"</",c:[e,t.CLCM,t.CBCM,{cN:"string",v:[t.inherit(t.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},t.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line pragma",c:[{b:/\\\n/,r:0},{b:'include\\s*[<"]',e:'[>"]',k:"include",i:"\\n"},t.CLCM]},{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:r,c:["self",e]},{b:t.IR+"::",k:r},{bK:"new throw return else",r:0},{cN:"function",b:"("+t.IR+"\\s+)+"+t.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:t.IR+"\\s*\\(",rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[t.CBCM]},t.CLCM,t.CBCM]}]}});

================================================
FILE: assets/slather.css
================================================
/* --------------------------------------------------------
Slather stylesheet

version: 0.1
author: Ikhsan Assaat (@ixnixnixn)
----------------------------------------------------------*/

/* General */
html {
  position: relative;
  min-height: 100%;
}
body {
  font: 16px "Helvetica", sans-serif;
  margin: 0 0 120px;
  color: #333;
}
.row { margin: 0 2em; }

/* Header */
header { margin-top: 1em; }
header img { width: auto; height: 120px; }

/* Coverage */
#reports > h2 { margin-bottom: 0; }
#reports > h4 { margin-top: 5px; }
.percentage {
  padding: 4px ;
  font-weight: bold;
}
.cov_high { color: #67CF7C; }
.cov_medium { color: #F89404; }
.cov_low { color: #F86769; }
.cov_title { margin-bottom: 0; }
.cov_subtitle { margin-top: 0.2em; }
.cov_filepath { font-style: italic; }

/* Index Table */
table.coverage_list {
  width: 90%;
  min-width: 400px;
}
table.coverage_list th,
table.coverage_list td {
  padding: .6em .5em;
  text-align: left;
}
table.coverage_list th.col_num { width: 70px; }
table.coverage_list th.col_percent { width: 75px; }
table.coverage_list thead, tfoot { background: #FDCD9B; }
table.coverage_list tbody tr:hover { background: #FCF2E6; }
table.coverage_list tbody td { border-bottom: 1px solid #CCC; }
table.coverage_list td a {
  color: #333;
  text-decoration: none;
  border-bottom: 1px dotted;
}
table.coverage_list td a:hover {
  border-bottom: none;
}

/* Source Code */
table.source_code {
  width: 100%;
  max-width: 1200px;
  min-width: 400px;
  font-size: 13px;
  border-spacing: 0;
  background: #FCF2E6;
  padding: 1.2em 1em;
  margin-bottom: 2em;
}

table.source_code td {
  padding-bottom: 0.3em;
}
code.missed { background-color: rgba(255, 73, 76, 0.3); }
table.source_code tr.missed td { background-color: rgba(248, 103, 105, 0.2); }
table.source_code tr.covered td { background-color: rgba(103, 207, 124, 0.2); }
table.source_code td.num {
  border-right: 1px rgba(0,0,0,0.1) solid;
  text-align: right;
  padding-right: 1em;
  width: 30px;
}
table.source_code td.src {
  border-left: 1px rgba(255,255,255,0.7) solid;
  padding-left: 1em;
}
table.source_code td.src pre {
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  white-space: -pre-wrap;
  white-space: -o-pre-wrap;
  word-wrap: break-word;
  margin: 0;
}
table.source_code td.src pre code { font: 13px "Menlo", "Courier New"; }

table.source_code td.coverage {
  text-align: right;
  padding-right: 0.5em;
}

/* Footer */
footer {
  background-color: #67CDCF;
  height: 80px;

  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  overflow:hidden;
}

footer p, footer a {
  color: #ffffff;
  font-weight: bold;
  text-align: center;
}


/* ----------------------------------------------------------
Syntax Highlighting using highlight.js (https://highlightjs.org)
------------------------------------------------------------- */
.hljs {
  display: inline-block;
  overflow-x: auto;
  -webkit-text-size-adjust: none;
}

.hljs,
.hljs-subst,
.hljs-tag .hljs-title,
.nginx .hljs-title {
  color: #333;
}

.hljs-string,
.hljs-title,
.hljs-constant,
.hljs-parent,
.hljs-tag .hljs-value,
.hljs-rule .hljs-value,
.hljs-preprocessor,
.hljs-pragma,
.hljs-name,
.haml .hljs-symbol,
.ruby .hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.hljs-template_tag,
.django .hljs-variable,
.smalltalk .hljs-class,
.hljs-addition,
.hljs-flow,
.hljs-stream,
.bash .hljs-variable,
.pf .hljs-variable,
.apache .hljs-tag,
.apache .hljs-cbracket,
.tex .hljs-command,
.tex .hljs-special,
.erlang_repl .hljs-function_or_atom,
.asciidoc .hljs-header,
.markdown .hljs-header,
.coffeescript .hljs-attribute,
.tp .hljs-variable {
  color: #D14F4F;
}

.smartquote,
.hljs-comment,
.hljs-annotation,
.diff .hljs-header,
.hljs-chunk,
.asciidoc .hljs-blockquote,
.markdown .hljs-blockquote {
  color: #888;
}

.hljs-number,
.hljs-date,
.hljs-regexp,
.hljs-literal,
.hljs-hexcolor,
.smalltalk .hljs-symbol,
.smalltalk .hljs-char,
.go .hljs-constant,
.hljs-change,
.lasso .hljs-variable,
.makefile .hljs-variable,
.asciidoc .hljs-bullet,
.markdown .hljs-bullet,
.asciidoc .hljs-link_url,
.markdown .hljs-link_url {
  color: #05A5A8;
}

.hljs-label,
.ruby .hljs-string,
.hljs-decorator,
.hljs-filter .hljs-argument,
.hljs-localvars,
.hljs-array,
.hljs-attr_selector,
.hljs-important,
.hljs-pseudo,
.hljs-pi,
.haml .hljs-bullet,
.hljs-doctype,
.hljs-deletion,
.hljs-envvar,
.hljs-shebang,
.apache .hljs-sqbracket,
.nginx .hljs-built_in,
.tex .hljs-formula,
.erlang_repl .hljs-reserved,
.hljs-prompt,
.asciidoc .hljs-link_label,
.markdown .hljs-link_label,
.vhdl .hljs-attribute,
.clojure .hljs-attribute,
.asciidoc .hljs-attribute,
.lasso .hljs-attribute,
.coffeescript .hljs-property,
.hljs-phony {
  color: #087599;
}

.hljs-keyword,
.hljs-id,
.hljs-title,
.hljs-built_in,
.css .hljs-tag,
.hljs-doctag,
.smalltalk .hljs-class,
.hljs-winutils,
.bash .hljs-variable,
.pf .hljs-variable,
.apache .hljs-tag,
.hljs-type,
.hljs-typename,
.tex .hljs-command,
.asciidoc .hljs-strong,
.markdown .hljs-strong,
.hljs-request,
.hljs-status,
.tp .hljs-data,
.tp .hljs-io {
  font-weight: bold;
}

.asciidoc .hljs-emphasis,
.markdown .hljs-emphasis,
.tp .hljs-units {
  font-style: italic;
}

.nginx .hljs-built_in {
  font-weight: normal;
}

.coffeescript .javascript,
.javascript .xml,
.lasso .markup,
.tex .hljs-formula,
.xml .javascript,
.xml .vbscript,
.xml .css,
.xml .hljs-cdata {
  opacity: 0.5;
}

/* -------------------------------------------------------
Sorting & Filtering with List.js (http://www.listjs.com/)
------------------------------------------------------- */

input.search {
  border:solid 1px #ccc;
  border-radius: 4px;
  padding:7px;
  margin-bottom:10px;
  font-size: 12px;
}
input.search:focus {
  outline:none;
  border-color:#aaa;
}

th.sort::-moz-selection { background:transparent; }
th.sort::selection      { background:transparent; }
th.sort { cursor:pointer; }
th.sort:after {
  content:'';
  display:inline-block;
  width: 0;
  height: 0;
  position: relative;
  top: -3px;
  right: -6px;
  border-width:0 4px 4px;
  border-style:solid;
  border-color:#404040 transparent;
  visibility:hidden;
}
 th.sort:hover:after { visibility:visible; }
 th.sort.desc:after,
 th.sort.asc:after,
 th.sort.asc:hover:after {
  visibility:visible;
  opacity:0.6;
}
 th.sort.desc:after {
  border-bottom:none;
  border-width:4px 4px 0;
}


================================================
FILE: bin/slather
================================================
#!/usr/bin/env ruby
require 'clamp'
require 'yaml'
require_relative '../lib/slather'
require_relative '../lib/slather/command/coverage_command'
require_relative '../lib/slather/command/setup_command'
require_relative '../lib/slather/command/version_command'

class MainCommand < Clamp::Command
  self.default_subcommand = "coverage"

  subcommand 'setup', 'Configures a .xcodeproj for test coverage generation', SetupCommand
  subcommand 'coverage', 'Computes coverage for the supplied project', CoverageCommand
  subcommand 'version', 'Prints slather version', VersionCommand
end

MainCommand.run


================================================
FILE: lib/cocoapods_plugin.rb
================================================
require_relative 'slather'

Pod::HooksManager.register('slather', :post_install) do |installer_context|
  sandbox_root = installer_context.sandbox_root
  sandbox = Pod::Sandbox.new(sandbox_root)
  project = Xcodeproj::Project.open(sandbox.project_path)
  project.slather_setup_for_coverage()
  project.save()
end



================================================
FILE: lib/slather/command/coverage_command.rb
================================================
class CoverageCommand < Clamp::Command

  parameter "[PROJECT]", "Path to the xcodeproj", :attribute_name => :xcodeproj_path

  option ["--travis", "-t"], :flag, "Indicate that the builds are running on Travis CI"
  option ["--travispro"], :flag, "Indicate that the builds are running on Travis Pro CI"
  option ["--circleci"], :flag, "Indicate that the builds are running on CircleCI"
  option ["--jenkins"], :flag, "Indicate that the builds are running on Jenkins"
  option ["--buildkite"], :flag, "Indicate that the builds are running on Buildkite"
  option ["--teamcity"], :flag, "Indicate that the builds are running on TeamCity"
  option ["--github"], :flag, "Indicate that the builds are running on Github Actions"

  option ["--coveralls", "-c"], :flag, "Post coverage results to coveralls"
  option ["--simple-output", "-s"], :flag, "Output coverage results to the terminal"
  option ["--gutter-json", "-g"], :flag, "Output coverage results as Gutter JSON format"
  option ["--cobertura-xml", "-x"], :flag, "Output coverage results as Cobertura XML format"
  option ["--sonarqube-xml", "-sq"], :flag, "Output coverage results as SonarQube XML format"
  option ["--llvm-cov", "-r"], :flag, "Output coverage as llvm-cov format"
  option ["--json"], :flag, "Output coverage results as simple JSON"
  option ["--html"], :flag, "Output coverage results as static html pages"
  option ["--show"], :flag, "Indicate that the static html pages will open automatically"
  option ["--cdn-assets"], :flag, "Indicate that the static html pages will load assets from a CDN"

  option ["--build-directory", "-b"], "BUILD_DIRECTORY", "The directory where gcno files will be written to. Defaults to derived data."
  option ["--source-directory"], "SOURCE_DIRECTORY", "The directory where your source files are located."
  option ["--output-directory"], "OUTPUT_DIRECTORY", "The directory where your Cobertura XML report will be written to."
  option ["--ignore", "-i"], "IGNORE", "ignore files conforming to a path", :multivalued => true
  option ["--verbose", "-v"], :flag, "Enable verbose mode"

  option ["--input-format"], "INPUT_FORMAT", "Input format (gcov, profdata)"
  option ["--scheme"], "SCHEME", "The scheme for which the coverage was generated"
  option ["--configuration"], "CONFIGURATION", "The configuration for test that the project was set"
  option ["--workspace"], "WORKSPACE", "The workspace that the project was built in"
  option ["--binary-file"], "BINARY_FILE", "The binary file against which the coverage will be run", :multivalued => true
  option ["--binary-basename"], "BINARY_BASENAME", "Basename of the file against which the coverage will be run", :multivalued => true
  option ["--arch"], "ARCH", "Architecture to use from universal binaries"
  option ["--source-files"], "SOURCE_FILES", "A Dir.glob compatible pattern used to limit the lookup to specific source files. Ignored in gcov mode.", :multivalued => true
  option ["--decimals"], "DECIMALS", "The amount of decimals to use for % coverage reporting"
  option ["--ymlfile"], "YMLFILE", "Relative path to a file used in place of '.slather.yml'"

  def execute
    puts "Slathering..."

    setup_ymlfile # MUST be the first setup
    setup_service_name
    setup_ignore_list
    setup_build_directory
    setup_source_directory
    setup_output_directory
    setup_coverage_service
    setup_verbose_mode
    setup_input_format
    setup_scheme
    setup_configuration
    setup_workspace
    setup_binary_file
    setup_binary_basename
    setup_arch
    setup_source_files
    setup_decimals

    project.configure

    post

    puts "Slathered"
  end

  def setup_ymlfile
    Slather::Project.yml_filename = ymlfile if ymlfile
  end

  def setup_build_directory
    project.build_directory = build_directory if build_directory
  end

  def setup_source_directory
    project.source_directory = source_directory if source_directory
  end

  def setup_output_directory
    project.output_directory = output_directory if output_directory
  end

  def setup_ignore_list
    project.ignore_list = ignore_list if !ignore_list.empty?
  end

  def setup_service_name
    if travis?
      project.ci_service = :travis_ci
    elsif travispro?
      project.ci_service = :travis_pro
    elsif circleci?
      project.ci_service = :circleci
    elsif jenkins?
      project.ci_service = :jenkins
    elsif buildkite?
      project.ci_service = :buildkite
    elsif teamcity?
      project.ci_service = :teamcity
    elsif github?
      project.ci_service = :github
    end
  end

  def post
    project.post
  end

  def project
    @project ||= begin
      xcodeproj_path_to_open = xcodeproj_path || Slather::Project.yml["xcodeproj"]
      if xcodeproj_path_to_open
        project = Slather::Project.open(xcodeproj_path_to_open)
      else
        raise StandardError, "Must provide an xcodeproj either via the 'slather [SUBCOMMAND] [PROJECT].xcodeproj' command or through .slather.yml"
      end
    end
  end

  def setup_coverage_service
    if coveralls?
      project.coverage_service = :coveralls
    elsif simple_output?
      project.coverage_service = :terminal
    elsif gutter_json?
      project.coverage_service = :gutter_json
    elsif cobertura_xml?
      project.coverage_service = :cobertura_xml
    elsif llvm_cov?
      project.coverage_service = :llvm_cov
    elsif html?
      project.coverage_service = :html
      project.show_html = show?
      project.cdn_assets = cdn_assets?
    elsif json?
      project.coverage_service = :json
    elsif sonarqube_xml?
      project.coverage_service = :sonarqube_xml
    end
  end

  def setup_verbose_mode
    project.verbose_mode = verbose?
  end

  def setup_input_format
    project.input_format = input_format
  end

  def setup_scheme
    project.scheme = scheme
  end

  def setup_configuration
    project.configuration = configuration
  end

  def setup_workspace
    project.workspace = workspace
  end

  def setup_binary_file
    project.binary_file = binary_file_list if !binary_file_list.empty?
  end

  def setup_binary_basename
    project.binary_basename = binary_basename_list if !binary_basename_list.empty?
  end

  def setup_arch
    project.arch = arch
  end

  def setup_source_files
    project.source_files = source_files_list if !source_files_list.empty?
  end

  def setup_decimals
    project.decimals = decimals if decimals
  end
end


================================================
FILE: lib/slather/command/setup_command.rb
================================================
class SetupCommand < Clamp::Command
  parameter "[PROJECT]", "Path to the .xcodeproj", :attribute_name => :xcodeproj_path

  option ["--format"], "FORMAT", "Type of coverage to use (gcov, clang, auto)"
  option ["--ymlfile"], "YMLFILE", "Relative path to a file used in place of '.slather.yml'"

  def execute
    setup_ymlfile
    xcodeproj_path_to_open = xcodeproj_path || Slather::Project.yml["xcodeproj"]
    unless xcodeproj_path_to_open
      raise StandardError, "Must provide a .xcodeproj either via the 'slather [SUBCOMMAND] [PROJECT].xcodeproj' command or through .slather.yml"
    end
    project = Slather::Project.open(xcodeproj_path_to_open)
    project.setup_for_coverage(format ? format.to_sym : :auto)
    project.save
  end

  def setup_ymlfile
    Slather::Project.yml_filename = ymlfile if ymlfile
  end
end


================================================
FILE: lib/slather/command/version_command.rb
================================================
class VersionCommand < Clamp::Command

  def execute
    puts "slather #{Slather::VERSION}"
  end
end


================================================
FILE: lib/slather/coverage_file.rb
================================================
require_relative 'coverage_info'
require_relative 'coveralls_coverage'

module Slather
  class CoverageFile

    include CoverageInfo
    include CoverallsCoverage

    attr_accessor :project, :gcno_file_pathname

    def initialize(project, gcno_file_pathname)
      self.project = project
      self.gcno_file_pathname = Pathname(gcno_file_pathname)
    end

    def source_file_pathname
      @source_file_pathname ||= begin
        base_filename = gcno_file_pathname.basename.sub_ext("")
        path = nil
        if project.source_directory
          path = Dir["#{project.source_directory}/**/#{base_filename}.{#{supported_file_extensions.join(",")}}"].first
          path &&= Pathname(path)
        else
          pbx_file = project.files.detect { |pbx_file|
            current_base_filename = pbx_file.real_path.basename
            ext_name = File.extname(current_base_filename.to_s)[1..-1]
            current_base_filename.sub_ext("") == base_filename && supported_file_extensions.include?(ext_name)
          }
          path = pbx_file && pbx_file.real_path
        end
        path
      end
    end

    def source_file
      File.new(source_file_pathname)
    end

    def source_data
      source_file.read
    end

    def gcov_data
      @gcov_data ||= begin
        gcov_data = ""

        Dir.chdir(project.project_dir) do
          gcov_output = `gcov "#{source_file_pathname}" --object-directory "#{gcno_file_pathname.parent}" --branch-probabilities --branch-counts`
          # Sometimes gcov makes gcov files for Cocoa Touch classes, like NSRange. Ignore and delete later.
          gcov_files_created = gcov_output.scan(/creating '(.+\..+\.gcov)'/)

          gcov_file_name = "./#{source_file_pathname.basename}.gcov"
          if File.exist?(gcov_file_name)
            gcov_data = File.new(gcov_file_name).read
          else
            gcov_data = ""
          end

          gcov_files_created.each { |file| FileUtils.rm_f(file) }
        end

        gcov_data
      end
    end

    def all_lines
      unless cleaned_gcov_data.empty?
        first_line_start = cleaned_gcov_data =~ /^\s+(-|#+|[0-9+]):\s+1:/
        cleaned_gcov_data[first_line_start..-1].split("\n").map
      else
        []
      end
    end

    def cleaned_gcov_data
      data = gcov_data.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/^function(.*) called [0-9]+ returned [0-9]+% blocks executed(.*)$\r?\n/, '')
      data.gsub(/^branch(.*)$\r?\n/, '')
    end

    def raw_data
      self.gcov_data
    end

    def line_coverage_data
      unless cleaned_gcov_data.empty?
        first_line_start = cleaned_gcov_data =~ /^\s+(-|#+|[0-9+]):\s+1:/

        cleaned_gcov_data[first_line_start..-1].split("\n").map do |line|
          coverage_for_line(line)
        end
      else
        []
      end
    end

    def line_number_in_line(line)
      line.split(':')[1].strip.to_i
    end

    def coverage_for_line(line)
      line =~ /^(.+?):/

      match = $1.strip
      case match
      when /[0-9]+/
        match.to_i
      when /#+/
        0
      when "-"
        nil
      end
    end

    def branch_coverage_data
      @branch_coverage_data ||= begin
        branch_coverage_data = Hash.new

        gcov_data.scan(/(^(\s+(-|#+|[0-9]+):\s+[1-9]+:(.*)$\r?\n)(^branch\s+[0-9]+\s+[a-zA-Z0-9]+\s+[a-zA-Z0-9]+$\r?\n)+)+/) do |data|
          lines = data[0].split("\n")
          line_number = lines[0].split(':')[1].strip.to_i
          branch_coverage_data[line_number] = lines[1..-1].map do |line|
            if line.split(' ')[2].strip == "never"
              0
            else
              line.split(' ')[3].strip.to_i
            end
          end
        end
        branch_coverage_data
      end
    end

    def source_file_basename
      File.basename(source_file_pathname, '.m')
    end

    def line_number_separator
      ":"
    end

    def supported_file_extensions
      ["cpp", "mm", "m"]
    end
    private :supported_file_extensions
  end
end


================================================
FILE: lib/slather/coverage_info.rb
================================================
module Slather
  module CoverageInfo

    def num_lines_tested
      line_coverage_data.compact.select { |cd| cd > 0 }.count
    end

    def num_lines_testable
      line_coverage_data.compact.count
    end

    def rate_lines_tested
      if num_lines_testable > 0
        (num_lines_tested / num_lines_testable.to_f)
      else
        0
      end
    end

    def percentage_lines_tested
      if num_lines_testable == 0
        100
      else
        rate_lines_tested * 100
      end
    end

    def branch_coverage_data_for_statement_on_line(line_number)
      branch_coverage_data[line_number] || []
    end

    def num_branches_for_statement_on_line(line_number)
      branch_coverage_data_for_statement_on_line(line_number).length
    end

    def num_branch_hits_for_statement_on_line(line_number)
      branch_coverage_data_for_statement_on_line(line_number).count { |hit_count| hit_count > 0 }
    end

    def rate_branch_coverage_for_statement_on_line(line_number)
      branch_data = branch_coverage_data_for_statement_on_line(line_number)
      if branch_data.empty?
        0.0
      else
        (num_branch_hits_for_statement_on_line(line_number) / branch_data.length.to_f)
      end
    end

    def percentage_branch_coverage_for_statement_on_line(line_number)
      rate_branch_coverage_for_statement_on_line(line_number) * 100
    end

    def num_branches_testable
      branch_coverage_data.keys.reduce(0) do |sum, line_number|
        sum += num_branches_for_statement_on_line(line_number)
      end
    end

    def num_branches_tested
      branch_coverage_data.keys.reduce(0) do |sum, line_number|
        sum += num_branch_hits_for_statement_on_line(line_number)
      end
    end

    def rate_branches_tested
      if (num_branches_testable > 0)
        (num_branches_tested / num_branches_testable.to_f)
      else
        0.0
      end
    end

    def source_file_pathname_relative_to_repo_root
      source_file_pathname.realpath.relative_path_from(Pathname("./").realpath)
    end

    def ignored?
      project.ignore_list.any? do |ignore|
        File.fnmatch(ignore, source_file_pathname_relative_to_repo_root)
      end
    end

    def include_file?
      rv = true # default true return value to fix https://github.com/SlatherOrg/slather/issues/561
      project.source_files.any? do |include|
        rv = File.fnmatch(include, source_file_pathname_relative_to_repo_root)
      end

      rv
    end

  end
end

================================================
FILE: lib/slather/coverage_service/cobertura_xml_output.rb
================================================
require 'nokogiri'
require 'date'

module Slather
  module CoverageService
    module CoberturaXmlOutput

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def post
        cobertura_xml_report = create_xml_report(coverage_files)
        store_report(cobertura_xml_report)
      end

      def store_report(report)
        output_file = 'cobertura.xml'
        if output_directory
          FileUtils.mkdir_p(output_directory)
          output_file = File.join(output_directory, output_file)
        end
        File.write(output_file, report.to_s)
      end

      def grouped_coverage_files(coverage_files)
        groups = Hash.new
        coverage_files.each do |coverage_file|
          next if coverage_file == nil
          path = File.dirname(coverage_file.source_file_pathname_relative_to_repo_root)
          if groups[path] == nil
            groups[path] = Array.new
          end
          groups[path].push(coverage_file)
        end
        groups
      end

      def create_xml_report(coverage_files)
        total_project_lines = 0
        total_project_lines_tested = 0
        total_project_line_rate = '%.16f' % 1.0
        total_project_branches = 0
        total_project_branches_tested = 0
        total_project_branch_rate = '%.16f' % 1.0

        create_empty_xml_report
        coverage_node = @doc.root
        source_node = @doc.at_css "source" 
        source_node.content = Pathname.pwd.to_s
        packages_node = @doc.at_css "packages"

        # group files by path
          grouped_coverage_files(coverage_files).each do |path , package_coverage_files|
          package_node = Nokogiri::XML::Node.new "package", @doc
          package_node.parent = packages_node
          classes_node = Nokogiri::XML::Node.new "classes", @doc
          classes_node.parent = package_node
          package_node['name'] = path.gsub(/\//, '.')

          total_package_lines = 0
          total_package_lines_tested = 0
          total_package_lines_rate = '%.16f' % 1.0
          total_package_branches = 0
          total_package_branches_tested = 0
          total_package_branch_rate = '%.16f' % 1.0

          package_coverage_files.each do |package_coverage_file|
            class_node = create_class_node(package_coverage_file)
            class_node.parent = classes_node
            total_package_lines += package_coverage_file.num_lines_testable
            total_package_lines_tested += package_coverage_file.num_lines_tested
            total_package_branches += package_coverage_file.num_branches_testable
            total_package_branches_tested += package_coverage_file.num_branches_tested
          end

          if (total_package_lines > 0)
            total_package_line_rate = '%.16f' % (total_package_lines_tested / total_package_lines.to_f)
          end

          if (total_package_branches > 0)
            total_package_branch_rate = '%.16f' % (total_package_branches_tested / total_package_branches.to_f)
          end

          package_node['line-rate'] = total_package_line_rate
          package_node['branch-rate'] = total_package_branch_rate
          package_node['complexity'] = '0.0'

          total_project_lines += total_package_lines
          total_project_lines_tested += total_package_lines_tested
          total_project_branches += total_package_branches
          total_project_branches_tested += total_package_branches_tested
        end

        if (total_project_lines > 0)
          total_project_line_rate = '%.16f' % (total_project_lines_tested / total_project_lines.to_f)
        end

        if (total_project_branches > 0)
          total_project_branch_rate = '%.16f' % (total_project_branches_tested / total_project_branches.to_f)
        end

        coverage_node['line-rate'] = total_project_line_rate
        coverage_node['branch-rate'] = total_project_branch_rate
        coverage_node['lines-covered'] = total_project_lines_tested
        coverage_node['lines-valid'] = total_project_lines
        coverage_node['branches-covered'] = total_project_branches_tested
        coverage_node['branches-valid'] = total_project_branches
        coverage_node['complexity'] = "0.0"
        coverage_node['timestamp'] = DateTime.now.strftime('%s')
        coverage_node['version'] = "Slather #{Slather::VERSION}"
        @doc.to_xml
      end

      def create_class_node(coverage_file)
        filename = coverage_file.source_file_basename
        filepath = coverage_file.source_file_pathname_relative_to_repo_root.to_s

        class_node = Nokogiri::XML::Node.new "class", @doc
        class_node['name'] = filename
        class_node['filename'] = filepath
        class_node['line-rate'] = '%.16f' %  [(coverage_file.num_lines_testable > 0) ? coverage_file.rate_lines_tested : 1.0]
        class_node['branch-rate'] = '%.16f' % [(coverage_file.num_branches_testable > 0) ? coverage_file.rate_branches_tested : 1.0]
        class_node['complexity'] = '0.0'

        methods_node = Nokogiri::XML::Node.new "methods", @doc
        methods_node.parent = class_node
        lines_node = Nokogiri::XML::Node.new "lines", @doc
        lines_node.parent = class_node
        
        coverage_file.all_lines.each do |line|
          if coverage_file.coverage_for_line(line)
            line_node = create_line_node(line, coverage_file)
            line_node.parent = lines_node
          end
        end
        class_node
      end

      def create_line_node(line, coverage_file)
        line_number = coverage_file.line_number_in_line(line)
        line_node = Nokogiri::XML::Node.new "line", @doc
        line_node['number'] = line_number
        line_node['branch'] = "false"
        line_node['hits'] = coverage_file.coverage_for_line(line)
      
        unless coverage_file.branch_coverage_data_for_statement_on_line(line_number).empty?
          line_node['branch'] = "true"  
          conditions_node = Nokogiri::XML::Node.new "conditions", @doc
          conditions_node.parent = line_node
          condition_node = Nokogiri::XML::Node.new "condition", @doc
          condition_node.parent = conditions_node
          condition_node['number'] = "0"
          condition_node['type'] = "jump"
          branches_testable = coverage_file.num_branches_for_statement_on_line(line_number)
          branch_hits = coverage_file.num_branch_hits_for_statement_on_line(line_number)
          condition_coverage = coverage_file.percentage_branch_coverage_for_statement_on_line(line_number)
          condition_node['coverage'] = "#{condition_coverage.to_i}%"
          line_node['condition-coverage'] = "#{condition_coverage.to_i}% (#{branch_hits}/#{branches_testable})"
        end
        line_node
      end

      def create_empty_xml_report
        builder = Nokogiri::XML::Builder.new do |xml|
          xml.doc.create_internal_subset(
            'coverage',
            nil,
            "https://raw.githubusercontent.com/cobertura/cobertura/master/cobertura/src/site/htdocs/xml/coverage-04.dtd"
          )
          xml.coverage do
            xml.sources do
              xml.source
            end
            xml.packages
          end
        end
        @doc = builder.doc
      end

    end
  end
end


================================================
FILE: lib/slather/coverage_service/coveralls.rb
================================================
module Slather
  module CoverageService
    module Coveralls

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def travis_job_id
        ENV['TRAVIS_JOB_ID']
      end
      private :travis_job_id

      def circleci_job_id
        ENV['CIRCLE_BUILD_NUM']
      end
      private :circleci_job_id

      def circleci_pull_request
        ENV['CIRCLE_PR_NUMBER'] || ENV['CI_PULL_REQUEST'] || ""
      end
      private :circleci_pull_request

      def teamcity_job_id
        ENV['TC_BUILD_NUMBER']
      end
      private :teamcity_job_id

      def jenkins_job_id
        ENV['BUILD_ID']
      end
      private :jenkins_job_id

      def github_job_id
        ENV['GITHUB_RUN_ID']
      end
      private :github_job_id

      def bitrise_job_id
        ENV['BITRISE_BUILD_NUMBER']
      end
      private :bitrise_job_id

      def bitrise_pull_request
        ENV['BITRISE_PULL_REQUEST']
      end
      private :bitrise_pull_request

      def github_pull_request
        ENV['CI_PULL_REQUEST'] || ""
      end
      private :github_pull_request

      def github_repo_name
        ENV['GITHUB_REPOSITORY'] || ""
      end
      private :github_repo_name

      def jenkins_branch_name
        branch_name = ENV['GIT_BRANCH'] || ENV['BRANCH_NAME']
        if branch_name.include? 'origin/'
          branch_name[7...branch_name.length]
        else
          branch_name
        end
      end
      private :jenkins_branch_name

      def teamcity_branch_name
        ENV['GIT_BRANCH'] || `git ls-remote --heads origin | grep $(git rev-parse HEAD) | cut -d / -f 3-`.chomp
      end
      private :teamcity_branch_name

      def github_branch_name
        ENV['GIT_BRANCH'] || `git ls-remote --heads origin | grep $(git rev-parse HEAD) | cut -d / -f 3-`.chomp
      end
      private :github_branch_name

      def bitrise_branch_name
        ENV['BITRISE_GIT_BRANCH'] || `git ls-remote --heads origin | grep $(git rev-parse HEAD) | cut -d / -f 3-`.chomp
      end
      private :bitrise_branch_name

      def buildkite_job_id
        ENV['BUILDKITE_BUILD_NUMBER']
      end
      private :buildkite_job_id

      def buildkite_pull_request
        ENV['BUILDKITE_PULL_REQUEST']
      end
      private :buildkite_pull_request

      def jenkins_git_info
        {
          head: {
            id: ENV['sha1'],
            author_name: ENV['ghprbActualCommitAuthor'],
            message: ENV['ghprbPullTitle']
          },
          branch: jenkins_branch_name
        }
      end
      private :jenkins_git_info

      def teamcity_git_info
        {
          head: {
            :id => (`git log --format=%H -n 1 HEAD`.chomp || ""),
            :author_name => (`git log --format=%an -n 1 HEAD`.chomp || ""),
            :author_email => (`git log --format=%ae -n 1 HEAD`.chomp || ""),
            :message => (`git log --format=%s -n 1 HEAD`.chomp || "")
          },
          :branch => teamcity_branch_name
        }
      end
      private :teamcity_git_info

      def circleci_build_url
        "https://circleci.com/gh/" + ENV['CIRCLE_PROJECT_USERNAME'] || "" + "/" + ENV['CIRCLE_PROJECT_REPONAME'] || "" + "/" + ENV['CIRCLE_BUILD_NUM'] || ""
      end
      private :circleci_build_url

      def circleci_git_info
        {
          :head => {
            :id => (ENV['CIRCLE_SHA1'] || ""),
            :author_name => (ENV['CIRCLE_PR_USERNAME'] || ENV['CIRCLE_USERNAME'] || ""),
            :message => (`git log --format=%s -n 1 HEAD`.chomp || "")
          },
          :branch => (ENV['CIRCLE_BRANCH'] || "")
        }
      end
      private :circleci_git_info

      def buildkite_git_info
        {
          :head => {
            :id => ENV['BUILDKITE_COMMIT'],
            :author_name => (`git log --format=%an -n 1 HEAD`.chomp || ""),
            :author_email => (`git log --format=%ae -n 1 HEAD`.chomp || ""),
            :message => (`git log --format=%s -n 1 HEAD`.chomp || "")
          },
          :branch => ENV['BUILDKITE_BRANCH']
        }
      end

      def buildkite_build_url
        "https://buildkite.com/" + ENV['BUILDKITE_PROJECT_SLUG'] + "/builds/" + ENV['BUILDKITE_BUILD_NUMBER'] + "#"
      end

      def github_git_info
        {
          :head => {
            :id => ENV['GITHUB_SHA'],
            :author_name => ENV['GITHUB_ACTOR'],
            :message => (`git log --format=%s -n 1 HEAD`.chomp || "")
          },
          :branch => github_branch_name
        }
      end
      private :github_git_info

      def bitrise_git_info
        {
          :head => {
            :id => ENV['BITRISE_GIT_COMMIT'],
            :committer_name => (ENV['GIT_CLONE_COMMIT_AUTHOR_NAME'] || `git log --format=%an -n 1 HEAD`.chomp || ""),
            :committer_email => (ENV['GIT_CLONE_COMMIT_AUTHOR_EMAIL'] || `git log --format=%ae -n 1 HEAD`.chomp || ""),
            :message => (ENV['BITRISE_GIT_MESSAGE'] || `git log --format=%s -n 1 HEAD`.chomp || "")
          },
          :branch => bitrise_branch_name
        }
      end
      private :bitrise_git_info

      def github_build_url
        "https://github.com/" + ENV['GITHUB_REPOSITORY'] + "/actions/runs/" + ENV['GITHUB_RUN_ID']
      end
      private :github_build_url

      def is_parallel
        ENV['IS_PARALLEL'] != nil
      end
      private :is_parallel

      def github_job_name
        ENV['GITHUB_JOB']
      end
      private :github_job_name

      def coveralls_coverage_data
        if ci_service == :travis_ci || ci_service == :travis_pro
          if travis_job_id
            if ci_service == :travis_ci

              if coverage_access_token.to_s.strip.length > 0
                raise StandardError, "Access token is set. Uploading coverage data for public repositories doesn't require an access token."
              end

              {
                :service_job_id => travis_job_id,
                :service_name => "travis-ci",
                :source_files => coverage_files.map(&:as_json)
              }.to_json
            elsif ci_service == :travis_pro

              if coverage_access_token.to_s.strip.length == 0
                raise StandardError, "Access token is not set. Uploading coverage data for private repositories requires an access token."
              end

              {
                :service_job_id => travis_job_id,
                :service_name => "travis-pro",
                :repo_token => coverage_access_token,
                :source_files => coverage_files.map(&:as_json)
              }.to_json
            end
          else
            raise StandardError, "Environment variable `TRAVIS_JOB_ID` not set. Is this running on a travis build?"
          end
        elsif ci_service == :circleci
          if circleci_job_id
            coveralls_hash = {
              :service_job_id => circleci_job_id,
              :service_name => "circleci",
              :repo_token => coverage_access_token,
              :source_files => coverage_files.map(&:as_json),
              :git => circleci_git_info,
              :service_build_url => circleci_build_url
            }

            if circleci_pull_request != nil && circleci_pull_request.length > 0
              coveralls_hash[:service_pull_request] = circleci_pull_request.split("/").last
            end

            coveralls_hash.to_json
          else
            raise StandardError, "Environment variable `CIRCLE_BUILD_NUM` not set. Is this running on a circleci build?"
          end
        elsif ci_service == :jenkins
          if jenkins_job_id
            {
              service_job_id: jenkins_job_id,
              service_name: "jenkins",
              repo_token: coverage_access_token,
              source_files: coverage_files.map(&:as_json),
              git: jenkins_git_info
            }.to_json
          else
            raise StandardError, "Environment variable `BUILD_ID` not set. Is this running on a jenkins build?"
          end
        elsif ci_service == :buildkite
          if buildkite_job_id
            {
              :service_job_id => buildkite_job_id,
              :service_name => "buildkite",
              :repo_token => coverage_access_token,
              :source_files => coverage_files.map(&:as_json),
              :git => buildkite_git_info,
              :service_build_url => buildkite_build_url,
              :service_pull_request => buildkite_pull_request
            }.to_json
          else
            raise StandardError, "Environment variable `BUILDKITE_BUILD_NUMBER` not set. Is this running on a buildkite build?"
          end
        elsif ci_service == :teamcity
          if teamcity_job_id
            {
              :service_job_id => teamcity_job_id,
              :service_name => "teamcity",
              :repo_token => coverage_access_token,
              :source_files => coverage_files.map(&:as_json),
              :git => teamcity_git_info
            }.to_json
          else
            raise StandardError, "Environment variable `TC_BUILD_NUMBER` not set. Is this running on a teamcity build?"
          end
        elsif ci_service == :github

          if coverage_access_token.to_s.strip.length == 0
            raise StandardError, "Access token is not set. Uploading coverage data for private repositories requires an access token."
          end

          if github_job_id
            {
              :service_job_id => github_job_id,
              :service_name => "github",
              :repo_token => coverage_access_token,
              :repo_name => github_repo_name,
              :source_files => coverage_files.map(&:as_json),
              :service_build_url => github_build_url,
              :service_pull_request => github_pull_request,
              :git => github_git_info,
              :parallel => is_parallel,
              :flag_name => github_job_name
            }.to_json
          else
            raise StandardError, "Environment variable `GITHUB_RUN_ID` not set.  Is this running on github build?"
          end
        elsif ci_service == :bitrise
          {
            :service_job_id => bitrise_job_id,
            :service_name => 'bitrise',
            :repo_token => coverage_access_token,
            :source_files => coverage_files.map(&:as_json),
            :service_pull_request => bitrise_pull_request,
            :service_branch => bitrise_branch_name,
            :git => bitrise_git_info
          }.to_json
        else
          {
            :service_job_id => ENV['CI_BUILD_NUMBER'],
            :service_name => ENV['CI_NAME'] || ci_service,
            :repo_token => coverage_access_token,
            :source_files => coverage_files.map(&:as_json),
            :service_build_url => ENV['CI_BUILD_URL'],
            :service_pull_request => ENV['CI_PULL_REQUEST'],
            :service_branch => ENV['CI_BRANCH'],
            :git => {
              :head => {
                :id => ENV['CI_COMMIT'],
                :committer_name => (`git log --format=%an -n 1 HEAD`.chomp || ""),
                :committer_email => (`git log --format=%ae -n 1 HEAD`.chomp || ""),
                :message => (`git log --format=%s -n 1 HEAD`.chomp || "")
              },
              :branch => ENV['CI_BRANCH']
            }
          }.to_json
        end
      end
      private :coveralls_coverage_data

      def post
        f = File.open('coveralls_json_file', 'w+')
        begin
          f.write(coveralls_coverage_data)
          f.close

          curl_result = `curl -s --form json_file=@#{f.path} #{coveralls_api_jobs_path}`

          if curl_result.is_a? String
            curl_result_json = JSON.parse(curl_result)

            if curl_result_json["error"]
              error_message = curl_result_json["message"]
              raise StandardError, "Error while uploading coverage data to Coveralls. CI Service: #{ci_service} Message: #{error_message}"
            end
          end

        rescue StandardError => e
          FileUtils.rm(f)
          raise e
        end
        FileUtils.rm(f)
      end

      def coveralls_api_jobs_path
        "https://coveralls.io/api/v1/jobs"
      end
      private :coveralls_api_jobs_path

    end
  end
end


================================================
FILE: lib/slather/coverage_service/gutter_json_output.rb
================================================
module Slather
  module CoverageService
    module GutterJsonOutput

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def post
        output = { 'meta' => { 'timestamp' => DateTime.now.strftime('%Y-%m-%d %H:%M:%S.%6N') } }
        symbols = {}

        coverage_files.each do |coverage_file|
          next unless coverage_file.raw_data

          filename = coverage_file.source_file_pathname.to_s
          filename = filename.sub(Pathname.pwd.to_s, '').reverse.chomp("/").reverse

          coverage_file.all_lines.each do |line|

            line_number = coverage_file.line_number_in_line(line)
            next unless line_number > 0

            coverage = coverage_file.coverage_for_line(line)
            short_text = coverage != nil ? coverage.to_s : "-"

            symbol = {  'line' => line_number,
                        'long_text' => '',
                        'short_text' => short_text }

            if coverage != nil
              symbol['background_color'] = coverage.to_i > 0 ? '0x35CC4B' : '0xFC635E'
            end

            if symbols.has_key?(filename)
              symbols[filename] << symbol
            else
              symbols[filename] = [ symbol ]
            end
          end
        end

        output['symbols_by_file'] = symbols
        File.open('.gutter.json', 'w') { |file| file.write(output.to_json) }
      end

    end
  end
end


================================================
FILE: lib/slather/coverage_service/hardcover.rb
================================================
module Slather
  module CoverageService
    module Hardcover

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def jenkins_job_id
        "#{ENV['JOB_NAME']}/#{ENV['BUILD_NUMBER']}"
      end
      private :jenkins_job_id

      def hardcover_coverage_data
        if ci_service == :jenkins_ci
          if jenkins_job_id
            {
              :service_job_id => jenkins_job_id,
              :service_name => "jenkins-ci",
              :repo_token => Project.yml["hardcover_repo_token"],
              :source_files => coverage_files.map(&:as_json)
            }.to_json
          else
            raise StandardError, "Environment variables `BUILD_NUMBER` and `JOB_NAME` are not set. Is this running on a Jenkins build?"
          end
        else
          raise StandardError, "No support for ci named #{ci_service}"
        end
      end
      private :hardcover_coverage_data

      def post
        f = File.open('hardcover_json_file', 'w+')
        begin
          f.write(hardcover_coverage_data)
          f.close
          `curl --form json_file=@#{f.path} #{hardcover_api_jobs_path}`
        rescue StandardError => e
          FileUtils.rm(f)
          raise e
        end
        FileUtils.rm(f)
      end

      def hardcover_api_jobs_path
        "#{hardcover_base_url}/v1/jobs"
      end
      private :hardcover_api_jobs_path

      def hardcover_base_url
        url = Project.yml["hardcover_base_url"]
        unless url
          raise "No `hardcover_base_url` configured. Please add it to your `.slather.yml`"
        end
        url
      end
      private :hardcover_base_url
    end
  end
end


================================================
FILE: lib/slather/coverage_service/html_output.rb
================================================
require 'nokogiri'
require "cgi"

module Slather
  module CoverageService
    module HtmlOutput

      attr_reader :docs

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def directory_path
        is_path_valid = !output_directory.nil? && !output_directory.strip.eql?("")
        is_path_valid ? File.expand_path(output_directory) : "html"
      end
      private :directory_path

      def post
        create_html_reports(coverage_files)
        generate_reports(@docs)

        index_html_path = File.join(directory_path, "index.html")
        if show_html
          open_coverage index_html_path
        else
          print_path_coverage index_html_path
        end
      end

      def print_path_coverage(index_html)
        path = File.expand_path index_html
        puts "\nTo open the html reports, use \n\nopen '#{path}'\n\nor use '--show' flag to open it automatically.\n\n"
      end

      def open_coverage(index_html)
        path = File.expand_path index_html
        `open '#{path}'` if File.exist?(path)
      end

      def create_html_reports(coverage_files)
        create_index_html(coverage_files)
        create_htmls_from_files(coverage_files)
      end

      def generate_reports(reports)
        FileUtils.rm_rf(directory_path) if Dir.exist?(directory_path)
        FileUtils.mkdir_p(directory_path)

        FileUtils.cp(File.join(gem_root_path, "docs/logo.jpg"), directory_path)
        FileUtils.cp(File.join(gem_root_path, "assets/slather.css"), directory_path)
        FileUtils.cp(File.join(gem_root_path, "assets/highlight.pack.js"), directory_path)
        FileUtils.cp(File.join(gem_root_path, "assets/list.min.js"), directory_path)

        reports.each do |name, doc|
          html_file = File.join(directory_path, "#{name}.html")
          File.write(html_file, doc.to_html)
        end
      end

      def create_index_html(coverage_files)
        project_name = File.basename(self.xcodeproj)
        template = generate_html_template(project_name, true, false)

        total_relevant_lines = 0
        total_tested_lines = 0
        total_relevant_branches = 0
        total_branches_tested = 0
        coverage_files.each { |coverage_file|
          total_tested_lines += coverage_file.num_lines_tested
          total_relevant_lines += coverage_file.num_lines_testable

          total_relevant_branches += coverage_file.num_branches_testable
          total_branches_tested += coverage_file.num_branches_tested
        }

        builder = Nokogiri::HTML::Builder.with(template.at('#reports')) { |cov|
          cov.h2 "Files for \"#{project_name}\""

          cov.h4 {
            percentage = (total_tested_lines / total_relevant_lines.to_f) * 100.0
            cov.span "Total Coverage : "
            cov.span decimal_f(percentage) + '%', :class => class_for_coverage_percentage(percentage), :id => "total_coverage"
            cov.span " ("
            cov.span total_tested_lines, :id => "total_tested_lines"
            cov.span " of "
            cov.span total_relevant_lines, :id => "total_relevant_lines"
            cov.span " lines)"
          }

          cov.h4 {
            percentage = (total_branches_tested / total_relevant_branches.to_f) * 100.0
            cov.span "Total Branch Coverage : "
            cov.span decimal_f(percentage) + '%', :class => class_for_coverage_percentage(percentage), :id => "total_coverage"
            cov.span " ("
            cov.span total_branches_tested, :id => "total_branches_tested"
            cov.span " of "
            cov.span total_relevant_branches, :id => "total_relevant_branches"
            cov.span " lines)"
          }

          cov.input(:class => "search", :placeholder => "Search")

          cov.table(:class => "coverage_list", :cellspacing => 0,  :cellpadding => 0) {

            cov.thead {
              cov.tr {
                cov.th "%", :class => "col_num sort", "data-sort" => "data_percentage"
                cov.th "File", :class => "sort", "data-sort" => "data_filename"
                cov.th "Lines", :class => "col_percent sort", "data-sort" => "data_lines"
                cov.th "Relevant", :class => "col_percent sort", "data-sort" => "data_relevant"
                cov.th "Covered", :class => "col_percent sort", "data-sort" => "data_covered"
                cov.th "Missed", :class => "col_percent sort", "data-sort" => "data_missed"
              }
            }

            cov.tbody(:class => "list") {
              coverage_files.each { |coverage_file|
                filename = File.basename(coverage_file.source_file_pathname_relative_to_repo_root)
                filename_link = CGI.escape(filename) + ".html"

                cov.tr {
                  percentage = coverage_file.percentage_lines_tested

                  cov.td { cov.span decimal_f(percentage), :class => "percentage #{class_for_coverage_percentage(percentage)} data_percentage" }
                  cov.td(:class => "data_filename") {
                    cov.a filename, :href => filename_link
                  }
                  cov.td "#{coverage_file.line_coverage_data.count}", :class => "data_lines"
                  cov.td "#{coverage_file.num_lines_testable}", :class => "data_relevant"
                  cov.td "#{coverage_file.num_lines_tested}", :class => "data_covered"
                  cov.td "#{(coverage_file.num_lines_testable - coverage_file.num_lines_tested)}", :class => "data_missed"
                }
              }
            }
          }
        }

        @docs = Hash.new
        @docs[:index] = builder.doc
      end

      def create_htmls_from_files(coverage_files)
        coverage_files.map { |file| create_html_from_file file }
      end

      def create_html_from_file(coverage_file)
        filepath = coverage_file.source_file_pathname_relative_to_repo_root
        filename = File.basename(filepath)
        percentage = coverage_file.percentage_lines_tested
        branch_percentage = coverage_file.rate_branches_tested * 100

        cleaned_gcov_lines = coverage_file.cleaned_gcov_data.split("\n")
        is_file_empty = (cleaned_gcov_lines.count <= 0)

        template = generate_html_template(filename, false, is_file_empty)

        builder = Nokogiri::HTML::Builder.with(template.at('#reports')) { |cov|
          cov.h2(:class => "cov_title") {
            cov.span("Coverage for \"#{filename}\"" + (!is_file_empty ? " : " : ""))
            cov.span("Lines: ") unless is_file_empty
            cov.span("#{decimal_f(percentage)}%", :class => class_for_coverage_percentage(percentage)) unless is_file_empty
            cov.span(" Branches: ") unless is_file_empty
            cov.span("#{decimal_f(branch_percentage)}%", :class => class_for_coverage_percentage(branch_percentage)) unless is_file_empty
          }

          cov.h4("(#{coverage_file.num_lines_tested} of #{coverage_file.num_lines_testable} relevant lines covered)", :class => "cov_subtitle")
          cov.h4(filepath, :class => "cov_filepath")

          if is_file_empty
            cov.p "¯\\_(ツ)_/¯"
            next
          end

          line_number_separator = coverage_file.line_number_separator

          cov.table(:class => "source_code") {
            cleaned_gcov_lines.each do |line|
              line_number = coverage_file.line_number_in_line(line)
              missed_regions = coverage_file.branch_region_data[line_number]
              hits = coverage_file.coverage_for_line(line)
              next unless line_number > 0

              line_source = line.split(line_number_separator, 3)[2]
              line_data = [line_number, line_source, hits_for_coverage_line(coverage_file, line)]
              classes = ["num", "src", "coverage"]

              cov.tr(:class => class_for_coverage_line(coverage_file,line)) {
                line_data.each_with_index { |line, idx|
                  if idx != 1
                    cov.td(line, :class => classes[idx])
                  else
                    cov.td(:class => classes[idx]) {
                      cov.pre {
                        # If the line has coverage and missed regions, split up
                        # the line to show regions that weren't covered
                        if missed_regions != nil && hits != nil && hits > 0
                          regions = missed_regions.map do |region|
                            region_start, region_length = region
                            if region_length != nil
                              line[region_start, region_length]
                            else
                              line[region_start, line.length - region_start]
                            end
                          end
                          current_line = line
                          regions.each do |region|
                            covered, remainder = current_line.split(region, 2)
                            cov.code(covered, :class => "objc")
                            cov.code(region, :class => "objc missed")
                            current_line = remainder
                          end
                          cov.code(current_line, :class => "objc")
                        else
                          cov.code(line, :class => "objc")
                        end
                      }
                    }
                  end
                }
              }
            end
          }
        }

        @docs[filename] = builder.doc
      end

      def generate_html_template(title, is_index, is_file_empty)
        if cdn_assets
          logo_path = "https://cdn.jsdelivr.net/gh/SlatherOrg/slather/docs/logo.jpg"
          css_path = "https://cdn.jsdelivr.net/gh/SlatherOrg/slather/assets/slather.css"
          highlight_js_path = "https://cdn.jsdelivr.net/gh/SlatherOrg/slather/assets/highlight.pack.js"
          list_js_path = "https://cdn.jsdelivr.net/gh/SlatherOrg/slather/assets/list.min.js"
        else
          logo_path = "logo.jpg"
          css_path = "slather.css"
          highlight_js_path = "highlight.pack.js"
          list_js_path = "list.min.js"
        end

        builder = Nokogiri::HTML::Builder.new do |doc|
          doc.html {
            doc.head {
              doc.title "#{title} - Slather"
              doc.link :href => css_path, :media => "all", :rel => "stylesheet"
            }
            doc.body {
              doc.header {
                doc.div(:class => "row") {
                  doc.a(:href => "index.html") { doc.img(:src => logo_path, :alt => "Slather logo") }
                }
              }
              doc.div(:class => "row") { doc.div(:id => "reports") }
              doc.footer {
                doc.div(:class => "row") {
                  doc.p { doc.a("Fork me on Github", :href => "https://github.com/SlatherOrg/slather") }
                  doc.p("© #{Date.today.year} Slather")
                }
              }

              if is_index
                doc.script :src => list_js_path
                doc.script "var reports = new List('reports', { valueNames: [ 'data_percentage', 'data_filename', 'data_lines', 'data_relevant', 'data_covered', 'data_missed' ]});"
              else
                unless is_file_empty
                  doc.script :src => highlight_js_path
                  doc.script "hljs.initHighlightingOnLoad();"
                end
              end
            }
          }
        end
        builder.doc
      end

      def gem_root_path
        File.expand_path File.join(File.dirname(__dir__), "../..")
      end

      def class_for_coverage_line(coverage_file, coverage_line)
        hits = coverage_file.coverage_for_line(coverage_line)
        case
        when hits == nil then "never"
        when hits > 0 then "covered"
        else "missed"
        end
      end

      def hits_for_coverage_line(coverage_file, coverage_line)
        hits = coverage_file.coverage_for_line(coverage_line)
        case
        when hits == nil then ""
        when hits > 0 then "#{hits}x"
        else "!"
        end
      end

      def class_for_coverage_percentage(percentage)
        case
        when percentage > 85 then "cov_high"
        when percentage > 70 then "cov_medium"
        else "cov_low"
        end
      end

    end
  end
end


================================================
FILE: lib/slather/coverage_service/json_output.rb
================================================
require 'nokogiri'
require 'date'

module Slather
  module CoverageService
    module JsonOutput

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def post
        report = coverage_files.map do |file|
          {
            file: file.source_file_pathname_relative_to_repo_root,
            coverage: file.line_coverage_data
          }
        end.to_json

        store_report(report)
      end

      def store_report(report)
        output_file = 'report.json'
        if output_directory
          FileUtils.mkdir_p(output_directory)
          output_file = File.join(output_directory, output_file)
        end
        File.write(output_file, report.to_s)
      end
    end
  end
end


================================================
FILE: lib/slather/coverage_service/llvm_cov_output.rb
================================================
require 'nokogiri'
require 'date'

module Slather
  module CoverageService
    module LlvmCovOutput

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          raise StandardError, "Only profdata input format supported by llvm-cov show."
        end
      end
      private :coverage_file_class

      def post
        report = coverage_files.map do |file|
          ["#{file.source_file_pathname.realpath}:", file.source_data, ""]
        end.flatten.join("\n")

        store_report(report)
      end

      def store_report(report)
        output_file = 'report.llcov'
        if output_directory
          FileUtils.mkdir_p(output_directory)
          output_file = File.join(output_directory, output_file)
        end
        File.write(output_file, report.to_s)
      end
    end
  end
end


================================================
FILE: lib/slather/coverage_service/simple_output.rb
================================================
module Slather
  module CoverageService
    module SimpleOutput

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def post
        total_project_lines = 0
        total_project_lines_tested = 0
        coverage_files.each do |coverage_file|
          # ignore lines that don't count towards coverage (comments, whitespace, etc). These are nil in the array.

          lines_tested = coverage_file.num_lines_tested
          total_lines = coverage_file.num_lines_testable
          percentage = decimal_f([coverage_file.percentage_lines_tested])

          total_project_lines_tested += lines_tested
          total_project_lines += total_lines

          puts "#{coverage_file.source_file_pathname_relative_to_repo_root}: #{lines_tested} of #{total_lines} lines (#{percentage}%)"
        end

        # check if there needs to be custom reporting based on the ci service
        if ci_service == :teamcity
          # TeamCity Build Statistic Reporting
          #
          # Reporting format ##teamcity[buildStatisticValue key='<valueTypeKey>' value='<value>']
          # key='CodeCoverageAbsLCovered' is total number of lines covered
          # key='CodeCoverageAbsLTotal' is total number of lines
          #
          # Sources:
          # - https://confluence.jetbrains.com/display/TCDL/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingBuildStatistics
          # - https://confluence.jetbrains.com/display/TCDL/Custom+Chart#CustomChart-listOfDefaultStatisticValues
          puts "##teamcity[buildStatisticValue key='CodeCoverageAbsLCovered' value='%i']" % total_project_lines_tested
          puts "##teamcity[buildStatisticValue key='CodeCoverageAbsLTotal' value='%i']" % total_project_lines
        end

        total_percentage = decimal_f([(total_project_lines_tested / total_project_lines.to_f) * 100.0])
        puts "Tested #{total_project_lines_tested}/#{total_project_lines} statements"
        puts "Test Coverage: #{total_percentage}%"
      end

    end
  end
end


================================================
FILE: lib/slather/coverage_service/sonarqube_xml_output.rb
================================================
require 'nokogiri'
require 'date'

module Slather
  module CoverageService
    module SonarqubeXmlOutput

      def coverage_file_class
        if input_format == "profdata"
          Slather::ProfdataCoverageFile
        else
          Slather::CoverageFile
        end
      end
      private :coverage_file_class

      def post
        cobertura_xml_report = create_xml_report(coverage_files)
        store_report(cobertura_xml_report)
      end

      def store_report(report)
        output_file = 'sonarqube-generic-coverage.xml'
        if output_directory
          FileUtils.mkdir_p(output_directory)
          output_file = File.join(output_directory, output_file)
        end
        File.write(output_file, report.to_s)
      end

      def create_xml_report(coverage_files)
        create_empty_xml_report
        coverage_node = @doc.root
        coverage_node['version'] = "1"

        coverage_files.each do |coverage_file|
          file_node = Nokogiri::XML::Node.new "file", @doc
          file_node.parent = coverage_node
          file_node['path'] = coverage_file.source_file_pathname_relative_to_repo_root.to_s
          coverage_file.all_lines.each do |line|
            if coverage_file.coverage_for_line(line)
              line_node = Nokogiri::XML::Node.new "lineToCover", @doc
              line_node['lineNumber'] = coverage_file.line_number_in_line(line)
              line_node['covered'] = coverage_file.coverage_for_line(line) == 0 ? "false" : "true"
              line_node.parent = file_node
            end
          end
        end
        @doc.to_xml
      end

      def create_empty_xml_report
        builder = Nokogiri::XML::Builder.new do |xml|
          xml.coverage
        end
        @doc = builder.doc
      end

    end
  end
end


================================================
FILE: lib/slather/coveralls_coverage.rb
================================================
module Slather
  module CoverallsCoverage

    def as_json
      {
        :name => source_file_pathname_relative_to_repo_root.to_s,
        :source => source_data,
        :coverage => line_coverage_data
      }
    end

  end
end


================================================
FILE: lib/slather/profdata_coverage_file.rb
================================================
require_relative 'coverage_info'
require_relative 'coveralls_coverage'
require 'digest/md5'

module Slather
  class ProfdataCoverageFile

    include CoverageInfo
    include CoverallsCoverage

    attr_accessor :project, :source, :segments, :line_numbers_first, :line_data

    def initialize(project, source, line_numbers_first)
      self.project = project
      self.source = source
      self.line_numbers_first = line_numbers_first
      create_line_data
    end

    def create_line_data
      line_data = Hash.new
      all_lines.each { |line| line_data[line_number_in_line(line, self.line_numbers_first)] = line }
      self.line_data = line_data
    end
    private :create_line_data

    def path_on_first_line?
      !source.lstrip.start_with?("1|")
    end

    def source_file_pathname
      @source_file_pathname ||= begin
        if path_on_first_line?
          end_index = self.source.index(/:?\n/)
          if end_index != nil
            end_index -= 1
            path = self.source[0..end_index]
          else
            # Empty file, output just contains path
            path = self.source.sub ":", ""
          end
          path &&= Pathname(path)
        else
          # llvm-cov was run with just one matching source file
          # It doesn't print the source path in this case, so we have to find it ourselves
          # This is slow because we read every source file and compare it, but this should only happen if there aren't many source files
          digest = Digest::MD5.digest(self.raw_source)
          path = nil

          project.find_source_files.each do |file|
            file_digest = Digest::MD5.digest(File.read(file).strip)

            if digest == file_digest
              path = file
            end
          end

          path
        end
      end
    end

    def source_file_pathname= (source_file_pathname)
        @source_file_pathname = source_file_pathname
    end

    def source_file
      File.new(source_file_pathname)
    end

    def source_code_lines
      lines = self.source.split("\n")[(path_on_first_line? ? 1 : 0)..-1]
      ignore_error_lines(lines)
    end

    def ignore_error_lines(lines, line_numbers_first = self.line_numbers_first)
      if line_numbers_first
        lines.reject { |line| line.lstrip.start_with?('|', '--') }
      else
        lines
      end
    end

    def source_data
      all_lines.join("\n")
    end

    def all_lines
      @all_lines ||= source_code_lines
    end

    def raw_source
      self.source.lines.map do |line|
        line.split('|').last
      end.join
    end

    def cleaned_gcov_data
      source_data
    end

    def raw_data
      self.source
    end

    def line_number_in_line(line, line_numbers_first = self.line_numbers_first)
      if line_numbers_first
        # Skip regex if the number is the first thing in the line
        fastpath_number = line.to_i
        return fastpath_number if fastpath_number != 0
        line =~ /^(\s*)(\d*)/
        group = $2
      else
        line =~ /^(\s*)(\d*)\|(\s*)(\d+)\|/
        group = $4
      end

      if group != nil
        match = group.strip
        case match
          when /[0-9]+/
            return match.to_i
        end
      else
        # llvm-cov outputs hit counts as 25.3k or 3.8M, so check this pattern as well
        did_match = line =~ /^(\s*)(\d+\.\d+)(k|M)\|(\s*)(\d+)\|/

        if did_match
          match = $5.strip
          case match
            when /[0-9]+/
              return match.to_i
          end
        end
      end
      0
    end

    def line_coverage_data
      all_lines.map do |line|
        coverage_for_line(line, self.line_numbers_first)
      end
    end

    def coverage_for_line(line, line_numbers_first = self.line_numbers_first)
      line = line.gsub(":", "|")

      if line_numbers_first
        line =~ /^(\s*)(\d*)\|(\s*)(\d+)\|/
        group = $4
      else
        line =~ /^(\s*)(\d*)\|/
        group = $2
      end

      if group == nil
        # Check for thousands or millions (llvm-cov outputs hit counts as 25.3k or 3.8M)
        if line_numbers_first
          did_match = line =~ /^(\s*)(\d+)\|(\s*)(\d+\.\d+)(k|M)\|/
          group = $4
          units_group = $5
        else
          did_match = line =~ /^(\s*)(\d+\.\d+)(k|M)\|/
          group = $2
          units_group = $3
        end

        if did_match
          count = group.strip
          units = units_group == 'k' ? 1000 : 1000000

          (count.to_f * units).to_i
        else
          return nil
        end
      else
        match = group.strip
        case match
        when /[0-9]+/
          match.to_i
        when /#+/
          0
        when "-"
          nil
        end
      end
    end

    def branch_coverage_data
      @branch_coverage_data ||= begin
        branch_coverage_data = Hash.new

        self.segments.each do |segment|
          line, col, hits, has_count, *rest = segment
          next if !has_count
          if branch_coverage_data.key?(line)
            branch_coverage_data[line] = branch_coverage_data[line] + [hits]
          else
            branch_coverage_data[line] = [hits]
          end
        end

        branch_coverage_data
      end
    end

    def branch_region_data
      @branch_region_data ||= begin
        branch_region_data = Hash.new
        region_start = nil
        current_line = 0
        @segments ||= []
        @segments.each do |segment|
          line, col, hits, has_count, *rest = segment
          # Make column 0 based index
          col = col - 1
          if hits == 0 && has_count
            current_line = line
            region_start = col
          elsif region_start != nil && hits > 0 && has_count
            # if the region wrapped to a new line before ending, put nil to indicate it didnt end on this line
            region_end = line == current_line ? col - region_start : nil
            if branch_region_data.key?(current_line)
              branch_region_data[current_line] << [region_start, region_end]
            else
              branch_region_data[current_line] = [[region_start, region_end]]
            end
            region_start = nil
          end
        end
        branch_region_data
      end
    end

    def source_file_basename
      File.basename(source_file_pathname, '.swift')
    end

    def line_number_separator
      "|"
    end

    def supported_file_extensions
      ["swift"]
    end
    private :supported_file_extensions

    def ignored?
      path = source_file_pathname.to_s

      # This indicates a llvm-cov coverage warning (occurs if a passed in source file
      # is not covered or with cache in some cases).
      return true if path.end_with?("isn't covered.")
      # Ignore source files inside of platform SDKs
      return true if path.include?("/Xcode.*\.app\/Contents\/Developer\/Platforms")

      super
    end
  end
end


================================================
FILE: lib/slather/project.rb
================================================
require 'fileutils'
require 'xcodeproj'
require 'json'
require 'yaml'
require 'shellwords'

module Xcodeproj

  class Project

    def slather_setup_for_coverage(format = :auto)
      unless [:gcov, :clang, :auto].include?(format)
        raise StandardError, "Only supported formats for setup are gcov, clang or auto"
      end
      if format == :auto
        format = Slather.xcode_version[0] < 7 ? :gcov : :clang
      end

      build_configurations.each do |build_configuration|
        if format == :clang
          build_configuration.build_settings["CLANG_ENABLE_CODE_COVERAGE"] = "YES"
        else
          build_configuration.build_settings["GCC_INSTRUMENT_PROGRAM_FLOW_ARCS"] = "YES"
          build_configuration.build_settings["GCC_GENERATE_TEST_COVERAGE_FILES"] = "YES"
        end
      end

      # Patch xcschemes too
      if format == :clang
        schemes_path = Xcodeproj::XCScheme.shared_data_dir(self.path)
        Xcodeproj::Project.schemes(self.path).each do |scheme_name|
          xcscheme_path = "#{schemes_path + scheme_name}.xcscheme"
          xcscheme = Xcodeproj::XCScheme.new(xcscheme_path)
          xcscheme.test_action.xml_element.attributes['codeCoverageEnabled'] = 'YES'
          xcscheme.save_as(self.path, scheme_name)
        end
      end
    end

  end
end

module Slather
  class Project < Xcodeproj::Project

    attr_accessor :build_directory, :ignore_list, :ci_service, :coverage_service, :coverage_access_token, :source_directory,
      :output_directory, :xcodeproj, :show_html, :cdn_assets, :verbose_mode, :input_format, :scheme, :workspace, :binary_file, :binary_basename, :arch, :source_files,
      :decimals, :llvm_version, :configuration

    alias_method :setup_for_coverage, :slather_setup_for_coverage

    def self.open(xcodeproj)
      proj = super
      proj.xcodeproj = xcodeproj
      proj
    end

    def failure_help_string
      "\n\tAre you sure your project is generating coverage? Make sure you enable code coverage in the Test section of your Xcode scheme.\n\tDid you specify your Xcode scheme? (--scheme or 'scheme' in .slather.yml)\n\tIf you're using a workspace, did you specify it? (--workspace or 'workspace' in .slather.yml)\n\tIf you use a different Xcode configuration, did you specify it? (--configuration or 'configuration' in .slather.yml)"
    end

    def derived_data_path
      # Get the derived data path from xcodebuild
      # Use OBJROOT when possible, as it provides regardless of whether or not the Derived Data location is customized
      if self.workspace
        projectOrWorkspaceArgument = "-workspace \"#{self.workspace}\""
      else
        projectOrWorkspaceArgument = "-project \"#{self.path}\""
      end

      if self.scheme
        schemeArgument = "-scheme \"#{self.scheme}\""
        buildAction = "test"
      else
        schemeArgument = nil
        buildAction = nil
      end

      # redirect stderr to avoid xcodebuild errors being printed.
      build_settings = `xcodebuild #{projectOrWorkspaceArgument} #{schemeArgument} -showBuildSettings #{buildAction} CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO 2>&1`

      if build_settings
        derived_data_path = build_settings.match(/ OBJROOT = (.+)/)
        # when match fails derived_data_path is nil
        derived_data_path = derived_data_path[1] if derived_data_path
      end

      if derived_data_path == nil
        derived_data_path = File.expand_path('~') + "/Library/Developer/Xcode/DerivedData/"
      end

      derived_data_path
    end
    private :derived_data_path

    def coverage_files
      if self.input_format == "profdata"
        profdata_coverage_files
      else
        gcov_coverage_files
      end
    end

    def gcov_coverage_files
      coverage_files = Dir["#{build_directory}/**/*.gcno"].map do |file|
        coverage_file = coverage_file_class.new(self, file)
        # If there's no source file for this gcno, it probably belongs to another project.
        coverage_file.source_file_pathname && !coverage_file.ignored? ? coverage_file : nil
      end.compact

      if coverage_files.empty?
        raise StandardError, "No coverage files found."
      else
        dedupe(coverage_files)
      end
    end
    private :gcov_coverage_files

    def profdata_coverage_files
      coverage_files = []

      if self.binary_file
        self.binary_file.each do |binary_path|
          pathnames_per_binary = pathnames_per_binary(binary_path)
          coverage_files.concat(create_coverage_files_for_binary(binary_path, pathnames_per_binary))
        end
      end

      if coverage_files.empty?
        raise StandardError, "No coverage files found."
      else
        dedupe(coverage_files)
      end
    end
    private :profdata_coverage_files

    def pathnames_per_binary(binary_path)
      coverage_json_string = llvm_cov_export_output(binary_path)
      if coverage_json_string.strip != ""
        # JSON.parse will crash on an empty string, so just skip everything if the string is empty.
        coverage_json = JSON.parse(coverage_json_string)
        coverage_json["data"].reduce([]) do |result, chunk|
          result.concat(chunk["files"].map do |file|
            filename = file["filename"]
            path = Pathname(filename)
            # Don't crash if the file doesn't exist on disk.
            # This may happen for autogenerated files that have been deleted.
            filename = path.exist? ? path.realpath : filename
            {"filename" => filename, "segments" => file["segments"]}
          end)
        end
      end
    end
    private :pathnames_per_binary

    def create_coverage_files_for_binary(binary_path, pathnames_per_binary)
      return [] unless pathnames_per_binary != nil

      coverage_files = []

      begin
        coverage_files.concat(create_coverage_files(binary_path, pathnames_per_binary))
      rescue Errno::E2BIG => e
        # pathnames_per_binary is too big for the OS to handle so it's split in two halfs which are processed independently
        if pathnames_per_binary.count > 1
          left, right = pathnames_per_binary.each_slice( (pathnames_per_binary.size/2.0).round ).to_a
          coverage_files.concat(create_coverage_files_for_binary(binary_path, left))
          coverage_files.concat(create_coverage_files_for_binary(binary_path, right))
        else
          # pathnames_per_binary contains one element which is too big for the OS to handle. 
          raise e, "#{e}. A path in your project is close to the E2BIG limit. https://github.com/SlatherOrg/slather/pull/414", e.backtrace
        end
      end

      coverage_files
    end
    private :create_coverage_files_for_binary

    def create_coverage_files(binary_path, path_objects)
      line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
      # get just file names from the path objects
      pathnames = path_objects.map { |path_obj| path_obj["filename"] }.compact
      # Map of path name => segment array
      paths_to_segments = path_objects.reduce(Hash.new) do |hash, path_obj|
        hash[path_obj["filename"]] = path_obj["segments"]
        hash
      end
      files = create_profdata(binary_path, pathnames)
      files.map do |source|
        coverage_file = coverage_file_class.new(self, source, line_numbers_first)
        # If a single source file is used, the resulting output does not contain the file name.
        coverage_file.source_file_pathname = pathnames.first if pathnames.count == 1
        # if there is segment data for the given path, add it to the coverage_file
        if paths_to_segments.key?(coverage_file.source_file_pathname)
          coverage_file.segments = paths_to_segments[coverage_file.source_file_pathname]
        end
        coverage_file.source_file_pathname && !coverage_file.ignored? && coverage_file.include_file? ? coverage_file : nil
      end.compact
    end
    private :create_coverage_files

    def create_profdata(binary_path, pathnames)
      profdata_llvm_cov_output(binary_path, pathnames).split("\n\n")
    end
    private :create_profdata

    def remove_extension(path)
      path.split(".")[0..-2].join(".")
    end

    def first_product_name
      first_product = self.products.first
      # If name is not available it computes it using
      # the path by dropping the 'extension' of the path.
      first_product.name || remove_extension(first_product.path)
    end

    def profdata_coverage_dir
      @profdata_coverage_dir ||= begin
        raise StandardError, "The specified build directory (#{self.build_directory}) does not exist" unless File.exist?(self.build_directory)
        dir = nil
        if self.scheme
          dir = Dir[File.join(build_directory,"/**/CodeCoverage/#{self.scheme}")].first
        else
          dir = Dir[File.join(build_directory,"/**/#{first_product_name}")].first
        end

        if dir == nil
          # Xcode 7.3 moved the location of Coverage.profdata
          dir = Dir[File.join(build_directory,"/**/CodeCoverage")].first
        end

        if dir == nil && Slather.xcode_version[0] >= 9
          # Xcode 9 moved the location of Coverage.profdata
          coverage_files = Dir[File.join(build_directory, "/**/ProfileData/*/Coverage.profdata")]

          if coverage_files.count == 0
            # Look up one directory
            # The ProfileData directory is next to Intermediates.noindex (in previous versions of Xcode the coverage was inside Intermediates)
            coverage_files = Dir[File.join(build_directory, "../**/ProfileData/*/Coverage.profdata")]
          end

          if coverage_files != nil && coverage_files.count != 0
            dir = Pathname.new(coverage_files.first).parent()
          end
        end

        raise StandardError, "No coverage directory found." unless dir != nil
        dir
      end
    end

    def profdata_file
      profdata_coverage_dir = self.profdata_coverage_dir
      if profdata_coverage_dir == nil
        raise StandardError, "No coverage directory found. Please make sure the \"Code Coverage\" checkbox is enabled in your scheme's Test action or the build_directory property is set."
      end

      file =  Dir["#{profdata_coverage_dir}/**/Coverage.profdata"].first
      unless file != nil
        return nil
      end
      return File.expand_path(file)
    end
    private :profdata_file

    def unsafe_llvm_cov_export_output(binary_path)
      profdata_file_arg = profdata_file
      if profdata_file_arg == nil
        raise StandardError, "No Coverage.profdata files found. Please make sure the \"Code Coverage\" checkbox is enabled in your scheme's Test action or the build_directory property is set."
      end

      if binary_path == nil
        raise StandardError, "No binary file found."
      end

      llvm_cov_args = %W(export -instr-profile #{profdata_file_arg} #{binary_path})
      if self.arch
        llvm_cov_args << "--arch" << self.arch
      end
      `xcrun llvm-cov #{llvm_cov_args.shelljoin}`
    end
    private :unsafe_llvm_cov_export_output

    def llvm_cov_export_output(binary_path)
      output = unsafe_llvm_cov_export_output(binary_path)
      output.valid_encoding? ? output : output.encode!('UTF-8', 'binary', :invalid => :replace, undef: :replace)
    end
    private :llvm_cov_export_output

    def unsafe_profdata_llvm_cov_output(binary_path, source_files)
      profdata_file_arg = profdata_file
      if profdata_file_arg == nil
        raise StandardError, "No Coverage.profdata files found. Please make sure the \"Code Coverage\" checkbox is enabled in your scheme's Test action or the build_directory property is set."
      end

      if binary_path == nil
        raise StandardError, "No binary file found."
      end

      llvm_cov_args = %W(show -instr-profile #{profdata_file_arg} #{binary_path})
      if self.arch
        llvm_cov_args << "--arch" << self.arch
      end

      # POSIX systems have an ARG_MAX for the maximum total length of the command line, so the command may fail with an error message of "Argument list too long".
      # Using the xargs command we can break the list of source_files into sublists small enough to be acceptable.
      `printf '%s\\0' #{source_files.shelljoin} | xargs -0 xcrun llvm-cov #{llvm_cov_args.shelljoin}`
    end
    private :unsafe_profdata_llvm_cov_output

    def profdata_llvm_cov_output(binary_path, source_files)
      output = unsafe_profdata_llvm_cov_output(binary_path, source_files)
      output.valid_encoding? ? output : output.encode!('UTF-8', 'binary', :invalid => :replace, undef: :replace)
    end
    private :profdata_llvm_cov_output

    def dedupe(coverage_files)
      coverage_files.group_by(&:source_file_pathname).values.map { |cf_array| cf_array.max_by(&:percentage_lines_tested) }
    end
    private :dedupe

    @@ymlfile = '.slather.yml'

    def self.yml_filename=(var)
      @@ymlfile = var
    end

    def self.yml_filename
      @@ymlfile
    end

    def self.yml
      @yml ||= File.exist?(yml_filename) ? YAML.load_file(yml_filename) : {}
    end

    def configure
      begin
        configure_scheme
        configure_configuration
        configure_workspace
        configure_build_directory
        configure_ignore_list
        configure_ci_service
        configure_coverage_access_token
        configure_coverage_service
        configure_source_directory
        configure_output_directory
        configure_input_format
        configure_arch
        configure_binary_file
        configure_decimals
        configure_source_files

        self.llvm_version = `xcrun llvm-cov --version`.match(/LLVM version ([\d\.]+)/).captures[0]
      rescue => e
        puts e.message
        puts failure_help_string
        puts "\n"
        raise
      end

      if self.verbose_mode
        puts "\nProcessing coverage file: #{profdata_file}"
        if self.binary_file
          puts "Against binary files:"
          self.binary_file.each do |binary_file|
            puts "\t#{binary_file}"
          end
        else
          puts "No binary files found."
        end
        puts "\n"
      end
    end

    def configure_build_directory
      self.build_directory ||= self.class.yml["build_directory"] || derived_data_path
    end

    def configure_source_directory
      self.source_directory ||= self.class.yml["source_directory"] if self.class.yml["source_directory"]
    end

    def configure_output_directory
      self.output_directory ||= self.class.yml["output_directory"] if self.class.yml["output_directory"]
    end

    def configure_ignore_list
      self.ignore_list ||= [(self.class.yml["ignore"] || [])].flatten
    end

    def configure_source_files
      self.source_files ||= [(self.class.yml["source_files"] || [])].flatten
    end

    def configure_ci_service
      self.ci_service ||= (ENV["CI_SERVICE"] || self.class.yml["ci_service"] || :other)
    end

    def configure_input_format
      self.input_format ||= (self.class.yml["input_format"] || "auto")
    end

    def input_format=(format)
      format ||= "auto"
      unless %w(gcov profdata auto).include?(format)
        raise StandardError, "Only supported input formats are gcov, profdata or auto"
      end
      if format == "auto"
        @input_format = Slather.xcode_version[0] < 7 ? "gcov" : "profdata"
      else
        @input_format = format
      end
    end

    def configure_scheme
      self.scheme ||= self.class.yml["scheme"] if self.class.yml["scheme"]
    end

    def configure_configuration
      self.configuration ||= self.class.yml["configuration"] if self.class.yml["configuration"]
    end

    def configure_decimals
      return if self.decimals
      self.decimals ||= self.class.yml["decimals"] if self.class.yml["decimals"]
      self.decimals = self.decimals ? Integer(self.decimals) : 2
    end

    def configure_workspace
      self.workspace ||= self.class.yml["workspace"] if self.class.yml["workspace"]
    end

    def ci_service=(service)
      @ci_service = service && service.to_sym
    end

    def configure_coverage_service
      self.coverage_service ||= (self.class.yml["coverage_service"] || :terminal)
    end

    def configure_coverage_access_token
      self.coverage_access_token ||= (ENV["COVERAGE_ACCESS_TOKEN"] || self.class.yml["coverage_access_token"] || "")
    end

    def coverage_service=(service)
      service = service && service.to_sym
      case service
      when :coveralls
        extend(Slather::CoverageService::Coveralls)
      when :hardcover
        extend(Slather::CoverageService::Hardcover)
      when :terminal
        extend(Slather::CoverageService::SimpleOutput)
      when :gutter_json
        extend(Slather::CoverageService::GutterJsonOutput)
      when :cobertura_xml
        extend(Slather::CoverageService::CoberturaXmlOutput)
      when :llvm_cov
        extend(Slather::CoverageService::LlvmCovOutput)
      when :html
        extend(Slather::CoverageService::HtmlOutput)
      when :json
        extend(Slather::CoverageService::JsonOutput)
      when :sonarqube_xml
        extend(Slather::CoverageService::SonarqubeXmlOutput)
      else
        raise ArgumentError, "`#{coverage_service}` is not a valid coverage service. Try `terminal`, `coveralls`, `gutter_json`, `cobertura_xml` or `html`"
      end
      @coverage_service = service
    end

    def configure_binary_file
      if self.input_format == "profdata"
        self.binary_file = load_option_array("binary_file") || find_binary_files
      end
    end

    def configure_arch
      self.arch ||= self.class.yml["arch"] if self.class.yml["arch"]
    end

    def decimal_f decimal_arg
      configure_decimals unless decimals
      decimal = "%.#{decimals}f" % decimal_arg
      return decimal if decimals == 2 # special case 2 for backwards compatibility
      decimal.to_f.to_s
    end

    def find_binary_file_in_bundle(bundle_file)
      if File.directory? bundle_file
        bundle_file_noext = File.basename(bundle_file, File.extname(bundle_file))

        # Search for .debug.dylib binaries
        # See https://developer.apple.com/documentation/xcode/build-settings-reference#Enable-Debug-Dylib-Support for details
        debug_dylib_matches = Dir["#{bundle_file}/**/#{bundle_file_noext}.debug.dylib"]

        if debug_dylib_matches.length() > 0
          debug_dylib_matches.first
        else
          Dir["#{bundle_file}/**/#{bundle_file_noext}"].first
        end
      else
        bundle_file
      end
    end

    def find_binary_files
      binary_basename = load_option_array("binary_basename")
      found_binaries = []

      # Get scheme info out of the xcodeproj
      if self.scheme
        schemes_path = Xcodeproj::XCScheme.shared_data_dir(self.path)
        xcscheme_path = "#{schemes_path + self.scheme}.xcscheme"

        # Try to look inside 'xcuserdata' if the scheme is not found in 'xcshareddata'
        if !File.file?(xcscheme_path)
          schemes_path = Xcodeproj::XCScheme.user_data_dir(self.path)
          xcscheme_path = "#{schemes_path + self.scheme}.xcscheme"
        end

        if self.workspace and !File.file?(xcscheme_path)
          # No scheme was found in the xcodeproj, check the workspace
          schemes_path = Xcodeproj::XCScheme.shared_data_dir(self.workspace)
          xcscheme_path = "#{schemes_path + self.scheme}.xcscheme"

          if !File.file?(xcscheme_path)
            schemes_path = Xcodeproj::XCScheme.user_data_dir(self.workspace)
            xcscheme_path = "#{schemes_path + self.scheme}.xcscheme"
          end
        end

        raise StandardError, "No scheme named '#{self.scheme}' found in #{self.path}" unless File.exist? xcscheme_path

        xcscheme = Xcodeproj::XCScheme.new(xcscheme_path)

        if self.configuration
          configuration = self.configuration
        else
          configuration = xcscheme.test_action.build_configuration
        end

        search_list = binary_basename || find_buildable_names(xcscheme)
        search_dir = profdata_coverage_dir

        if Slather.xcode_version[0] >= 9
          # Go from the directory containing Coverage.profdata back to the directory containing Products (back out of ProfileData/UUID-dir)
          search_dir = File.join(search_dir, '../..')
        end

        search_list.each do |search_for|
          found_product = Dir["#{search_dir}/Products/#{configuration}*/#{search_for}*"].sort { |x, y|
            # Sort the matches without the file extension to ensure better matches when there are multiple candidates
            # For example, if the binary_basename is Test then we want Test.app to be matched before Test Helper.app
            File.basename(x, File.extname(x)) <=> File.basename(y, File.extname(y))
          }.find { |path|
            next if path.end_with? ".dSYM"
            next if path.end_with? ".swiftmodule"

            if File.directory? path
              path = find_binary_file_in_bundle(path)
              next if path.nil?
            end

            matches_arch(path)
          }

          if found_product and File.directory? found_product
            found_binary = find_binary_file_in_bundle(found_product)
          else
            found_binary = found_product
          end

          if found_binary
            found_binaries.push(found_binary)
          end
        end
      else
        xctest_bundle = Dir["#{profdata_coverage_dir}/**/*.xctest"].reject { |bundle|
            # Ignore xctest bundles that are in the UI runner app
            bundle.include? "-Runner.app/PlugIns/"
        }.first

        # Find the matching binary file
        search_list = binary_basename || ['*']

        search_list.each do |search_for|
          xctest_bundle_file_directory = Pathname.new(xctest_bundle).dirname
          app_bundle = Dir["#{xctest_bundle_file_directory}/#{search_for}.app"].first
          matched_xctest_bundle = Dir["#{xctest_bundle_file_directory}/#{search_for}.xctest"].first
          dynamic_lib_bundle = Dir["#{xctest_bundle_file_directory}/#{search_for}.{framework,dylib}"].first

          if app_bundle != nil
            found_binary = find_binary_file_in_bundle(app_bundle)
          elsif matched_xctest_bundle != nil
            found_binary = find_binary_file_in_bundle(matched_xctest_bundle)
          elsif dynamic_lib_bundle != nil
            found_binary = find_binary_file_in_bundle(dynamic_lib_bundle)
          else
            found_binary = find_binary_file_in_bundle(xctest_bundle)
          end

          if found_binary
            found_binaries.push(found_binary)
          end
        end
      end

      raise StandardError, "No product binary found in #{profdata_coverage_dir}." unless found_binaries.count > 0

      found_binaries.map { |binary| File.expand_path(binary) }
    end

    def find_buildable_names(xcscheme)
      found_buildable_names = []

      # enumerate code coverage targets
      begin
        code_coverage_targets = xcscheme.test_action.xml_element.elements['CodeCoverageTargets']
        targets = code_coverage_targets.map do |node|
          Xcodeproj::XCScheme::BuildableReference.new(node) if node.is_a?(REXML::Element)
        end.compact
        buildable_names = targets.each do |target|
          found_buildable_names.push(target.buildable_name)
        end
      rescue
        # just in case if there are no entries in the test action
      end

      # enumerate build action entries
      begin
        xcscheme.build_action.entries.each do |entry|
          buildable_name = entry.buildable_references[0].buildable_name

          if !buildable_name.end_with? ".a"
            # Can't run code coverage on static libraries
            found_buildable_names.push(buildable_name)
          end
        end
      rescue
        # xcodeproj will raise an exception if there are no entries in the build action
      end

      # enumerate test action entries
      begin
        xcscheme.test_action.testables.each do |entry|
          buildable_name = entry.buildable_references[0].buildable_name
          found_buildable_names.push(buildable_name)
        end
      rescue
        # just in case if there are no entries in the test action
      end

      # some items are both buildable and testable, so return only unique ones
      found_buildable_names.uniq
    end

    def matches_arch(binary_path)
      if self.arch
        lipo_output = `lipo -info "#{binary_path}"`
        archs_in_binary = lipo_output.split(':').last.split(' ')
        archs_in_binary.include? self.arch
      else
        true
      end
    end

    def find_source_files
      source_files = load_option_array("source_files")
      return [] if source_files.nil?

      current_dir = Pathname("./").realpath
      paths = source_files.flat_map { |pattern| Dir.glob(pattern) }.uniq

      paths.map do |path|
        source_file_absolute_path = Pathname(path).realpath
        source_file_relative_path = source_file_absolute_path.relative_path_from(current_dir)
        self.ignore_list.any? { |ignore| File.fnmatch(ignore, source_file_relative_path) } ? nil : source_file_absolute_path
      end.compact
    end

    def load_option_array(option)
      value = self.send(option.to_sym)
      # Only load if a value is not already set
      if !value
        value_yml = self.class.yml[option]
        # Need to check the type in the config file because it can be a string or array
        if value_yml and value_yml.is_a? Array
          value = value_yml
        elsif value_yml
          value = [value_yml]
        end
      end
      value
    end
  end
end


================================================
FILE: lib/slather/version.rb
================================================
module Slather
  VERSION = '2.8.5' unless defined?(Slather::VERSION)
end


================================================
FILE: lib/slather.rb
================================================
require_relative 'slather/version'
require_relative 'slather/project'
require_relative 'slather/coverage_info'
require_relative 'slather/coverage_file'
require_relative 'slather/coveralls_coverage'
require_relative 'slather/profdata_coverage_file'
require_relative 'slather/coverage_service/cobertura_xml_output'
require_relative 'slather/coverage_service/coveralls'
require_relative 'slather/coverage_service/hardcover'
require_relative 'slather/coverage_service/gutter_json_output'
require_relative 'slather/coverage_service/simple_output'
require_relative 'slather/coverage_service/html_output'
require_relative 'slather/coverage_service/json_output'
require_relative 'slather/coverage_service/llvm_cov_output'
require_relative 'slather/coverage_service/sonarqube_xml_output'
require 'cfpropertylist'

module Slather

  Encoding.default_external = "utf-8"

  def self.prepare_pods(pods)
    Pod::UI.warn("[Slather] prepare_pods is now deprecated. The call to prepare_pods in your Podfile can simply be ommitted.")
  end

  def self.xcode_version
    xcode_path = `xcode-select -p`.strip
    plist = CFPropertyList::List.new(:file => File.join(xcode_path, '..', 'Info.plist'))
    xcode_version = CFPropertyList.native_types(plist.value)["CFBundleShortVersionString"]
    xcode_version.split('.').map(&:to_i)
  end

end


================================================
FILE: slather.gemspec
================================================
# encoding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'slather/version'

Gem::Specification.new do |spec|
  spec.name          = 'slather'
  spec.version       = Slather::VERSION
  spec.authors       = ['Mark Larsen']
  spec.email         = ['mark@venmo.com']
  spec.summary       = %q{Test coverage reports for Xcode projects}
  spec.homepage      = 'https://github.com/SlatherOrg/slather'
  spec.license       = 'MIT'

  spec.files         = `git ls-files -z`.force_encoding('utf-8').split("\x0")
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ['lib']

  spec.add_development_dependency 'bundler', '~> 2.0'
  spec.add_development_dependency 'coveralls', '~> 0.8'
  spec.add_development_dependency 'simplecov', '~> 0'
  spec.add_development_dependency 'rake', '~> 12.3'
  spec.add_development_dependency 'rspec', '~> 3.8'
  spec.add_development_dependency 'pry', '~> 0.12'
  spec.add_development_dependency 'cocoapods', '~> 1.10.beta.1'
  spec.add_development_dependency 'json_spec', '~> 1.1'
  spec.add_development_dependency 'equivalent-xml', '~> 0.6'

  spec.add_dependency 'clamp', '~> 1.3'
  spec.add_dependency 'xcodeproj', '~> 1.27'
  spec.add_dependency 'nokogiri', '>= 1.14.3'
  spec.add_dependency 'CFPropertyList', '>= 2.2', '< 4'

  spec.add_runtime_dependency 'activesupport'
end


================================================
FILE: spec/fixtures/FixtureFramework/FixtureFramework.h
================================================
//
//  FixtureFramework.h
//  FixtureFramework
//
//  Created by Stephen Williams on 11/03/21.
//  Copyright © 2021 marklarr. All rights reserved.
//

#import <Foundation/Foundation.h>

//! Project version number for FixtureFramework.
FOUNDATION_EXPORT double FixtureFrameworkVersionNumber;

//! Project version string for FixtureFramework.
FOUNDATION_EXPORT const unsigned char FixtureFrameworkVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <FixtureFramework/PublicHeader.h>




================================================
FILE: spec/fixtures/FixtureFramework/FlashExperiment.swift
================================================
import Foundation

public struct FlashExperiment {
    public let isAwesome = true
    
    public init() {}
}


================================================
FILE: spec/fixtures/FixtureFramework/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>$(CURRENT_PROJECT_VERSION)</string>
	<key>NSHumanReadableCopyright</key>
	<string>Copyright © 2021 marklarr. All rights reserved.</string>
</dict>
</plist>


================================================
FILE: spec/fixtures/FixtureFrameworkTests/FixtureFrameworkTests.swift
================================================
//
//  FixtureFrameworkTests.swift
//  FixtureFrameworkTests
//
//  Created by Stephen Williams on 11/03/21.
//  Copyright © 2021 marklarr. All rights reserved.
//

import XCTest
@testable import FixtureFramework

class FixtureFrameworkTests: XCTestCase {

    override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
    }

    func testExample() throws {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

    func testPerformanceExample() throws {
        // This is an example of a performance test case.
        self.measure {
            // Put the code you want to measure the time of here.
        }
    }

}


================================================
FILE: spec/fixtures/FixtureFrameworkTests/FlashExperimentTests.swift
================================================
import XCTest
import FixtureFramework

class FlashExperimentTests: XCTestCase {
    func testExample() throws {
        let sut = FlashExperiment()
        XCTAssertTrue(sut.isAwesome, "Your flash experiment isn't awesome!")
    }
}


================================================
FILE: spec/fixtures/FixtureFrameworkTests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
</dict>
</plist>


================================================
FILE: spec/fixtures/fixtures/Fixtures.swift
================================================

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
    }
}

================================================
FILE: spec/fixtures/fixtures/Supporting Files/fixtures-Prefix.pch
================================================
//
//  Prefix header
//
//  The contents of this file are implicitly included at the beginning of every source file.
//

#ifdef __OBJC__
    #import <Cocoa/Cocoa.h>
#endif


================================================
FILE: spec/fixtures/fixtures/fixtures.h
================================================
//
//  fixtures.h
//  fixtures
//
//  Created by Mark Larsen on 6/24/14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface fixtures : NSObject

- (void)testedMethod;
- (void)untestedMethod;

@end


================================================
FILE: spec/fixtures/fixtures/fixtures.m
================================================
//
//  fixtures.m
//  fixtures
//
//  Created by Mark Larsen on 6/24/14.
//  Copyright (c) 2014 marklarr 🌟. All rights reserved.
//

#import "fixtures.h"

@implementation fixtures

- (void)testedMethod
{
    NSLog(@"tested");
}

- (void)untestedMethod
{
    NSLog(@"untested");
}

@end


================================================
FILE: spec/fixtures/fixtures/fixtures_cpp.cpp
================================================
//
//  fixtures_cpp.cpp
//  fixtures
//
//  Created by Larsen, Mark on 4/3/15.
//  Copyright (c) 2015 marklarr. All rights reserved.
//

#include "fixtures_cpp.h"


================================================
FILE: spec/fixtures/fixtures/fixtures_cpp.h
================================================
#ifndef __fixtures__fixtures_cpp__
#define __fixtures__fixtures_cpp__

#include <stdio.h>

#endif /* defined(__fixtures__fixtures_cpp__) */


================================================
FILE: spec/fixtures/fixtures/fixtures_m.h
================================================
#import <Foundation/Foundation.h>

@interface fixtures_m : NSObject

@end


================================================
FILE: spec/fixtures/fixtures/fixtures_m.m
================================================
#import "fixtures_m.h"

@implementation fixtures_m

@end


================================================
FILE: spec/fixtures/fixtures/fixtures_mm.h
================================================
#import <Foundation/Foundation.h>

@interface fixtures_mm : NSObject

@end


================================================
FILE: spec/fixtures/fixtures/fixtures_mm.mm
================================================
#import "fixtures_mm.h"

@implementation fixtures_mm

@end


================================================
FILE: spec/fixtures/fixtures/more_files/Branches.h
================================================
//
//  Branches.h
//  fixtures
//
//  Created by Julian Krumow on 11.10.14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Branches : NSObject

- (void)branches:(BOOL)goIf skipBranches:(BOOL)skipBranches;

@end


================================================
FILE: spec/fixtures/fixtures/more_files/Branches.m
================================================
//
//  Branches.m
//  fixtures
//
//  Created by Julian Krumow on 11.10.14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import "Branches.h"

@implementation Branches

- (void)branches:(BOOL)goIf skipBranches:(BOOL)skipBranches
{
    if (goIf) {
        NSLog(@"foo.");
        
        if (!skipBranches) {
            NSLog(@"not skipped.");
        }
    } else {
        NSLog(@"bar.");
    }
    
    int i = 5;
    if (i == 5) {
        return;
    }
    switch (i) {
        case 0:
            NSLog(@"0");
            break;
            
        case 1:
            NSLog(@"1");
            break;
        case 5:
            NSLog(@"5");
            break;
        default:
            break;
    }
}

@end


================================================
FILE: spec/fixtures/fixtures/more_files/Empty.h
================================================
//
//  Empty.h
//  fixtures
//
//  Created by Julian Krumow on 27.10.14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Empty : NSObject

@end


================================================
FILE: spec/fixtures/fixtures/more_files/Empty.m
================================================
//
//  Empty.m
//  fixtures
//
//  Created by Julian Krumow on 27.10.14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import "Empty.h"

@implementation Empty

@end


================================================
FILE: spec/fixtures/fixtures/more_files/peekaview.h
================================================
//
//  peekaview.h
//  fixtures
//
//  Created by Mark Larsen on 6/25/14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import <AppKit/AppKit.h>

@interface peekaview : NSView

@end


================================================
FILE: spec/fixtures/fixtures/more_files/peekaview.m
================================================
//
//  peekaview.m
//  fixtures
//
//  Created by Mark Larsen on 6/25/14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import "peekaview.h"

@implementation peekaview

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end


================================================
FILE: spec/fixtures/fixtures/other_fixtures.m
================================================
//
//  other_fixtures.m
//  fixtures
//
//  Created by Mark Larsen on 6/24/14.
//  Copyright (c) 2014 marklarr. All rights reserved.
//

#import "other_fixtures.h"

@implementation other_fixtures

- (void)testedMethod
{
    NSLog(@"tested");
}

- (void)untestedMethod
{
    NSLog(@"untested");
}

@end


================================================
FILE: spec/fixtures/fixtures.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		155BBCA519E9CB6700BACB13 /* Branches.h in Headers */ = {isa = PBXBuildFile; fileRef = 155BBCA319E9CB6700BACB13 /* Branches.h */; };
		155BBCA619E9CB6700BACB13 /* Branches.m in Sources */ = {isa = PBXBuildFile; fileRef = 155BBCA419E9CB6700BACB13 /* Branches.m */; };
		155BBCA819E9CCC500BACB13 /* BranchesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 155BBCA719E9CCC500BACB13 /* BranchesTests.m */; };
		155D8AFE19FED984004666BA /* Empty.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D8AFC19FED984004666BA /* Empty.h */; };
		155D8AFF19FED984004666BA /* Empty.m in Sources */ = {isa = PBXBuildFile; fileRef = 155D8AFD19FED984004666BA /* Empty.m */; };
		3773307C1CC42A58005EAF65 /* fixturesTwo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3773307B1CC42A58005EAF65 /* fixturesTwo.h */; };
		3773307E1CC42A58005EAF65 /* fixturesTwo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3773307D1CC42A58005EAF65 /* fixturesTwo.m */; };
		377330821CC42ABF005EAF65 /* libfixturesTwo.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 377330791CC42A58005EAF65 /* libfixturesTwo.dylib */; };
		8554482F1E461FAF0032518E /* fixturesTestsSecond.m in Sources */ = {isa = PBXBuildFile; fileRef = 8554482E1E461FAF0032518E /* fixturesTestsSecond.m */; };
		85AE69041E45F0F900DA2D47 /* libfixtures.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C9A202D195965F10013B6B3 /* libfixtures.a */; };
		85AE69051E45F0F900DA2D47 /* libfixturesTwo.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 377330791CC42A58005EAF65 /* libfixturesTwo.dylib */; };
		85AE69061E45F0F900DA2D47 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C9A2030195965F10013B6B3 /* Cocoa.framework */; };
		85AE69081E45F0F900DA2D47 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C9A204A195965F10013B6B3 /* InfoPlist.strings */; };
		8C0F0B401ACF43A300793B7D /* fixtures_m.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C0F0B3E1ACF43A300793B7D /* fixtures_m.h */; };
		8C0F0B411ACF43A300793B7D /* fixtures_m.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C0F0B3F1ACF43A300793B7D /* fixtures_m.m */; };
		8C0F0B441ACF44E000793B7D /* fixtures_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C0F0B421ACF44E000793B7D /* fixtures_cpp.cpp */; };
		8C0F0B451ACF44E000793B7D /* fixtures_cpp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C0F0B431ACF44E000793B7D /* fixtures_cpp.h */; };
		8C0F0B481ACF44F200793B7D /* fixtures_mm.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C0F0B461ACF44F200793B7D /* fixtures_mm.h */; };
		8C0F0B491ACF44F200793B7D /* fixtures_mm.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8C0F0B471ACF44F200793B7D /* fixtures_mm.mm */; };
		8C52AEF7195AAE32008A882A /* peekaview.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C52AEF5195AAE32008A882A /* peekaview.h */; };
		8C52AEF8195AAE33008A882A /* peekaview.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C52AEF6195AAE32008A882A /* peekaview.m */; };
		8C52AEFA195AAE70008A882A /* peekaviewTests💣.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C52AEF9195AAE70008A882A /* peekaviewTests💣.m */; };
		8C9A2031195965F10013B6B3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C9A2030195965F10013B6B3 /* Cocoa.framework */; };
		8C9A203B195965F10013B6B3 /* fixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C9A203A195965F10013B6B3 /* fixtures.m */; };
		8C9A2043195965F10013B6B3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C9A2030195965F10013B6B3 /* Cocoa.framework */; };
		8C9A2046195965F10013B6B3 /* libfixtures.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C9A202D195965F10013B6B3 /* libfixtures.a */; };
		8C9A204C195965F10013B6B3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C9A204A195965F10013B6B3 /* InfoPlist.strings */; };
		8C9A204E195965F10013B6B3 /* fixturesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C9A204D195965F10013B6B3 /* fixturesTests.m */; };
		B1E6981225F96B680086A3E2 /* FixtureFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E6980425F96B670086A3E2 /* FixtureFramework.h */; settings = {ATTRIBUTES = (Public, ); }; };
		B1E6982025F96B930086A3E2 /* FlashExperiment.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E6981F25F96B930086A3E2 /* FlashExperiment.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
		85AE68FE1E45F0F900DA2D47 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 8C9A2025195965F00013B6B3 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 8C9A202C195965F10013B6B3;
			remoteInfo = fixtures;
		};
		8C9A2044195965F10013B6B3 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 8C9A2025195965F00013B6B3 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 8C9A202C195965F10013B6B3;
			remoteInfo = fixtures;
		};
		B1E6982F25F96F490086A3E2 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 8C9A2025195965F00013B6B3 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = B1E6980125F96B670086A3E2;
			remoteInfo = FixtureFramework;
		};
		B1E6983725F970320086A3E2 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 8C9A2025195965F00013B6B3 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = B1E6980125F96B670086A3E2;
			remoteInfo = FixtureFramework;
		};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
		155BBCA319E9CB6700BACB13 /* Branches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Branches.h; sourceTree = "<group>"; };
		155BBCA419E9CB6700BACB13 /* Branches.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Branches.m; sourceTree = "<group>"; };
		155BBCA719E9CCC500BACB13 /* BranchesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchesTests.m; sourceTree = "<group>"; };
		155D8AFC19FED984004666BA /* Empty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Empty.h; sourceTree = "<group>"; };
		155D8AFD19FED984004666BA /* Empty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Empty.m; sourceTree = "<group>"; };
		377330791CC42A58005EAF65 /* libfixturesTwo.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libfixturesTwo.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
		3773307B1CC42A58005EAF65 /* fixturesTwo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fixturesTwo.h; sourceTree = "<group>"; };
		3773307D1CC42A58005EAF65 /* fixturesTwo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fixturesTwo.m; sourceTree = "<group>"; };
		8554482E1E461FAF0032518E /* fixturesTestsSecond.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = fixturesTestsSecond.m; sourceTree = "<group>"; };
		85AE690C1E45F0F900DA2D47 /* fixturesTestsSecond.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = fixturesTestsSecond.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
		8C0F0B3E1ACF43A300793B7D /* fixtures_m.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixtures_m.h; sourceTree = "<group>"; };
		8C0F0B3F1ACF43A300793B7D /* fixtures_m.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = fixtures_m.m; sourceTree = "<group>"; };
		8C0F0B421ACF44E000793B7D /* fixtures_cpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fixtures_cpp.cpp; sourceTree = "<group>"; };
		8C0F0B431ACF44E000793B7D /* fixtures_cpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixtures_cpp.h; sourceTree = "<group>"; };
		8C0F0B461ACF44F200793B7D /* fixtures_mm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixtures_mm.h; sourceTree = "<group>"; };
		8C0F0B471ACF44F200793B7D /* fixtures_mm.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = fixtures_mm.mm; sourceTree = "<group>"; };
		8C52AEF5195AAE32008A882A /* peekaview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = peekaview.h; sourceTree = "<group>"; };
		8C52AEF6195AAE32008A882A /* peekaview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = peekaview.m; sourceTree = "<group>"; };
		8C52AEF9195AAE70008A882A /* peekaviewTests💣.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "peekaviewTests💣.m"; sourceTree = "<group>"; };
		8C9A202D195965F10013B6B3 /* libfixtures.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfixtures.a; sourceTree = BUILT_PRODUCTS_DIR; };
		8C9A2030195965F10013B6B3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
		8C9A2033195965F10013B6B3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
		8C9A2034195965F10013B6B3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
		8C9A2035195965F10013B6B3 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
		8C9A2038195965F10013B6B3 /* fixtures-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "fixtures-Prefix.pch"; sourceTree = "<group>"; };
		8C9A2039195965F10013B6B3 /* fixtures.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fixtures.h; sourceTree = "<group>"; };
		8C9A203A195965F10013B6B3 /* fixtures.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fixtures.m; sourceTree = "<group>"; };
		8C9A2040195965F10013B6B3 /* fixturesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = fixturesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
		8C9A2049195965F10013B6B3 /* fixturesTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "fixturesTests-Info.plist"; sourceTree = "<group>"; };
		8C9A204B195965F10013B6B3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
		8C9A204D195965F10013B6B3 /* fixturesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fixturesTests.m; sourceTree = "<group>"; };
		B1E6980225F96B670086A3E2 /* FixtureFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FixtureFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		B1E6980425F96B670086A3E2 /* FixtureFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FixtureFramework.h; sourceTree = "<group>"; };
		B1E6980525F96B670086A3E2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		B1E6980F25F96B680086A3E2 /* FixtureFrameworkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FixtureFrameworkTests.swift; sourceTree = "<group>"; };
		B1E6981125F96B680086A3E2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		B1E6981F25F96B930086A3E2 /* FlashExperiment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashExperiment.swift; sourceTree = "<group>"; };
		B1E6982725F96BD30086A3E2 /* FlashExperimentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashExperimentTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		377330761CC42A58005EAF65 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		85AE69031E45F0F900DA2D47 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				85AE69041E45F0F900DA2D47 /* libfixtures.a in Frameworks */,
				85AE69051E45F0F900DA2D47 /* libfixturesTwo.dylib in Frameworks */,
				85AE69061E45F0F900DA2D47 /* Cocoa.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		8C9A202A195965F10013B6B3 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C9A2031195965F10013B6B3 /* Cocoa.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		8C9A203D195965F10013B6B3 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C9A2046195965F10013B6B3 /* libfixtures.a in Frameworks */,
				377330821CC42ABF005EAF65 /* libfixturesTwo.dylib in Frameworks */,
				8C9A2043195965F10013B6B3 /* Cocoa.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		B1E697FF25F96B670086A3E2 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		3773307A1CC42A58005EAF65 /* fixturesTwo */ = {
			isa = PBXGroup;
			children = (
				3773307B1CC42A58005EAF65 /* fixturesTwo.h */,
				3773307D1CC42A58005EAF65 /* fixturesTwo.m */,
			);
			path = fixturesTwo;
			sourceTree = "<group>";
		};
		8C52AEF4195AAE16008A882A /* more_files */ = {
			isa = PBXGroup;
			children = (
				8C52AEF5195AAE32008A882A /* peekaview.h */,
				8C52AEF6195AAE32008A882A /* peekaview.m */,
				155BBCA319E9CB6700BACB13 /* Branches.h */,
				155BBCA419E9CB6700BACB13 /* Branches.m */,
				155D8AFC19FED984004666BA /* Empty.h */,
				155D8AFD19FED984004666BA /* Empty.m */,
			);
			path = more_files;
			sourceTree = "<group>";
		};
		8C9A2024195965F00013B6B3 = {
			isa = PBXGroup;
			children = (
				8C9A2036195965F10013B6B3 /* fixtures */,
				3773307A1CC42A58005EAF65 /* fixturesTwo */,
				8C9A2047195965F10013B6B3 /* fixturesTests */,
				B1E6980325F96B670086A3E2 /* FixtureFramework */,
				B1E6980E25F96B670086A3E2 /* FixtureFrameworkTests */,
				8C9A202F195965F10013B6B3 /* Frameworks */,
				8C9A202E195965F10013B6B3 /* Products */,
			);
			sourceTree = "<group>";
		};
		8C9A202E195965F10013B6B3 /* Products */ = {
			isa = PBXGroup;
			children = (
				8C9A202D195965F10013B6B3 /* libfixtures.a */,
				8C9A2040195965F10013B6B3 /* fixturesTests.xctest */,
				377330791CC42A58005EAF65 /* libfixturesTwo.dylib */,
				85AE690C1E45F0F900DA2D47 /* fixturesTestsSecond.xctest */,
				B1E6980225F96B670086A3E2 /* FixtureFramework.framework */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		8C9A202F195965F10013B6B3 /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				8C9A2030195965F10013B6B3 /* Cocoa.framework */,
				8C9A2032195965F10013B6B3 /* Other Frameworks */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		8C9A2032195965F10013B6B3 /* Other Frameworks */ = {
			isa = PBXGroup;
			children = (
				8C9A2033195965F10013B6B3 /* Foundation.framework */,
				8C9A2034195965F10013B6B3 /* CoreData.framework */,
				8C9A2035195965F10013B6B3 /* AppKit.framework */,
			);
			name = "Other Frameworks";
			sourceTree = "<group>";
		};
		8C9A2036195965F10013B6B3 /* fixtures */ = {
			isa = PBXGroup;
			children = (
				8C52AEF4195AAE16008A882A /* more_files */,
				8C9A2039195965F10013B6B3 /* fixtures.h */,
				8C9A203A195965F10013B6B3 /* fixtures.m */,
				8C0F0B3E1ACF43A300793B7D /* fixtures_m.h */,
				8C0F0B3F1ACF43A300793B7D /* fixtures_m.m */,
				8C9A2037195965F10013B6B3 /* Supporting Files */,
				8C0F0B421ACF44E000793B7D /* fixtures_cpp.cpp */,
				8C0F0B431ACF44E000793B7D /* fixtures_cpp.h */,
				8C0F0B461ACF44F200793B7D /* fixtures_mm.h */,
				8C0F0B471ACF44F200793B7D /* fixtures_mm.mm */,
			);
			path = fixtures;
			sourceTree = "<group>";
		};
		8C9A2037195965F10013B6B3 /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
				8C9A2038195965F10013B6B3 /* fixtures-Prefix.pch */,
			);
			path = "Supporting Files";
			sourceTree = "<group>";
		};
		8C9A2047195965F10013B6B3 /* fixturesTests */ = {
			isa = PBXGroup;
			children = (
				8C9A204D195965F10013B6B3 /* fixturesTests.m */,
				8554482E1E461FAF0032518E /* fixturesTestsSecond.m */,
				8C9A2048195965F10013B6B3 /* Supporting Files */,
				8C52AEF9195AAE70008A882A /* peekaviewTests💣.m */,
				155BBCA719E9CCC500BACB13 /* BranchesTests.m */,
			);
			path = fixturesTests;
			sourceTree = "<group>";
		};
		8C9A2048195965F10013B6B3 /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
				8C9A2049195965F10013B6B3 /* fixturesTests-Info.plist */,
				8C9A204A195965F10013B6B3 /* InfoPlist.strings */,
			);
			path = "Supporting Files";
			sourceTree = "<group>";
		};
		B1E6980325F96B670086A3E2 /* FixtureFramework */ = {
			isa = PBXGroup;
			children = (
				B1E6980425F96B670086A3E2 /* FixtureFramework.h */,
				B1E6980525F96B670086A3E2 /* Info.plist */,
				B1E6981F25F96B930086A3E2 /* FlashExperiment.swift */,
			);
			path = FixtureFramework;
			sourceTree = "<group>";
		};
		B1E6980E25F96B670086A3E2 /* FixtureFrameworkTests */ = {
			isa = PBXGroup;
			children = (
				B1E6980F25F96B680086A3E2 /* FixtureFrameworkTests.swift */,
				B1E6981125F96B680086A3E2 /* Info.plist */,
				B1E6982725F96BD30086A3E2 /* FlashExperimentTests.swift */,
			);
			path = FixtureFrameworkTests;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
		377330771CC42A58005EAF65 /* Headers */ = {
			isa = PBXHeadersBuildPhase;
			buildActionMask = 2147483647;
			files = (
				3773307C1CC42A58005EAF65 /* fixturesTwo.h in Headers */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		8C9A202B195965F10013B6B3 /* Headers */ = {
			isa = PBXHeadersBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C0F0B481ACF44F200793B7D /* fixtures_mm.h in Headers */,
				8C0F0B401ACF43A300793B7D /* fixtures_m.h in Headers */,
				155D8AFE19FED984004666BA /* Empty.h in Headers */,
				155BBCA519E9CB6700BACB13 /* Branches.h in Headers */,
				8C0F0B451ACF44E000793B7D /* fixtures_cpp.h in Headers */,
				8C52AEF7195AAE32008A882A /* peekaview.h in Headers */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		B1E697FD25F96B670086A3E2 /* Headers */ = {
			isa = PBXHeadersBuildPhase;
			buildActionMask = 2147483647;
			files = (
				B1E6981225F96B680086A3E2 /* FixtureFramework.h in Headers */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXHeadersBuildPhase section */

/* Begin PBXNativeTarget section */
		377330781CC42A58005EAF65 /* fixturesTwo */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 3773307F1CC42A58005EAF65 /* Build configuration list for PBXNativeTarget "fixturesTwo" */;
			buildPhases = (
				377330751CC42A58005EAF65 /* Sources */,
				377330761CC42A58005EAF65 /* Frameworks */,
				377330771CC42A58005EAF65 /* Headers */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = fixturesTwo;
			productName = fixturesTwo;
			productReference = 377330791CC42A58005EAF65 /* libfixturesTwo.dylib */;
			productType = "com.apple.product-type.library.dynamic";
		};
		85AE68FC1E45F0F900DA2D47 /* fixturesTestsSecond */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 85AE69091E45F0F900DA2D47 /* Build configuration list for PBXNativeTarget "fixturesTestsSecond" */;
			buildPhases = (
				85AE68FF1E45F0F900DA2D47 /* Sources */,
				85AE69031E45F0F900DA2D47 /* Frameworks */,
				85AE69071E45F0F900DA2D47 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
				85AE68FD1E45F0F900DA2D47 /* PBXTargetDependency */,
			);
			name = fixturesTestsSecond;
			productName = fixturesTests;
			productReference = 85AE690C1E45F0F900DA2D47 /* fixturesTestsSecond.xctest */;
			productType = "com.apple.product-type.bundle.unit-test";
		};
		8C9A202C195965F10013B6B3 /* fixtures */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 8C9A2051195965F10013B6B3 /* Build configuration list for PBXNativeTarget "fixtures" */;
			buildPhases = (
				8C9A2029195965F10013B6B3 /* Sources */,
				8C9A202A195965F10013B6B3 /* Frameworks */,
				8C9A202B195965F10013B6B3 /* Headers */,
			);
			buildRules = (
			);
			dependencies = (
				B1E6983025F96F490086A3E2 /* PBXTargetDependency */,
			);
			name = fixtures;
			productName = fixtures;
			productReference = 8C9A202D195965F10013B6B3 /* libfixtures.a */;
			productType = "com.apple.product-type.library.static";
		};
		8C9A203F195965F10013B6B3 /* fixturesTests */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 8C9A2054195965F10013B6B3 /* Build configuration list for PBXNativeTarget "fixturesTests" */;
			buildPhases = (
				8C9A203C195965F10013B6B3 /* Sources */,
				8C9A203D195965F10013B6B3 /* Frameworks */,
				8C9A203E195965F10013B6B3 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
				B1E6983825F970320086A3E2 /* PBXTargetDependency */,
				8C9A2045195965F10013B6B3 /* PBXTargetDependency */,
			);
			name = fixturesTests;
			productName = fixturesTests;
			productReference = 8C9A2040195965F10013B6B3 /* fixturesTests.xctest */;
			productType = "com.apple.product-type.bundle.unit-test";
		};
		B1E6980125F96B670086A3E2 /* FixtureFramework */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = B1E6981725F96B680086A3E2 /* Build configuration list for PBXNativeTarget "FixtureFramework" */;
			buildPhases = (
				B1E697FD25F96B670086A3E2 /* Headers */,
				B1E697FE25F96B670086A3E2 /* Sources */,
				B1E697FF25F96B670086A3E2 /* Frameworks */,
				B1E6980025F96B670086A3E2 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = FixtureFramework;
			productName = FixtureFramework;
			productReference = B1E6980225F96B670086A3E2 /* FixtureFramework.framework */;
			productType = "com.apple.product-type.framework";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		8C9A2025195965F00013B6B3 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastSwiftUpdateCheck = 1240;
				LastUpgradeCheck = 0510;
				ORGANIZATIONNAME = marklarr;
				TargetAttributes = {
					377330781CC42A58005EAF65 = {
						CreatedOnToolsVersion = 7.3;
					};
					B1E6980125F96B670086A3E2 = {
						CreatedOnToolsVersion = 12.4;
						LastSwiftMigration = 1240;
						ProvisioningStyle = Automatic;
					};
				};
			};
			buildConfigurationList = 8C9A2028195965F00013B6B3 /* Build configuration list for PBXProject "fixtures" */;
			compatibilityVersion = "Xcode 3.2";
			developmentRegion = English;
			hasScannedForEncodings = 0;
			knownRegions = (
				English,
				en,
			);
			mainGroup = 8C9A2024195965F00013B6B3;
			productRefGroup = 8C9A202E195965F10013B6B3 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				8C9A202C195965F10013B6B3 /* fixtures */,
				377330781CC42A58005EAF65 /* fixturesTwo */,
				8C9A203F195965F10013B6B3 /* fixturesTests */,
				85AE68FC1E45F0F900DA2D47 /* fixturesTestsSecond */,
				B1E6980125F96B670086A3E2 /* FixtureFramework */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		85AE69071E45F0F900DA2D47 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				85AE69081E45F0F900DA2D47 /* InfoPlist.strings in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		8C9A203E195965F10013B6B3 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C9A204C195965F10013B6B3 /* InfoPlist.strings in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		B1E6980025F96B670086A3E2 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		377330751CC42A58005EAF65 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				3773307E1CC42A58005EAF65 /* fixturesTwo.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		85AE68FF1E45F0F900DA2D47 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8554482F1E461FAF0032518E /* fixturesTestsSecond.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		8C9A2029195965F10013B6B3 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C9A203B195965F10013B6B3 /* fixtures.m in Sources */,
				155D8AFF19FED984004666BA /* Empty.m in Sources */,
				8C0F0B411ACF43A300793B7D /* fixtures_m.m in Sources */,
				8C0F0B441ACF44E000793B7D /* fixtures_cpp.cpp in Sources */,
				155BBCA619E9CB6700BACB13 /* Branches.m in Sources */,
				8C0F0B491ACF44F200793B7D /* fixtures_mm.mm in Sources */,
				8C52AEF8195AAE33008A882A /* peekaview.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		8C9A203C195965F10013B6B3 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C9A204E195965F10013B6B3 /* fixturesTests.m in Sources */,
				8C52AEFA195AAE70008A882A /* peekaviewTests💣.m in Sources */,
				155BBCA819E9CCC500BACB13 /* BranchesTests.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		B1E697FE25F96B670086A3E2 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				B1E6982025F96B930086A3E2 /* FlashExperiment.swift in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
		85AE68FD1E45F0F900DA2D47 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = 8C9A202C195965F10013B6B3 /* fixtures */;
			targetProxy = 85AE68FE1E45F0F900DA2D47 /* PBXContainerItemProxy */;
		};
		8C9A2045195965F10013B6B3 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = 8C9A202C195965F10013B6B3 /* fixtures */;
			targetProxy = 8C9A2044195965F10013B6B3 /* PBXContainerItemProxy */;
		};
		B1E6983025F96F490086A3E2 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = B1E6980125F96B670086A3E2 /* FixtureFramework */;
			targetProxy = B1E6982F25F96F490086A3E2 /* PBXContainerItemProxy */;
		};
		B1E6983825F970320086A3E2 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = B1E6980125F96B670086A3E2 /* FixtureFramework */;
			targetProxy = B1E6983725F970320086A3E2 /* PBXContainerItemProxy */;
		};
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
		8C9A204A195965F10013B6B3 /* InfoPlist.strings */ = {
			isa = PBXVariantGroup;
			children = (
				8C9A204B195965F10013B6B3 /* en */,
			);
			name = InfoPlist.strings;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		377330801CC42A58005EAF65 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				DYLIB_COMPATIBILITY_VERSION = 1;
				DYLIB_CURRENT_VERSION = 1;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				EXECUTABLE_PREFIX = lib;
				GCC_NO_COMMON_BLOCKS = YES;
				MTL_ENABLE_DEBUG_INFO = YES;
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Debug;
		};
		377330811CC42A58005EAF65 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				COPY_PHASE_STRIP = NO;
				DYLIB_COMPATIBILITY_VERSION = 1;
				DYLIB_CURRENT_VERSION = 1;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				EXECUTABLE_PREFIX = lib;
				GCC_NO_COMMON_BLOCKS = YES;
				MTL_ENABLE_DEBUG_INFO = NO;
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Release;
		};
		85AE690A1E45F0F900DA2D47 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				COMBINE_HIDPI_IMAGES = YES;
				FRAMEWORK_SEARCH_PATHS = (
					"$(DEVELOPER_FRAMEWORKS_DIR)",
					"$(inherited)",
				);
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
				GCC_PREFIX_HEADER = "fixtures/Supporting Files/fixtures-Prefix.pch";
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				PRODUCT_NAME = "$(TARGET_NAME)";
				WRAPPER_EXTENSION = xctest;
			};
			name = Debug;
		};
		85AE690B1E45F0F900DA2D47 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				COMBINE_HIDPI_IMAGES = YES;
				FRAMEWORK_SEARCH_PATHS = (
					"$(DEVELOPER_FRAMEWORKS_DIR)",
					"$(inherited)",
				);
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
				GCC_PREFIX_HEADER = "fixtures/Supporting Files/fixtures-Prefix.pch";
				PRODUCT_NAME = "$(TARGET_NAME)";
				WRAPPER_EXTENSION = xctest;
			};
			name = Release;
		};
		8C9A204F195965F10013B6B3 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.9;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = macosx;
			};
			name = Debug;
		};
		8C9A2050195965F10013B6B3 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				COPY_PHASE_STRIP = YES;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.9;
				SDKROOT = macosx;
			};
			name = Release;
		};
		8C9A2052195965F10013B6B3 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
				GCC_PREFIX_HEADER = "fixtures/Supporting Files/fixtures-Prefix.pch";
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Debug;
		};
		8C9A2053195965F10013B6B3 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
				GCC_PREFIX_HEADER = "fixtures/Supporting Files/fixtures-Prefix.pch";
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Release;
		};
		8C9A2055195965F10013B6B3 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				COMBINE_HIDPI_IMAGES = YES;
				FRAMEWORK_SEARCH_PATHS = (
					"$(DEVELOPER_FRAMEWORKS_DIR)",
					"$(inherited)",
				);
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
				GCC_PREFIX_HEADER = "fixtures/Supporting Files/fixtures-Prefix.pch";
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				INFOPLIST_FILE = "fixturesTests/Supporting Files/fixturesTests-Info.plist";
				PRODUCT_NAME = "$(TARGET_NAME)";
				WRAPPER_EXTENSION = xctest;
			};
			name = Debug;
		};
		8C9A2056195965F10013B6B3 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				COMBINE_HIDPI_IMAGES = YES;
				FRAMEWORK_SEARCH_PATHS = (
					"$(DEVELOPER_FRAMEWORKS_DIR)",
					"$(inherited)",
				);
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
				GCC_PREFIX_HEADER = "fixtures/Supporting Files/fixtures-Prefix.pch";
				INFOPLIST_FILE = "fixturesTests/Supporting Files/fixturesTests-Info.plist";
				PRODUCT_NAME = "$(TARGET_NAME)";
				WRAPPER_EXTENSION = xctest;
			};
			name = Release;
		};
		B1E6981325F96B680086A3E2 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CODE_SIGN_STYLE = Automatic;
				COMBINE_HIDPI_IMAGES = YES;
				CURRENT_PROJECT_VERSION = 1;
				DEFINES_MODULE = YES;
				DYLIB_COMPATIBILITY_VERSION = 1;
				DYLIB_CURRENT_VERSION = 1;
				DYLIB_INSTALL_NAME_BASE = "@rpath";
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_NO_COMMON_BLOCKS = YES;
				INFOPLIST_FILE = FixtureFramework/Info.plist;
				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
				MACOSX_DEPLOYMENT_TARGET = 11.1;
				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
				MTL_FAST_MATH = YES;
				PRODUCT_BUNDLE_IDENTIFIER = com.onato.FixtureFramework;
				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
				SKIP_INSTALL = YES;
				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
				SWIFT_VERSION = 5.0;
				VERSIONING_SYSTEM = "apple-generic";
				VERSION_INFO_PREFIX = "";
			};
			name = Debug;
		};
		B1E6981425F96B680086A3E2 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CODE_SIGN_STYLE = Automatic;
				COMBINE_HIDPI_IMAGES = YES;
				COPY_PHASE_STRIP = NO;
				CURRENT_PROJECT_VERSION = 1;
				DEFINES_MODULE = YES;
				DYLIB_COMPATIBILITY_VERSION = 1;
				DYLIB_CURRENT_VERSION = 1;
				DYLIB_INSTALL_NAME_BASE = "@rpath";
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_NO_COMMON_BLOCKS = YES;
				INFOPLIST_FILE = FixtureFramework/Info.plist;
				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
				MACOSX_DEPLOYMENT_TARGET = 11.1;
				MTL_ENABLE_DEBUG_INFO = NO;
				MTL_FAST_MATH = YES;
				PRODUCT_BUNDLE_IDENTIFIER = com.onato.FixtureFramework;
				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
				SKIP_INSTALL = YES;
				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
				SWIFT_VERSION = 5.0;
				VERSIONING_SYSTEM = "apple-generic";
				VERSION_INFO_PREFIX = "";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		3773307F1CC42A58005EAF65 /* Build configuration list for PBXNativeTarget "fixturesTwo" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				377330801CC42A58005EAF65 /* Debug */,
				377330811CC42A58005EAF65 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		85AE69091E45F0F900DA2D47 /* Build configuration list for PBXNativeTarget "fixturesTestsSecond" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				85AE690A1E45F0F900DA2D47 /* Debug */,
				85AE690B1E45F0F900DA2D47 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		8C9A2028195965F00013B6B3 /* Build configuration list for PBXProject "fixtures" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				8C9A204F195965F10013B6B3 /* Debug */,
				8C9A2050195965F10013B6B3 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		8C9A2051195965F10013B6B3 /* Build configuration list for PBXNativeTarget "fixtures" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				8C9A2052195965F10013B6B3 /* Debug */,
				8C9A2053195965F10013B6B3 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		8C9A2054195965F10013B6B3 /* Build configuration list for PBXNativeTarget "fixturesTests" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				8C9A2055195965F10013B6B3 /* Debug */,
				8C9A2056195965F10013B6B3 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		B1E6981725F96B680086A3E2 /* Build configuration list for PBXNativeTarget "FixtureFramework" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				B1E6981325F96B680086A3E2 /* Debug */,
				B1E6981425F96B680086A3E2 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};
	rootObject = 8C9A2025195965F00013B6B3 /* Project object */;
}


================================================
FILE: spec/fixtures/fixtures.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:fixtures.xcodeproj">
   </FileRef>
</Workspace>


================================================
FILE: spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/aggregateFixturesTests.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
   LastUpgradeVersion = "0730"
   version = "1.3">
   <BuildAction
      parallelizeBuildables = "YES"
      buildImplicitDependencies = "YES">
      <BuildActionEntries>
         <BuildActionEntry
            buildForTesting = "YES"
            buildForRunning = "YES"
            buildForProfiling = "YES"
            buildForArchiving = "YES"
            buildForAnalyzing = "YES">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "85AE68FC1E45F0F900DA2D47"
               BuildableName = "fixturesTestsSecond.xctest"
               BlueprintName = "fixturesTestsSecond"
               ReferencedContainer = "container:fixtures.xcodeproj">
            </BuildableReference>
         </BuildActionEntry>
      </BuildActionEntries>
   </BuildAction>
   <TestAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      shouldUseLaunchSchemeArgsEnv = "YES">
      <Testables>
         <TestableReference
            skipped = "NO">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "85AE68FC1E45F0F900DA2D47"
               BuildableName = "fixturesTestsSecond.xctest"
               BlueprintName = "fixturesTestsSecond"
               ReferencedContainer = "container:fixtures.xcodeproj">
            </BuildableReference>
         </TestableReference>
         <TestableReference
            skipped = "NO">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "8C9A203F195965F10013B6B3"
               BuildableName = "fixturesTests.xctest"
               BlueprintName = "fixturesTests"
               ReferencedContainer = "container:fixtures.xcodeproj">
            </BuildableReference>
         </TestableReference>
      </Testables>
      <MacroExpansion>
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "85AE68FC1E45F0F900DA2D47"
            BuildableName = "fixturesTestsSecond.xctest"
            BlueprintName = "fixturesTestsSecond"
            ReferencedContainer = "container:fixtures.xcodeproj">
         </BuildableReference>
      </Macro
Download .txt
gitextract_cr8xe6x0/

├── .coveralls.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── assets/
│   ├── highlight.pack.js
│   └── slather.css
├── bin/
│   └── slather
├── lib/
│   ├── cocoapods_plugin.rb
│   ├── slather/
│   │   ├── command/
│   │   │   ├── coverage_command.rb
│   │   │   ├── setup_command.rb
│   │   │   └── version_command.rb
│   │   ├── coverage_file.rb
│   │   ├── coverage_info.rb
│   │   ├── coverage_service/
│   │   │   ├── cobertura_xml_output.rb
│   │   │   ├── coveralls.rb
│   │   │   ├── gutter_json_output.rb
│   │   │   ├── hardcover.rb
│   │   │   ├── html_output.rb
│   │   │   ├── json_output.rb
│   │   │   ├── llvm_cov_output.rb
│   │   │   ├── simple_output.rb
│   │   │   └── sonarqube_xml_output.rb
│   │   ├── coveralls_coverage.rb
│   │   ├── profdata_coverage_file.rb
│   │   ├── project.rb
│   │   └── version.rb
│   └── slather.rb
├── slather.gemspec
└── spec/
    ├── fixtures/
    │   ├── FixtureFramework/
    │   │   ├── FixtureFramework.h
    │   │   ├── FlashExperiment.swift
    │   │   └── Info.plist
    │   ├── FixtureFrameworkTests/
    │   │   ├── FixtureFrameworkTests.swift
    │   │   ├── FlashExperimentTests.swift
    │   │   └── Info.plist
    │   ├── fixtures/
    │   │   ├── Fixtures.swift
    │   │   ├── Supporting Files/
    │   │   │   └── fixtures-Prefix.pch
    │   │   ├── fixtures.h
    │   │   ├── fixtures.m
    │   │   ├── fixtures_cpp.cpp
    │   │   ├── fixtures_cpp.h
    │   │   ├── fixtures_m.h
    │   │   ├── fixtures_m.m
    │   │   ├── fixtures_mm.h
    │   │   ├── fixtures_mm.mm
    │   │   ├── more_files/
    │   │   │   ├── Branches.h
    │   │   │   ├── Branches.m
    │   │   │   ├── Empty.h
    │   │   │   ├── Empty.m
    │   │   │   ├── peekaview.h
    │   │   │   └── peekaview.m
    │   │   └── other_fixtures.m
    │   ├── fixtures.xcodeproj/
    │   │   ├── project.pbxproj
    │   │   ├── project.xcworkspace/
    │   │   │   └── contents.xcworkspacedata
    │   │   └── xcshareddata/
    │   │       └── xcschemes/
    │   │           ├── aggregateFixturesTests.xcscheme
    │   │           ├── fixtures.xcscheme
    │   │           ├── fixturesTests.xcscheme
    │   │           ├── fixturesTestsSecond.xcscheme
    │   │           └── fixturesTwo.xcscheme
    │   ├── fixtures.xcworkspace/
    │   │   ├── contents.xcworkspacedata
    │   │   └── xcshareddata/
    │   │       ├── IDEWorkspaceChecks.plist
    │   │       └── xcschemes/
    │   │           └── fixturesTestsWorkspace.xcscheme
    │   ├── fixturesTests/
    │   │   ├── BranchesTests.m
    │   │   ├── Supporting Files/
    │   │   │   ├── en.lproj/
    │   │   │   │   └── InfoPlist.strings
    │   │   │   └── fixturesTests-Info.plist
    │   │   ├── fixturesTests.m
    │   │   ├── fixturesTestsSecond.m
    │   │   └── peekaviewTests💣.m
    │   ├── fixturesTwo/
    │   │   ├── fixturesTwo.h
    │   │   └── fixturesTwo.m
    │   ├── fixtures_html/
    │   │   ├── Branches.m.html
    │   │   ├── BranchesTests.m.html
    │   │   ├── fixtures.m.html
    │   │   ├── fixturesTests.m.html
    │   │   ├── index.html
    │   │   └── peekaviewTests💣.m.html
    │   ├── gutter.json
    │   └── sonarqube-generic-coverage.xml
    ├── slather/
    │   ├── cocoapods_plugin_spec.rb
    │   ├── coverage_file_spec.rb
    │   ├── coverage_service/
    │   │   ├── cobertura_xml_spec.rb
    │   │   ├── coveralls_spec.rb
    │   │   ├── gutter_json_spec.rb
    │   │   ├── hardcover_spec.rb
    │   │   ├── html_output_spec.rb
    │   │   ├── json_spec.rb
    │   │   ├── llvm_cov_spec.rb
    │   │   ├── simple_output_spec.rb
    │   │   └── sonarqube_xml_spec.rb
    │   ├── profdata_coverage_spec.rb
    │   └── project_spec.rb
    └── spec_helper.rb
Download .txt
SYMBOL INDEX (284 symbols across 23 files)

FILE: assets/highlight.pack.js
  function n (line 1) | function n(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").repl...
  function t (line 1) | function t(e){return e.nodeName.toLowerCase()}
  function r (line 1) | function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}
  function a (line 1) | function a(e){return/no-?highlight|plain|text/.test(e)}
  function i (line 1) | function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNod...
  function o (line 1) | function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t...
  function u (line 1) | function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i...
  function c (line 1) | function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[...
  function s (line 1) | function s(e){function n(e){return e&&e.source||e}function t(t,r){return...
  function f (line 1) | function f(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n....
  function l (line 1) | function l(e,t){t=t||w.languages||Object.keys(x);var r={r:0,value:n(e)},...
  function g (line 1) | function g(e){return w.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,fun...
  function h (line 1) | function h(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)...
  function p (line 1) | function p(e){var n=i(e);if(!a(n)){var t;w.useBR?(t=document.createEleme...
  function d (line 1) | function d(e){w=o(w,e)}
  function b (line 1) | function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("...
  function v (line 1) | function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener(...
  function m (line 1) | function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e)...
  function N (line 1) | function N(){return Object.keys(x)}
  function E (line 1) | function E(e){return x[e]||x[R[e]]}

FILE: lib/slather.rb
  type Slather (line 18) | module Slather
    function prepare_pods (line 22) | def self.prepare_pods(pods)
    function xcode_version (line 26) | def self.xcode_version

FILE: lib/slather/command/coverage_command.rb
  class CoverageCommand (line 1) | class CoverageCommand < Clamp::Command
    method execute (line 41) | def execute
    method setup_ymlfile (line 69) | def setup_ymlfile
    method setup_build_directory (line 73) | def setup_build_directory
    method setup_source_directory (line 77) | def setup_source_directory
    method setup_output_directory (line 81) | def setup_output_directory
    method setup_ignore_list (line 85) | def setup_ignore_list
    method setup_service_name (line 89) | def setup_service_name
    method post (line 107) | def post
    method project (line 111) | def project
    method setup_coverage_service (line 122) | def setup_coverage_service
    method setup_verbose_mode (line 144) | def setup_verbose_mode
    method setup_input_format (line 148) | def setup_input_format
    method setup_scheme (line 152) | def setup_scheme
    method setup_configuration (line 156) | def setup_configuration
    method setup_workspace (line 160) | def setup_workspace
    method setup_binary_file (line 164) | def setup_binary_file
    method setup_binary_basename (line 168) | def setup_binary_basename
    method setup_arch (line 172) | def setup_arch
    method setup_source_files (line 176) | def setup_source_files
    method setup_decimals (line 180) | def setup_decimals

FILE: lib/slather/command/setup_command.rb
  class SetupCommand (line 1) | class SetupCommand < Clamp::Command
    method execute (line 7) | def execute
    method setup_ymlfile (line 18) | def setup_ymlfile

FILE: lib/slather/command/version_command.rb
  class VersionCommand (line 1) | class VersionCommand < Clamp::Command
    method execute (line 3) | def execute

FILE: lib/slather/coverage_file.rb
  type Slather (line 4) | module Slather
    class CoverageFile (line 5) | class CoverageFile
      method initialize (line 12) | def initialize(project, gcno_file_pathname)
      method source_file_pathname (line 17) | def source_file_pathname
      method source_file (line 36) | def source_file
      method source_data (line 40) | def source_data
      method gcov_data (line 44) | def gcov_data
      method all_lines (line 67) | def all_lines
      method cleaned_gcov_data (line 76) | def cleaned_gcov_data
      method raw_data (line 81) | def raw_data
      method line_coverage_data (line 85) | def line_coverage_data
      method line_number_in_line (line 97) | def line_number_in_line(line)
      method coverage_for_line (line 101) | def coverage_for_line(line)
      method branch_coverage_data (line 115) | def branch_coverage_data
      method source_file_basename (line 134) | def source_file_basename
      method line_number_separator (line 138) | def line_number_separator
      method supported_file_extensions (line 142) | def supported_file_extensions

FILE: lib/slather/coverage_info.rb
  type Slather (line 1) | module Slather
    type CoverageInfo (line 2) | module CoverageInfo
      function num_lines_tested (line 4) | def num_lines_tested
      function num_lines_testable (line 8) | def num_lines_testable
      function rate_lines_tested (line 12) | def rate_lines_tested
      function percentage_lines_tested (line 20) | def percentage_lines_tested
      function branch_coverage_data_for_statement_on_line (line 28) | def branch_coverage_data_for_statement_on_line(line_number)
      function num_branches_for_statement_on_line (line 32) | def num_branches_for_statement_on_line(line_number)
      function num_branch_hits_for_statement_on_line (line 36) | def num_branch_hits_for_statement_on_line(line_number)
      function rate_branch_coverage_for_statement_on_line (line 40) | def rate_branch_coverage_for_statement_on_line(line_number)
      function percentage_branch_coverage_for_statement_on_line (line 49) | def percentage_branch_coverage_for_statement_on_line(line_number)
      function num_branches_testable (line 53) | def num_branches_testable
      function num_branches_tested (line 59) | def num_branches_tested
      function rate_branches_tested (line 65) | def rate_branches_tested
      function source_file_pathname_relative_to_repo_root (line 73) | def source_file_pathname_relative_to_repo_root
      function ignored? (line 77) | def ignored?
      function include_file? (line 83) | def include_file?

FILE: lib/slather/coverage_service/cobertura_xml_output.rb
  type Slather (line 4) | module Slather
    type CoverageService (line 5) | module CoverageService
      type CoberturaXmlOutput (line 6) | module CoberturaXmlOutput
        function coverage_file_class (line 8) | def coverage_file_class
        function post (line 17) | def post
        function store_report (line 22) | def store_report(report)
        function grouped_coverage_files (line 31) | def grouped_coverage_files(coverage_files)
        function create_xml_report (line 44) | def create_xml_report(coverage_files)
        function create_class_node (line 120) | def create_class_node(coverage_file)
        function create_line_node (line 145) | def create_line_node(line, coverage_file)
        function create_empty_xml_report (line 169) | def create_empty_xml_report

FILE: lib/slather/coverage_service/coveralls.rb
  type Slather (line 1) | module Slather
    type CoverageService (line 2) | module CoverageService
      type Coveralls (line 3) | module Coveralls
        function coverage_file_class (line 5) | def coverage_file_class
        function travis_job_id (line 14) | def travis_job_id
        function circleci_job_id (line 19) | def circleci_job_id
        function circleci_pull_request (line 24) | def circleci_pull_request
        function teamcity_job_id (line 29) | def teamcity_job_id
        function jenkins_job_id (line 34) | def jenkins_job_id
        function github_job_id (line 39) | def github_job_id
        function bitrise_job_id (line 44) | def bitrise_job_id
        function bitrise_pull_request (line 49) | def bitrise_pull_request
        function github_pull_request (line 54) | def github_pull_request
        function github_repo_name (line 59) | def github_repo_name
        function jenkins_branch_name (line 64) | def jenkins_branch_name
        function teamcity_branch_name (line 74) | def teamcity_branch_name
        function github_branch_name (line 79) | def github_branch_name
        function bitrise_branch_name (line 84) | def bitrise_branch_name
        function buildkite_job_id (line 89) | def buildkite_job_id
        function buildkite_pull_request (line 94) | def buildkite_pull_request
        function jenkins_git_info (line 99) | def jenkins_git_info
        function teamcity_git_info (line 111) | def teamcity_git_info
        function circleci_build_url (line 124) | def circleci_build_url
        function circleci_git_info (line 129) | def circleci_git_info
        function buildkite_git_info (line 141) | def buildkite_git_info
        function buildkite_build_url (line 153) | def buildkite_build_url
        function github_git_info (line 157) | def github_git_info
        function bitrise_git_info (line 169) | def bitrise_git_info
        function github_build_url (line 182) | def github_build_url
        function is_parallel (line 187) | def is_parallel
        function github_job_name (line 192) | def github_job_name
        function coveralls_coverage_data (line 197) | def coveralls_coverage_data
        function post (line 339) | def post
        function coveralls_api_jobs_path (line 363) | def coveralls_api_jobs_path

FILE: lib/slather/coverage_service/gutter_json_output.rb
  type Slather (line 1) | module Slather
    type CoverageService (line 2) | module CoverageService
      type GutterJsonOutput (line 3) | module GutterJsonOutput
        function coverage_file_class (line 5) | def coverage_file_class
        function post (line 14) | def post

FILE: lib/slather/coverage_service/hardcover.rb
  type Slather (line 1) | module Slather
    type CoverageService (line 2) | module CoverageService
      type Hardcover (line 3) | module Hardcover
        function coverage_file_class (line 5) | def coverage_file_class
        function jenkins_job_id (line 14) | def jenkins_job_id
        function hardcover_coverage_data (line 19) | def hardcover_coverage_data
        function post (line 37) | def post
        function hardcover_api_jobs_path (line 50) | def hardcover_api_jobs_path
        function hardcover_base_url (line 55) | def hardcover_base_url

FILE: lib/slather/coverage_service/html_output.rb
  type Slather (line 4) | module Slather
    type CoverageService (line 5) | module CoverageService
      type HtmlOutput (line 6) | module HtmlOutput
        function coverage_file_class (line 10) | def coverage_file_class
        function directory_path (line 19) | def directory_path
        function post (line 25) | def post
        function print_path_coverage (line 37) | def print_path_coverage(index_html)
        function open_coverage (line 42) | def open_coverage(index_html)
        function create_html_reports (line 47) | def create_html_reports(coverage_files)
        function generate_reports (line 52) | def generate_reports(reports)
        function create_index_html (line 67) | def create_index_html(coverage_files)
        function create_htmls_from_files (line 149) | def create_htmls_from_files(coverage_files)
        function create_html_from_file (line 153) | def create_html_from_file(coverage_file)
        function generate_html_template (line 235) | def generate_html_template(title, is_index, is_file_empty)
        function gem_root_path (line 283) | def gem_root_path
        function class_for_coverage_line (line 287) | def class_for_coverage_line(coverage_file, coverage_line)
        function hits_for_coverage_line (line 296) | def hits_for_coverage_line(coverage_file, coverage_line)
        function class_for_coverage_percentage (line 305) | def class_for_coverage_percentage(percentage)

FILE: lib/slather/coverage_service/json_output.rb
  type Slather (line 4) | module Slather
    type CoverageService (line 5) | module CoverageService
      type JsonOutput (line 6) | module JsonOutput
        function coverage_file_class (line 8) | def coverage_file_class
        function post (line 17) | def post
        function store_report (line 28) | def store_report(report)

FILE: lib/slather/coverage_service/llvm_cov_output.rb
  type Slather (line 4) | module Slather
    type CoverageService (line 5) | module CoverageService
      type LlvmCovOutput (line 6) | module LlvmCovOutput
        function coverage_file_class (line 8) | def coverage_file_class
        function post (line 17) | def post
        function store_report (line 25) | def store_report(report)

FILE: lib/slather/coverage_service/simple_output.rb
  type Slather (line 1) | module Slather
    type CoverageService (line 2) | module CoverageService
      type SimpleOutput (line 3) | module SimpleOutput
        function coverage_file_class (line 5) | def coverage_file_class
        function post (line 14) | def post

FILE: lib/slather/coverage_service/sonarqube_xml_output.rb
  type Slather (line 4) | module Slather
    type CoverageService (line 5) | module CoverageService
      type SonarqubeXmlOutput (line 6) | module SonarqubeXmlOutput
        function coverage_file_class (line 8) | def coverage_file_class
        function post (line 17) | def post
        function store_report (line 22) | def store_report(report)
        function create_xml_report (line 31) | def create_xml_report(coverage_files)
        function create_empty_xml_report (line 52) | def create_empty_xml_report

FILE: lib/slather/coveralls_coverage.rb
  type Slather (line 1) | module Slather
    type CoverallsCoverage (line 2) | module CoverallsCoverage
      function as_json (line 4) | def as_json

FILE: lib/slather/profdata_coverage_file.rb
  type Slather (line 5) | module Slather
    class ProfdataCoverageFile (line 6) | class ProfdataCoverageFile
      method initialize (line 13) | def initialize(project, source, line_numbers_first)
      method create_line_data (line 20) | def create_line_data
      method path_on_first_line? (line 27) | def path_on_first_line?
      method source_file_pathname (line 31) | def source_file_pathname
      method source_file_pathname= (line 63) | def source_file_pathname= (source_file_pathname)
      method source_file (line 67) | def source_file
      method source_code_lines (line 71) | def source_code_lines
      method ignore_error_lines (line 76) | def ignore_error_lines(lines, line_numbers_first = self.line_numbers...
      method source_data (line 84) | def source_data
      method all_lines (line 88) | def all_lines
      method raw_source (line 92) | def raw_source
      method cleaned_gcov_data (line 98) | def cleaned_gcov_data
      method raw_data (line 102) | def raw_data
      method line_number_in_line (line 106) | def line_number_in_line(line, line_numbers_first = self.line_numbers...
      method line_coverage_data (line 139) | def line_coverage_data
      method coverage_for_line (line 145) | def coverage_for_line(line, line_numbers_first = self.line_numbers_f...
      method branch_coverage_data (line 189) | def branch_coverage_data
      method branch_region_data (line 207) | def branch_region_data
      method source_file_basename (line 235) | def source_file_basename
      method line_number_separator (line 239) | def line_number_separator
      method supported_file_extensions (line 243) | def supported_file_extensions
      method ignored? (line 248) | def ignored?

FILE: lib/slather/project.rb
  type Xcodeproj (line 7) | module Xcodeproj
    class Project (line 9) | class Project
      method slather_setup_for_coverage (line 11) | def slather_setup_for_coverage(format = :auto)
  type Slather (line 43) | module Slather
    class Project (line 44) | class Project < Xcodeproj::Project
      method open (line 52) | def self.open(xcodeproj)
      method failure_help_string (line 58) | def failure_help_string
      method derived_data_path (line 62) | def derived_data_path
      method coverage_files (line 96) | def coverage_files
      method gcov_coverage_files (line 104) | def gcov_coverage_files
      method profdata_coverage_files (line 119) | def profdata_coverage_files
      method pathnames_per_binary (line 137) | def pathnames_per_binary(binary_path)
      method create_coverage_files_for_binary (line 156) | def create_coverage_files_for_binary(binary_path, pathnames_per_binary)
      method create_coverage_files (line 179) | def create_coverage_files(binary_path, path_objects)
      method create_profdata (line 202) | def create_profdata(binary_path, pathnames)
      method remove_extension (line 207) | def remove_extension(path)
      method first_product_name (line 211) | def first_product_name
      method profdata_coverage_dir (line 218) | def profdata_coverage_dir
      method profdata_file (line 253) | def profdata_file
      method unsafe_llvm_cov_export_output (line 267) | def unsafe_llvm_cov_export_output(binary_path)
      method llvm_cov_export_output (line 285) | def llvm_cov_export_output(binary_path)
      method unsafe_profdata_llvm_cov_output (line 291) | def unsafe_profdata_llvm_cov_output(binary_path, source_files)
      method profdata_llvm_cov_output (line 312) | def profdata_llvm_cov_output(binary_path, source_files)
      method dedupe (line 318) | def dedupe(coverage_files)
      method yml_filename= (line 325) | def self.yml_filename=(var)
      method yml_filename (line 329) | def self.yml_filename
      method yml (line 333) | def self.yml
      method configure (line 337) | def configure
      method configure_build_directory (line 377) | def configure_build_directory
      method configure_source_directory (line 381) | def configure_source_directory
      method configure_output_directory (line 385) | def configure_output_directory
      method configure_ignore_list (line 389) | def configure_ignore_list
      method configure_source_files (line 393) | def configure_source_files
      method configure_ci_service (line 397) | def configure_ci_service
      method configure_input_format (line 401) | def configure_input_format
      method input_format= (line 405) | def input_format=(format)
      method configure_scheme (line 417) | def configure_scheme
      method configure_configuration (line 421) | def configure_configuration
      method configure_decimals (line 425) | def configure_decimals
      method configure_workspace (line 431) | def configure_workspace
      method ci_service= (line 435) | def ci_service=(service)
      method configure_coverage_service (line 439) | def configure_coverage_service
      method configure_coverage_access_token (line 443) | def configure_coverage_access_token
      method coverage_service= (line 447) | def coverage_service=(service)
      method configure_binary_file (line 474) | def configure_binary_file
      method configure_arch (line 480) | def configure_arch
      method decimal_f (line 484) | def decimal_f decimal_arg
      method find_binary_file_in_bundle (line 491) | def find_binary_file_in_bundle(bundle_file)
      method find_binary_files (line 509) | def find_binary_files
      method find_buildable_names (line 616) | def find_buildable_names(xcscheme)
      method matches_arch (line 660) | def matches_arch(binary_path)
      method find_source_files (line 670) | def find_source_files
      method load_option_array (line 684) | def load_option_array(option)

FILE: lib/slather/version.rb
  type Slather (line 1) | module Slather

FILE: spec/slather/coverage_service/html_output_spec.rb
  function extract_header_title (line 45) | def extract_header_title(doc)
  function extract_title (line 75) | def extract_title(doc)
  function extract_coverage_text (line 79) | def extract_coverage_text(doc)
  function extract_coverage_class (line 83) | def extract_coverage_class(doc)
  function extract_cov_header (line 87) | def extract_cov_header(doc)
  function extract_cov_index (line 93) | def extract_cov_index(doc)
  function extract_title (line 129) | def extract_title(doc)
  function extract_subtitle (line 133) | def extract_subtitle(doc)
  function extract_filepath (line 137) | def extract_filepath(doc)
  function extract_cov_data (line 141) | def extract_cov_data(doc)
  function extract_filepath (line 183) | def extract_filepath(doc)

FILE: spec/slather/project_spec.rb
  class SpecCoverageFile (line 39) | class SpecCoverageFile < Slather::CoverageFile
  class SpecXcode7CoverageFile (line 68) | class SpecXcode7CoverageFile < Slather::ProfdataCoverageFile
  class SpecXcode7CoverageFile (line 135) | class SpecXcode7CoverageFile < Slather::ProfdataCoverageFile
  function decimal_f (line 692) | def decimal_f *args

FILE: spec/spec_helper.rb
  type FixtureHelpers (line 30) | module FixtureHelpers
    function delete_derived_data (line 31) | def self.delete_derived_data
    function delete_temp_gcov_files (line 38) | def self.delete_temp_gcov_files
Condensed preview — 95 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (385K chars).
[
  {
    "path": ".coveralls.yml",
    "chars": 23,
    "preview": "service_name: travis-ci"
  },
  {
    "path": ".gitignore",
    "chars": 611,
    "preview": "*.gem\n*.rbc\n.bundle\n.config\n.yardoc\nGemfile.lock\nInstalledFiles\n_yardoc\ncoverage\ndoc/\nlib/bundler/man\npkg\nrdoc\nspec/repo"
  },
  {
    "path": ".travis.yml",
    "chars": 278,
    "preview": "language: objective-c\nscript: bundle exec rake\nosx_image: xcode12.2\n\ncache: bundler\n\nbefore_install:\n  - curl http://cur"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 19176,
    "preview": "# CHANGELOG\n\n## v2.8.5\n\n* Update xcodeproj to 1.27.1 to support Xcode 16 folder references\n  [authiatr](https://github.c"
  },
  {
    "path": "Gemfile",
    "chars": 92,
    "preview": "source 'https://rubygems.org'\n\n# Specify your gem's dependencies in slather.gemspec\ngemspec\n"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1068,
    "preview": "Copyright (c) 2014 Mark Larsen\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na cop"
  },
  {
    "path": "README.md",
    "chars": 10728,
    "preview": "\n\n![Slather Logo](https://raw.githubusercontent.com/SlatherOrg/slather/master/docs/logo.jpg)\n\n[![Gem Version](https://ba"
  },
  {
    "path": "Rakefile",
    "chars": 114,
    "preview": "require \"bundler/gem_tasks\"\nrequire \"rspec/core/rake_task\"\n\nRSpec::Core::RakeTask.new(:spec)\n\ntask default: :spec\n"
  },
  {
    "path": "assets/highlight.pack.js",
    "chars": 11432,
    "preview": "!function(e){\"undefined\"!=typeof exports?e(exports):(window.hljs=e({}),\"function\"==typeof define&&define.amd&&define(\"hl"
  },
  {
    "path": "assets/slather.css",
    "chars": 6331,
    "preview": "/* --------------------------------------------------------\nSlather stylesheet\n\nversion: 0.1\nauthor: Ikhsan Assaat (@ixn"
  },
  {
    "path": "bin/slather",
    "chars": 598,
    "preview": "#!/usr/bin/env ruby\nrequire 'clamp'\nrequire 'yaml'\nrequire_relative '../lib/slather'\nrequire_relative '../lib/slather/co"
  },
  {
    "path": "lib/cocoapods_plugin.rb",
    "chars": 314,
    "preview": "require_relative 'slather'\n\nPod::HooksManager.register('slather', :post_install) do |installer_context|\n  sandbox_root ="
  },
  {
    "path": "lib/slather/command/coverage_command.rb",
    "chars": 6402,
    "preview": "class CoverageCommand < Clamp::Command\n\n  parameter \"[PROJECT]\", \"Path to the xcodeproj\", :attribute_name => :xcodeproj_"
  },
  {
    "path": "lib/slather/command/setup_command.rb",
    "chars": 828,
    "preview": "class SetupCommand < Clamp::Command\n  parameter \"[PROJECT]\", \"Path to the .xcodeproj\", :attribute_name => :xcodeproj_pat"
  },
  {
    "path": "lib/slather/command/version_command.rb",
    "chars": 102,
    "preview": "class VersionCommand < Clamp::Command\n\n  def execute\n    puts \"slather #{Slather::VERSION}\"\n  end\nend\n"
  },
  {
    "path": "lib/slather/coverage_file.rb",
    "chars": 4024,
    "preview": "require_relative 'coverage_info'\nrequire_relative 'coveralls_coverage'\n\nmodule Slather\n  class CoverageFile\n\n    include"
  },
  {
    "path": "lib/slather/coverage_info.rb",
    "chars": 2458,
    "preview": "module Slather\n  module CoverageInfo\n\n    def num_lines_tested\n      line_coverage_data.compact.select { |cd| cd > 0 }.c"
  },
  {
    "path": "lib/slather/coverage_service/cobertura_xml_output.rb",
    "chars": 7362,
    "preview": "require 'nokogiri'\nrequire 'date'\n\nmodule Slather\n  module CoverageService\n    module CoberturaXmlOutput\n\n      def cove"
  },
  {
    "path": "lib/slather/coverage_service/coveralls.rb",
    "chars": 12320,
    "preview": "module Slather\n  module CoverageService\n    module Coveralls\n\n      def coverage_file_class\n        if input_format == \""
  },
  {
    "path": "lib/slather/coverage_service/gutter_json_output.rb",
    "chars": 1553,
    "preview": "module Slather\n  module CoverageService\n    module GutterJsonOutput\n\n      def coverage_file_class\n        if input_form"
  },
  {
    "path": "lib/slather/coverage_service/hardcover.rb",
    "chars": 1793,
    "preview": "module Slather\n  module CoverageService\n    module Hardcover\n\n      def coverage_file_class\n        if input_format == \""
  },
  {
    "path": "lib/slather/coverage_service/html_output.rb",
    "chars": 12439,
    "preview": "require 'nokogiri'\nrequire \"cgi\"\n\nmodule Slather\n  module CoverageService\n    module HtmlOutput\n\n      attr_reader :docs"
  },
  {
    "path": "lib/slather/coverage_service/json_output.rb",
    "chars": 859,
    "preview": "require 'nokogiri'\nrequire 'date'\n\nmodule Slather\n  module CoverageService\n    module JsonOutput\n\n      def coverage_fil"
  },
  {
    "path": "lib/slather/coverage_service/llvm_cov_output.rb",
    "chars": 868,
    "preview": "require 'nokogiri'\nrequire 'date'\n\nmodule Slather\n  module CoverageService\n    module LlvmCovOutput\n\n      def coverage_"
  },
  {
    "path": "lib/slather/coverage_service/simple_output.rb",
    "chars": 2189,
    "preview": "module Slather\n  module CoverageService\n    module SimpleOutput\n\n      def coverage_file_class\n        if input_format ="
  },
  {
    "path": "lib/slather/coverage_service/sonarqube_xml_output.rb",
    "chars": 1781,
    "preview": "require 'nokogiri'\nrequire 'date'\n\nmodule Slather\n  module CoverageService\n    module SonarqubeXmlOutput\n\n      def cove"
  },
  {
    "path": "lib/slather/coveralls_coverage.rb",
    "chars": 232,
    "preview": "module Slather\n  module CoverallsCoverage\n\n    def as_json\n      {\n        :name => source_file_pathname_relative_to_rep"
  },
  {
    "path": "lib/slather/profdata_coverage_file.rb",
    "chars": 6906,
    "preview": "require_relative 'coverage_info'\nrequire_relative 'coveralls_coverage'\nrequire 'digest/md5'\n\nmodule Slather\n  class Prof"
  },
  {
    "path": "lib/slather/project.rb",
    "chars": 25633,
    "preview": "require 'fileutils'\nrequire 'xcodeproj'\nrequire 'json'\nrequire 'yaml'\nrequire 'shellwords'\n\nmodule Xcodeproj\n\n  class Pr"
  },
  {
    "path": "lib/slather/version.rb",
    "chars": 73,
    "preview": "module Slather\n  VERSION = '2.8.5' unless defined?(Slather::VERSION)\nend\n"
  },
  {
    "path": "lib/slather.rb",
    "chars": 1322,
    "preview": "require_relative 'slather/version'\nrequire_relative 'slather/project'\nrequire_relative 'slather/coverage_info'\nrequire_r"
  },
  {
    "path": "slather.gemspec",
    "chars": 1483,
    "preview": "# encoding: utf-8\nlib = File.expand_path('../lib', __FILE__)\n$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)\nreq"
  },
  {
    "path": "spec/fixtures/FixtureFramework/FixtureFramework.h",
    "chars": 557,
    "preview": "//\n//  FixtureFramework.h\n//  FixtureFramework\n//\n//  Created by Stephen Williams on 11/03/21.\n//  Copyright © 2021 mark"
  },
  {
    "path": "spec/fixtures/FixtureFramework/FlashExperiment.swift",
    "chars": 111,
    "preview": "import Foundation\n\npublic struct FlashExperiment {\n    public let isAwesome = true\n    \n    public init() {}\n}\n"
  },
  {
    "path": "spec/fixtures/FixtureFramework/Info.plist",
    "chars": 855,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "spec/fixtures/FixtureFrameworkTests/FixtureFrameworkTests.swift",
    "chars": 986,
    "preview": "//\n//  FixtureFrameworkTests.swift\n//  FixtureFrameworkTests\n//\n//  Created by Stephen Williams on 11/03/21.\n//  Copyrig"
  },
  {
    "path": "spec/fixtures/FixtureFrameworkTests/FlashExperimentTests.swift",
    "chars": 233,
    "preview": "import XCTest\nimport FixtureFramework\n\nclass FlashExperimentTests: XCTestCase {\n    func testExample() throws {\n        "
  },
  {
    "path": "spec/fixtures/FixtureFrameworkTests/Info.plist",
    "chars": 727,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "spec/fixtures/fixtures/Fixtures.swift",
    "chars": 347,
    "preview": "\nimport UIKit\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n  "
  },
  {
    "path": "spec/fixtures/fixtures/Supporting Files/fixtures-Prefix.pch",
    "chars": 172,
    "preview": "//\n//  Prefix header\n//\n//  The contents of this file are implicitly included at the beginning of every source file.\n//\n"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures.h",
    "chars": 250,
    "preview": "//\n//  fixtures.h\n//  fixtures\n//\n//  Created by Mark Larsen on 6/24/14.\n//  Copyright (c) 2014 marklarr. All rights res"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures.m",
    "chars": 286,
    "preview": "//\n//  fixtures.m\n//  fixtures\n//\n//  Created by Mark Larsen on 6/24/14.\n//  Copyright (c) 2014 marklarr 🌟. All rights r"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures_cpp.cpp",
    "chars": 163,
    "preview": "//\n//  fixtures_cpp.cpp\n//  fixtures\n//\n//  Created by Larsen, Mark on 4/3/15.\n//  Copyright (c) 2015 marklarr. All righ"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures_cpp.h",
    "chars": 140,
    "preview": "#ifndef __fixtures__fixtures_cpp__\n#define __fixtures__fixtures_cpp__\n\n#include <stdio.h>\n\n#endif /* defined(__fixtures_"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures_m.h",
    "chars": 74,
    "preview": "#import <Foundation/Foundation.h>\n\n@interface fixtures_m : NSObject\n\n@end\n"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures_m.m",
    "chars": 57,
    "preview": "#import \"fixtures_m.h\"\n\n@implementation fixtures_m\n\n@end\n"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures_mm.h",
    "chars": 75,
    "preview": "#import <Foundation/Foundation.h>\n\n@interface fixtures_mm : NSObject\n\n@end\n"
  },
  {
    "path": "spec/fixtures/fixtures/fixtures_mm.mm",
    "chars": 59,
    "preview": "#import \"fixtures_mm.h\"\n\n@implementation fixtures_mm\n\n@end\n"
  },
  {
    "path": "spec/fixtures/fixtures/more_files/Branches.h",
    "chars": 268,
    "preview": "//\n//  Branches.h\n//  fixtures\n//\n//  Created by Julian Krumow on 11.10.14.\n//  Copyright (c) 2014 marklarr. All rights "
  },
  {
    "path": "spec/fixtures/fixtures/more_files/Branches.m",
    "chars": 731,
    "preview": "//\n//  Branches.m\n//  fixtures\n//\n//  Created by Julian Krumow on 11.10.14.\n//  Copyright (c) 2014 marklarr. All rights "
  },
  {
    "path": "spec/fixtures/fixtures/more_files/Empty.h",
    "chars": 200,
    "preview": "//\n//  Empty.h\n//  fixtures\n//\n//  Created by Julian Krumow on 27.10.14.\n//  Copyright (c) 2014 marklarr. All rights res"
  },
  {
    "path": "spec/fixtures/fixtures/more_files/Empty.m",
    "chars": 178,
    "preview": "//\n//  Empty.m\n//  fixtures\n//\n//  Created by Julian Krumow on 27.10.14.\n//  Copyright (c) 2014 marklarr. All rights res"
  },
  {
    "path": "spec/fixtures/fixtures/more_files/peekaview.h",
    "chars": 195,
    "preview": "//\n//  peekaview.h\n//  fixtures\n//\n//  Created by Mark Larsen on 6/25/14.\n//  Copyright (c) 2014 marklarr. All rights re"
  },
  {
    "path": "spec/fixtures/fixtures/more_files/peekaview.m",
    "chars": 530,
    "preview": "//\n//  peekaview.m\n//  fixtures\n//\n//  Created by Mark Larsen on 6/25/14.\n//  Copyright (c) 2014 marklarr. All rights re"
  },
  {
    "path": "spec/fixtures/fixtures/other_fixtures.m",
    "chars": 302,
    "preview": "//\n//  other_fixtures.m\n//  fixtures\n//\n//  Created by Mark Larsen on 6/24/14.\n//  Copyright (c) 2014 marklarr. All righ"
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/project.pbxproj",
    "chars": 40265,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 153,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:fixtures.xcodep"
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/aggregateFixturesTests.xcscheme",
    "chars": 4179,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/fixtures.xcscheme",
    "chars": 3651,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0600\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/fixturesTests.xcscheme",
    "chars": 1922,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0600\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/fixturesTestsSecond.xcscheme",
    "chars": 3746,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0600\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/fixturesTwo.xcscheme",
    "chars": 2874,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "spec/fixtures/fixtures.xcworkspace/contents.xcworkspacedata",
    "chars": 154,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:fixtures.xcode"
  },
  {
    "path": "spec/fixtures/fixtures.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "spec/fixtures/fixtures.xcworkspace/xcshareddata/xcschemes/fixturesTestsWorkspace.xcscheme",
    "chars": 3638,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "spec/fixtures/fixturesTests/BranchesTests.m",
    "chars": 834,
    "preview": "//\n//  BranchesTests.m\n//  fixtures\n//\n//  Created by Julian Krumow on 11.10.14.\n//  Copyright (c) 2014 marklarr. All ri"
  },
  {
    "path": "spec/fixtures/fixturesTests/Supporting Files/en.lproj/InfoPlist.strings",
    "chars": 45,
    "preview": "/* Localized versions of Info.plist keys */\n\n"
  },
  {
    "path": "spec/fixtures/fixturesTests/Supporting Files/fixturesTests-Info.plist",
    "chars": 688,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "spec/fixtures/fixturesTests/fixturesTests.m",
    "chars": 802,
    "preview": "//\n//  fixturesTests.m\n//  fixturesTests\n//\n//  Created by Mark Larsen on 6/24/14.\n//  Copyright (c) 2014 marklarr. All "
  },
  {
    "path": "spec/fixtures/fixturesTests/fixturesTestsSecond.m",
    "chars": 292,
    "preview": "//\n//  fixturesTestsSecond.m\n//  fixturesTests\n//\n//  Created by Mark Larsen on 6/24/14.\n//  Copyright (c) 2014 marklarr"
  },
  {
    "path": "spec/fixtures/fixturesTests/peekaviewTests💣.m",
    "chars": 598,
    "preview": "//\n//  peekaviewTests💣.m\n//  fixtures\n//\n//  Created by Mark Larsen on 6/25/14.\n//  Copyright (c) 2014 marklarr. All rig"
  },
  {
    "path": "spec/fixtures/fixturesTwo/fixturesTwo.h",
    "chars": 241,
    "preview": "//\n//  fixturesTwo.h\n//  fixturesTwo\n//\n//  Created by Kent Sutherland on 4/17/16.\n//  Copyright © 2016 marklarr. All ri"
  },
  {
    "path": "spec/fixtures/fixturesTwo/fixturesTwo.m",
    "chars": 289,
    "preview": "//\n//  fixturesTwo.m\n//  fixturesTwo\n//\n//  Created by Kent Sutherland on 4/17/16.\n//  Copyright © 2016 marklarr. All ri"
  },
  {
    "path": "spec/fixtures/fixtures_html/Branches.m.html",
    "chars": 7750,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>"
  },
  {
    "path": "spec/fixtures/fixtures_html/BranchesTests.m.html",
    "chars": 6910,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>"
  },
  {
    "path": "spec/fixtures/fixtures_html/fixtures.m.html",
    "chars": 4284,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>"
  },
  {
    "path": "spec/fixtures/fixtures_html/fixturesTests.m.html",
    "chars": 7686,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>"
  },
  {
    "path": "spec/fixtures/fixtures_html/index.html",
    "chars": 2910,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>"
  },
  {
    "path": "spec/fixtures/fixtures_html/peekaviewTests💣.m.html",
    "chars": 6156,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>"
  },
  {
    "path": "spec/fixtures/gutter.json",
    "chars": 10756,
    "preview": "{\"meta\":{\"timestamp\":\"2016-04-17 16:53:43.919308\"},\"symbols_by_file\":{\"spec/fixtures/fixtures/fixtures.m\":[{\"line\":1,\"lo"
  },
  {
    "path": "spec/fixtures/sonarqube-generic-coverage.xml",
    "chars": 4428,
    "preview": "<?xml version=\"1.0\"?>\n<coverage version=\"1\">\n  <file path=\"spec/fixtures/fixtures/fixtures.m\">\n    <lineToCover lineNumb"
  },
  {
    "path": "spec/slather/cocoapods_plugin_spec.rb",
    "chars": 821,
    "preview": "require 'cocoapods'\nrequire File.join(File.dirname(__FILE__), '..', 'spec_helper')\nrequire File.join(File.dirname(__FILE"
  },
  {
    "path": "spec/slather/coverage_file_spec.rb",
    "chars": 12567,
    "preview": "require File.join(File.dirname(__FILE__), '..', 'spec_helper')\n\ndescribe Slather::CoverageFile do\n\n  let(:fixtures_proje"
  },
  {
    "path": "spec/slather/coverage_service/cobertura_xml_spec.rb",
    "chars": 1570,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\nrequire 'json'\n\ndescribe Slather::CoverageService::"
  },
  {
    "path": "spec/slather/coverage_service/coveralls_spec.rb",
    "chars": 13581,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\n\ndescribe Slather::CoverageService::Coveralls do\n\n "
  },
  {
    "path": "spec/slather/coverage_service/gutter_json_spec.rb",
    "chars": 919,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\nrequire 'json'\n\ndescribe Slather::CoverageService::"
  },
  {
    "path": "spec/slather/coverage_service/hardcover_spec.rb",
    "chars": 4471,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\n\ndescribe Slather::CoverageService::Hardcover do\n\n "
  },
  {
    "path": "spec/slather/coverage_service/html_output_spec.rb",
    "chars": 7173,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\nrequire 'nokogiri'\n\ndescribe Slather::CoverageServi"
  },
  {
    "path": "spec/slather/coverage_service/json_spec.rb",
    "chars": 1307,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\nrequire 'json'\n\ndescribe Slather::CoverageService::"
  },
  {
    "path": "spec/slather/coverage_service/llvm_cov_spec.rb",
    "chars": 1425,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\n\ndescribe Slather::CoverageService::LlvmCovOutput d"
  },
  {
    "path": "spec/slather/coverage_service/simple_output_spec.rb",
    "chars": 2449,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\n\ndescribe Slather::CoverageService::SimpleOutput do"
  },
  {
    "path": "spec/slather/coverage_service/sonarqube_xml_spec.rb",
    "chars": 1389,
    "preview": "require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')\nrequire 'json'\n\ndescribe Slather::CoverageService::"
  },
  {
    "path": "spec/slather/profdata_coverage_spec.rb",
    "chars": 9704,
    "preview": "require File.join(File.dirname(__FILE__), '..', 'spec_helper')\n\ndescribe Slather::ProfdataCoverageFile do\n\n  let(:fixtur"
  },
  {
    "path": "spec/slather/project_spec.rb",
    "chars": 32763,
    "preview": "require File.join(File.dirname(__FILE__), '..', 'spec_helper')\n\ndescribe Slather::Project do\n\n  FIXTURES_PROJECT_SETUP_P"
  },
  {
    "path": "spec/spec_helper.rb",
    "chars": 2445,
    "preview": "if ENV['SIMPLECOV']\n  require 'simplecov'\n  SimpleCov.start\nelsif ENV['TRAVIS']\n  require 'coveralls'\n  Coveralls.wear!\n"
  }
]

About this extraction

This page contains the full source code of the venmo/slather GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 95 files (348.6 KB), approximately 100.6k tokens, and a symbol index with 284 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!