Skip to content

Commit

Permalink
initial release 0.1b
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeyPetrachkov committed Aug 23, 2023
0 parents commit ece32b0
Show file tree
Hide file tree
Showing 57 changed files with 2,220 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/healthcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: HealthCheck
on:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:

runs-on: macos-latest

steps:
- uses: actions/checkout@v3
- uses: swift-actions/setup-swift@65540b95f51493d65f5e59e97dcef9629ddf11bf
with:
swift-version: "5.8.0"
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v
26 changes: 26 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: ReleaseBuild
on:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:

runs-on: macos-latest

steps:
- uses: actions/checkout@v3
- uses: swift-actions/setup-swift@65540b95f51493d65f5e59e97dcef9629ddf11bf
with:
swift-version: "5.8.0"
- name: Build
run: swift build -v --configuration release

- name: Upload binary
if: success()
uses: actions/upload-artifact@v3
with:
name: xcresultscrapper
path: ./.build/release/XCResultScrapperClient
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
build
output
7 changes: 7 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright 2023, Sergei Petrachkov

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.
23 changes: 23 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"pins" : [
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser",
"state" : {
"revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a",
"version" : "1.2.2"
}
},
{
"identity" : "swiftyxml",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SergeyPetrachkov/SwiftyXML",
"state" : {
"branch" : "master",
"revision" : "30040f38675bc3a1666a0b0f6417adabaf26a3c6"
}
}
],
"version" : 2
}
88 changes: 88 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

// MARK: - Externals

let swiftXML = Target.Dependency.product(name: "SwiftyXML", package: "SwiftyXML")
let argumentParser = Target.Dependency.product(name: "ArgumentParser", package: "swift-argument-parser")

// MARK: - Internals

// MARK: Utils
let utils = "XCResultScrapperUtils"
let utilsTarget: Target = .target(name: utils, path: path(for: utils))
let utilsTargetDependency: Target.Dependency = .target(name: utils)

// MARK: Domain
let xcResultScrapperDomain = "XCResultScrapperDomain"
let domainTarget: Target = .target(
name: xcResultScrapperDomain,
dependencies: [utilsTargetDependency],
path: path(for: xcResultScrapperDomain)
)
let domainTargetDependency: Target.Dependency = .target(name: xcResultScrapperDomain)

// MARK: Report
let xcresultScrapperReport = "XCResultScrapperReport"
let xcresultScrapperReportTarget: Target = .target(
name: xcresultScrapperReport,
dependencies: [swiftXML, domainTargetDependency],
path: path(for: xcresultScrapperReport)
)
let xcresultScrapperReportDependency: Target.Dependency = .target(name: xcresultScrapperReport)

// MARK: Core
let xcResultScrapper = "XCResultScrapperCore"
let scrapperTarget: Target = .target(
name: xcResultScrapper,
dependencies: [domainTargetDependency, utilsTargetDependency, xcresultScrapperReportDependency],
path: path(for: xcResultScrapper)
)
let scrapperTargetDependency: Target.Dependency = .target(name: xcResultScrapper)

// MARK: Client
let xcResultScrapperClient = "XCResultScrapperClient"
let scrapperClientTarget: Target = .executableTarget(
name: xcResultScrapperClient,
dependencies: [scrapperTargetDependency, argumentParser],
path: path(for: xcResultScrapperClient)
)

// MARK: - Manifest

let package = Package(
name: "XCResultScrapper",
products: [
.library(
name: "XCResultScrapper",
targets: [xcResultScrapper]
),
.executable(
name: xcResultScrapperClient,
targets: [xcResultScrapperClient]
)
],
dependencies: [
.package(url: "https://github.com/SergeyPetrachkov/SwiftyXML", branch: "master"),
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.2")
],
targets: [
utilsTarget,
domainTarget,
scrapperTarget,
xcresultScrapperReportTarget,
scrapperClientTarget,
.testTarget(
name: "XCResultScrapperTests",
dependencies: ["XCResultScrapperCore"]
),
]
)

// MARK: - Private helpers

func path(for target: String) -> String {
"Sources/\(target)"
}
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# XCResultScrapper

Read your xcresult, extract failed tests and failure reasons, list tests coverage per target and more.

## Currently available scenarios

