-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
605 additions
and
216 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
on: | ||
push: | ||
tags: | ||
- '*.**' | ||
|
||
jobs: | ||
build: | ||
name: Create release, build and upload binary asset | ||
runs-on: macos-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
- name: Build project | ||
run: | | ||
go build -o xcccr | ||
- name: Create Release | ||
id: create_release | ||
uses: actions/create-release@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
tag_name: ${{ github.ref }} | ||
release_name: ${{ github.ref }} | ||
body_path: RELEASENOTES.md | ||
draft: false | ||
prerelease: false | ||
- name: Upload Release Asset | ||
id: upload-release-asset | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps | ||
asset_path: ./xcccr | ||
asset_name: xcccr | ||
asset_content_type: application/octet-stream |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
ProjectPath = "/Users/home/" # Usualy ok to leave empty. If empty gets current working dir at runtime. | ||
FilterTargets = ["CoreTests"] # If a target name contains one of these substrings the target would be filtered. Empty string "" matches everything. Please note that if regex is used targets filtering has no effect. | ||
FilterPaths = ["Tests","UITests","Constants.swift"] # If a path contains one of these substrings the path (file, dir) would be filtered. Empty string "" matches everything. Please note that if regex is used path filtering has no effect. | ||
FilterPattern = "[\\S\\s]*secret\\.json$" # Go flavored regex (non-PCRE!). Please check https://golang.org/pkg/regexp/ for more info. When used in config escape characters should be escaped twice for config parsing (unfortunately). Please note that if regex is used targets filtering has no effect. | ||
InvertFilter = false # Set `false` to disallow targets and paths in filters. Set `true` to allow only targets and paths in filters. Default `false`. | ||
IncludeMasked = false # Skip recalculating coverage, just read from xccov report regardless masked (filtered) targets and paths. Default `false`. | ||
MeterLOC = false # Set `false` for coverage percent and `true` for number of LOCs e.g. 42/13 (now/was). Default `false`. | ||
Tolerance = 5 # Percent. Default 0. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2020 Ilya Yachin | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
## Xcode Coverage for Commit Reporter (xcccr) | ||
This dead simple tool only works with Apple's `xccov` generated code coverage reports in json format. It takes two reports, diffs and spits out warnings and errors in GitHub Actions compatible format. | ||
|
||
### CLI usage | ||
Flag | Description | ||
--------|------------ | ||
`-cur` | For path of "current report" file. A report to be checked. | ||
`-lst` | For path of "last report" file. A report to be base for determining whether the coverage metrics is lowered or became higher in "current" report. | ||
`-tol` | Percent to be tolerated before error. E.g. last is 70%, current is 65% and tol is 10 means no error. | ||
`-proj` | Project root to get relative paths. If empty and missing from config working dir would be used. Usually in GitHub Actions you just want the working dir. | ||
`-rg` | Regex filter, pass it in quotes e.g. `-rg="[\s\S]\.swift"`. Matching paths would be ignored. When used with `-i` the result is opposite: only matching paths would be visible to reporter. Please note that if regex is used targets and paths filtering set in config has no effect. | ||
`-i` | Invert filter. Applied to -rg and to targets/paths filter lists in config. If no filters supplied prevents reporting allowing nothing. | ||
`-m` | Include masked files coverage in total metrics. If true warnings would be produced only for unfiltered targets/paths, but total coverage would be reported for all the files as listed in original xccov json. | ||
`-loc` | Count covered LOCs diff instead of percent coverage. | ||
`-cfg` | Path to config. Parameters passed with the flags have precedence and overrides the values stored in config. Config passed with this flag overrides default config at `.xcccr.toml`. If there aren't any config default values are used. | ||
|
||
|
||
If there aren't last report or it isn't needed it's ok to pass only the current one. Current report also may be piped in to xcccr like that `cat report.json | ./xcccr` | ||
|
||
### Config values | ||
|
||
Please check `.xcccr.toml.example` for reference. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
- This release only tested manually. Help wanted to cover with tests. | ||
- Some minor bugs are expected. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"encoding/json" | ||
"errors" | ||
"flag" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
"regexp" | ||
"strconv" | ||
|
||
"github.com/BurntSushi/toml" | ||
) | ||
|
||
func readConfig(path string) (*Config, error) { | ||
var cfg Config | ||
_, err := toml.DecodeFile(path, &cfg) | ||
return &cfg, err | ||
} | ||
|
||
func prepareRunConditions() (rnCnd *RunConditions, err error) { | ||
rnCnd = &RunConditions{} | ||
|
||
dumbValue := dumbValue() | ||
|
||
lstPth := flag.String( | ||
"lst", | ||
"", | ||
"Pass the path of last report to compare current report to.", | ||
) | ||
curPth := flag.String( | ||
"cur", | ||
"", | ||
"Pass the path of current report.", | ||
) | ||
tolerance := flag.String("tol", | ||
dumbValue, | ||
"Percent to be tolerated before error. E.g. last is 70%, current is 65% and tol is 10 means no error.", | ||
) | ||
projRoot := flag.String( | ||
"proj", | ||
getWorkdir(), | ||
"Project root to get relative paths. If empty and missing from config working dir would be used.", | ||
) | ||
filtr := flag.String("rg", | ||
dumbValue, | ||
"Regex filter. Applied to paths.", | ||
) | ||
fInvert := flag.Bool( | ||
"i", | ||
false, | ||
"Invert filter. Applied to -rg and to targets/paths filter lists in config. If no filters supplied prevents reporting allowing nothing.", | ||
) | ||
includeMasked := flag.Bool( | ||
"m", | ||
false, | ||
"Include masked files coverage in total metrics. If true warnings would be produced only for unfiltered targets/paths, but total coverage would be calculated for all the files.", | ||
) | ||
meterLOC := flag.Bool( | ||
"loc", | ||
false, | ||
"Count covered LOCs diff instead of percent coverage.", | ||
) | ||
cfgPth := flag.String( | ||
"cfg", | ||
"", | ||
"Path to config.", | ||
) | ||
|
||
flag.Parse() | ||
|
||
if *cfgPth == "" { | ||
*cfgPth = ".xcccr.toml" | ||
} | ||
cfg, err := readConfig(*cfgPth) | ||
if err != nil && !os.IsNotExist(err) { | ||
return | ||
} | ||
if *tolerance != dumbValue { | ||
i, e := strconv.Atoi(*tolerance) | ||
if i < 0 || i > 100 { | ||
e = errors.New("out of allowed range") | ||
} | ||
if e != nil { | ||
err = fmt.Errorf("tolerance -tol must be an int in range 0 to 100. %w", err) | ||
return | ||
} | ||
cfg.Tolerance = i | ||
} | ||
if *filtr != dumbValue { | ||
cfg.FilterPattern = *filtr | ||
} | ||
if *fInvert { | ||
cfg.InvertFilter = true | ||
} | ||
if *includeMasked { | ||
cfg.IncludeMasked = true | ||
} | ||
if *meterLOC { | ||
cfg.MeterLOC = true | ||
} | ||
cfg.ProjectPath = *projRoot | ||
if cfg.FilterPattern != "" { | ||
re, e := regexp.Compile(cfg.FilterPattern) | ||
if e != nil { | ||
err = fmt.Errorf("filter pattern (aka regexp) is invalid: %w", e) | ||
return | ||
} | ||
rnCnd.Regexp = re | ||
} | ||
|
||
rnCnd.Config = cfg | ||
rnCnd.DiffUnitChan = make(chan DiffUnit) | ||
rnCnd.TotalUnitChan = make(chan DiffUnit) | ||
|
||
curXccRep, err := getCurrentCoverage(curPth) | ||
if err != nil { | ||
return | ||
} | ||
rnCnd.CurrentReport = curXccRep | ||
|
||
lstXccRep, err := getLastCoverage(lstPth) | ||
if err != nil { | ||
return | ||
} | ||
rnCnd.LastReport = lstXccRep | ||
|
||
return | ||
} | ||
|
||
func getCurrentCoverage(curPth *string) (curXccRep *XCCoverageReport, err error) { | ||
var pipeIn []byte | ||
info, _ := os.Stdin.Stat() | ||
if info.Mode()&os.ModeNamedPipe != 0 { | ||
reader := bufio.NewReader(os.Stdin) | ||
for { | ||
ln, _, err := reader.ReadLine() | ||
if err != nil && err == io.EOF { | ||
break | ||
} | ||
pipeIn = append(pipeIn, ln...) | ||
} | ||
} | ||
|
||
if *curPth != "" { | ||
curXccRep, err = readReportFile(*curPth) | ||
if err != nil { | ||
return | ||
} | ||
} | ||
// piped in file content always overrides passed with a 'cur' flag | ||
if len(pipeIn) > 0 { | ||
if err = json.Unmarshal(pipeIn, &curXccRep); err != nil { | ||
return | ||
} | ||
} | ||
if *curPth == "" && len(pipeIn) == 0 { | ||
log.Fatal("No data passed to programme to report coverage.") | ||
} | ||
return | ||
} | ||
|
||
func getLastCoverage(lstPth *string) (lstXccRep *XCCoverageReport, err error) { | ||
lstXccRep = &XCCoverageReport{} | ||
if *lstPth != "" { | ||
lstXccRep, err = readReportFile(*lstPth) | ||
notExist := os.IsNotExist(err) | ||
if err != nil && notExist == false { | ||
return | ||
} | ||
if notExist { | ||
fmt.Println("Previous report file not found. Continuing with current report only.") | ||
} | ||
} | ||
return | ||
} | ||
|
||
func readReportFile(filePath string) (report *XCCoverageReport, err error) { | ||
report = &XCCoverageReport{} | ||
filePath = fmt.Sprintf("%s%s", getWorkdir(), filePath) | ||
_, err = os.Stat(filePath) | ||
if err != nil { | ||
return | ||
} | ||
fByt, err := ioutil.ReadFile(filePath) | ||
if err != nil { | ||
return | ||
} | ||
err = json.Unmarshal(fByt, report) | ||
|
||
return | ||
} | ||
|
||
func dumbValue() string { | ||
return randomStr(12) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module xcccr | ||
|
||
go 1.15 | ||
|
||
require github.com/BurntSushi/toml v0.3.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= |
Oops, something went wrong.