`xcresultscrapper --path /path/to/your.xcresult --fetch-coverage true --output-path /path/to/your/output_directory/`

This will read through the XCResult, extract the data and prepare a markdown report with targets coverage and failed tests.

------------------------------------

`xcresultscrapper extract-swiftui-previews-coverage --path /path/to/your.xcresult --output-path /path/to/your/output_directory/`

This will produce an xml document with only SwiftUI previews lines per file.

------------------------------------

`xcresultscrapper coverage --path /path/to/your.xcresult --output-path /path/to/your/output_directory/`

This will produce an xml document with the full coverage data ignoring SwiftUI Previews code

------------------------------------

## Future plans

* Complete Junit integration
* Add tests
* Add docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import ArgumentParser
import XCResultScrapperCore
import XCResultScrapperReport

struct CombinedScrapperCommand: ParsableCommand {

static let configuration = CommandConfiguration(commandName: "scrap")

@Option(help: "Path to your xcresult file")
private var path: String

@Option(help: "Path to your reports. Optional. Will write xml/md files if provided.")
private var outputPath: String?

@Option(wrappedValue: false, help: "Specify if you want to fetch tests coverage")
private var fetchCoverage: Bool

@Option(help: "Report format. Available options: markdown, sonarqube, junit, console.")
private var format: ReportFormat = .markdown

func run() throws {

let testsScrapper = TestsScrapper(
scrapperConfigurator: .init(
xcresultPath: path,
outputPath: outputPath,
reportFormat: .markdown
)
)
try testsScrapper.main()

if fetchCoverage {
let coverageScrapper = CoverageScrapper(
scrapperConfigurator: .init(
xcresultPath: path,
outputPath: outputPath,
verbose: false,
reportFormat: format
)
)
try coverageScrapper.main()
}
}
}
30 changes: 30 additions & 0 deletions Sources/XCResultScrapperClient/Commands/CoverageCommand.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import ArgumentParser
import XCResultScrapperCore
import XCResultScrapperReport

struct CoverageCommand: ParsableCommand {
static let configuration = CommandConfiguration(
commandName: "coverage"
)

@Option(help: "Path to your xcresult file")
private var path: String

@Option(help: "Path to your reports. Will write xml file.")
private var outputPath: String

@Option(help: "Report format. Available options: markdown, sonarqube, junit, console.")
private var format: ReportFormat = .sonarqube

func run() throws {
let coverageScrapper = CoverageScrapper(
scrapperConfigurator: .init(
xcresultPath: path,
outputPath: outputPath,
verbose: true,
reportFormat: format
)
)
try coverageScrapper.main()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import ArgumentParser
import XCResultScrapperCore
import XCResultScrapperReport

struct SwiftUIPreviewsExtractorCommand: ParsableCommand {
static let configuration = CommandConfiguration(
commandName: "extract-swiftui-previews-coverage"
)

@Option(help: "Path to your xcresult file")
private var path: String

@Option(help: "Path to your reports. Will write xml file.")
private var outputPath: String

func run() throws {
let coverageScrapper = CoverageScrapper(
xcresultPath: path,
outputPath: outputPath,
reportRenderer: SonarQubeRenderer()
)
try coverageScrapper.extractSwiftUIPreviews(from: path)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import ArgumentParser
import XCResultScrapperCore

struct XCResultScrapperHostCommand: ParsableCommand {
static var configuration: CommandConfiguration = CommandConfiguration(
commandName: "xcresultscrapper",
subcommands: [
CombinedScrapperCommand.self,
SwiftUIPreviewsExtractorCommand.self,
CoverageCommand.self
],
defaultSubcommand: CombinedScrapperCommand.self
)
}
4 changes: 4 additions & 0 deletions Sources/XCResultScrapperClient/ReportFormat+CommandLine.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import enum XCResultScrapperReport.ReportFormat
import ArgumentParser

extension ReportFormat: ExpressibleByArgument {}
12 changes: 12 additions & 0 deletions Sources/XCResultScrapperClient/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Foundation

Thread {
print("Starting XCResultScrapper")
while true {
print("......")
Thread.sleep(forTimeInterval: 30)
}
}
.start()

XCResultScrapperHostCommand.main()
Loading

0 comments on commit ece32b0

Please sign in to comment.