{"id":13872178,"url":"https://github.com/rockbruno/SwiftInfo","last_synced_at":"2025-07-16T01:33:14.629Z","repository":{"id":34334964,"uuid":"176599382","full_name":"rockbruno/SwiftInfo","owner":"rockbruno","description":"📊 Extract and analyze the evolution of an iOS app's code.","archived":false,"fork":false,"pushed_at":"2023-03-10T14:24:39.000Z","size":2917,"stargazers_count":1150,"open_issues_count":21,"forks_count":58,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-11-12T14:44:25.946Z","etag":null,"topics":["analytics","cli","hacktoberfest","ios","swift","tools","xcode"],"latest_commit_sha":null,"homepage":"https://swiftrocks.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rockbruno.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-19T21:14:45.000Z","updated_at":"2024-11-02T18:03:19.000Z","dependencies_parsed_at":"2024-01-16T09:55:41.859Z","dependency_job_id":"ca544d2a-c80a-48a2-8ac0-322e3de318f3","html_url":"https://github.com/rockbruno/SwiftInfo","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockbruno%2FSwiftInfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockbruno%2FSwiftInfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockbruno%2FSwiftInfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockbruno%2FSwiftInfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rockbruno","download_url":"https://codeload.github.com/rockbruno/SwiftInfo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225824698,"owners_count":17529906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","cli","hacktoberfest","ios","swift","tools","xcode"],"created_at":"2024-08-05T23:00:35.899Z","updated_at":"2024-11-23T19:31:40.662Z","avatar_url":"https://github.com/rockbruno.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# 📊 SwiftInfo\n\n\u003cimg src=\"https://i.imgur.com/Y6z0xij.png\"\u003e\n\n[![GitHub release](https://img.shields.io/github/tag/rockbruno/SwiftInfo.svg)](https://github.com/rockbruno/SwiftInfo/releases)\n\n**Note: I don't intend to ship further updates to this tool.**\n\nSwiftInfo is a CLI tool that extracts, tracks and analyzes metrics that are useful for Swift apps. Besides the default tracking options that are shipped with the tool, you can also customize SwiftInfo to track pretty much anything that can be conveyed in a simple `.swift` script.\n\nBy default SwiftInfo will assume you're extracting info from a release build and send the final results to Slack, but it can be used to extract info from individual pull requests as well with the [danger-SwiftInfo](https://github.com/rockbruno/danger-SwiftInfo) [danger](https://github.com/danger/danger) plugin.\n\n\u003cimg src=\"https://i.imgur.com/8kvEx5O.png\"\u003e\n\n## Available Providers\n\n| **Type Name** | **Description** |\n|---|:---:|\n| **📦 IPASizeProvider**        | Size of the .ipa archive (not the App Store size!) |\n| **📊 CodeCoverageProvider**        | Code coverage percentage |\n| **👶 TargetCountProvider**        | Number of targets (dependencies) |\n| **🎯 TestCountProvider**        | Sum of all test target's test count |\n| **⚠️ WarningCountProvider**        | Number of warnings in a build |\n| **🧙‍♂️ OBJCFileCountProvider**        | Number of OBJ-C files and headers (for mixed OBJ-C / Swift projects) |\n| **⏰ LongestTestDurationProvider**        | The name and duration of the longest test |\n| **🛏 TotalTestDurationProvider**        | Time it took to build and run all tests |\n| **🖼 LargestAssetCatalogProvider**        | The name and size of the largest asset catalog |\n| **🎨 TotalAssetCatalogsSizeProvider**        | The sum of the size of all asset catalogs |\n| **💻 LinesOfCodeProvider**        | Executable lines of code |\n| **🚚 ArchiveDurationProvider**        | Time it took to build and archive the app |\n| **📷 LargestAssetProvider**        | The largest asset in the project. Only considers files inside asset catalogs. |\n\nEach provider may have a specific set of requirements in order for them to work. [Check their documentation to learn more](https://rockbruno.github.io/SwiftInfo/Structs.html).\n\n## Usage\n\nSwiftInfo extracts information by analyzing the logs that your build system generates when you build and/or test your app. Because it requires these logs to work, SwiftInfo is meant to be used alongside a build automation tool like [fastlane](https://github.com/fastlane/fastlane). The following topics describe how you can retrieve these logs and setup SwiftInfo itself.\n\nWe'll show how to get the logs first as you'll need them to configure SwiftInfo.\n\n**Note:** This repository contains an example project. Check it out to see the tool in action -- just go to the example project folder and run `make swiftinfo` in your terminal.\t\n\n### Retrieving raw logs with [fastlane](https://github.com/fastlane/fastlane)\n\nIf you use fastlane, you can expose raw logs to SwiftInfo by adding the `buildlog_path` argument to `scan` (test logs) and `gym` (build logs). Here's a simple example of a fastlane lane that runs tests, submits an archive to TestFlight and runs SwiftInfo (make sure to edit the folder paths to what's being used by your project):\n\n```ruby\ndesc \"Submits a new beta build and runs SwiftInfo\"\nlane :beta do\n  # Run tests, copying the raw logs to the project folder\n  scan(\n    scheme: \"MyScheme\",\n    buildlog_path: \"./build/tests_log\"\n  )\n\n  # Archive the app, copying the raw logs to the project folder and the .ipa to the /build folder\n  gym(\n    workspace: \"MyApp.xcworkspace\",\n    scheme: \"Release\",\n    output_directory: \"build\",\n    buildlog_path: \"./build/build_log\"\n  )\n\n  # Send to TestFlight\n  pilot(\n      skip_waiting_for_build_processing: true\n  )\n\n  # Run the CocoaPods version of SwiftInfo\n  sh(\"../Pods/SwiftInfo/bin/swiftinfo\")\n\n  # Commit and push SwiftInfo's output\n  sh(\"git add ../SwiftInfo-output/SwiftInfoOutput.json\")\n  sh(\"git commit -m \\\"[ci skip] Updating SwiftInfo Output JSON\\\"\")\n  push_to_git_remote\nend\n```\n\n### Retrieving raw logs manually\n\nAn alternative that doesn't require fastlane is to simply manually run `xcodebuild` / `xctest` and pipe the output to a file. We don't recommend doing this in a real project, but it can be useful if you just want to test the tool without having to setup fastlane.\n\n```\nxcodebuild -workspace ./Example.xcworkspace -scheme Example 2\u003e\u00261 | tee ./build/build_log/Example-Release.log\n```\n\n## Configuring SwiftInfo\n\nSwiftInfo itself is configured by creating a `Infofile.swift` file in your project's root. Here's an example one with a detailed explanation:\n\n```swift\nimport SwiftInfoCore\n\n// Use `FileUtils` to configure the path of your logs. \n// If you're retrieving them with fastlane and don't know what the name of the log files are going to be, \n// just run it once to have it create them.\n\nFileUtils.buildLogFilePath = \"./build/build_log/MyApp-MyConfig.log\"\nFileUtils.testLogFilePath = \"./build/tests_log/MyApp-MyConfig.log\"\n\n// Now, create a `SwiftInfo` instance by passing your project's information.\n\nlet projectInfo = ProjectInfo(xcodeproj: \"MyApp.xcodeproj\",\n                              target: \"MyTarget\",\n                              configuration: \"MyConfig\")\n\nlet api = SwiftInfo(projectInfo: projectInfo)\n\n// Use SwiftInfo's `extract()` method to extract and append all the information you want into a single property.\n\nlet output = api.extract(IPASizeProvider.self) +\n             api.extract(WarningCountProvider.self) +\n             api.extract(TestCountProvider.self) +\n             api.extract(TargetCountProvider.self, args: .init(mode: .complainOnRemovals)) +\n             api.extract(CodeCoverageProvider.self, args: .init(targets: [\"NetworkModule\", \"MyApp\"])) +\n             api.extract(LinesOfCodeProvider.self, args: .init(targets: [\"NetworkModule\", \"MyApp\"]))\n\n// Lastly, process the output.\n\nif isInPullRequestMode {\n    // If called from danger-SwiftInfo, print the results to the pull request\n    api.print(output: output)\n} else {\n    // If called manually, send the results to Slack...\n    api.sendToSlack(output: output, webhookUrl: url)\n    // ...and save the output to your repo so it serves as the basis for new comparisons.\n    api.save(output: output)\n}\n```\n\n## Saving and visualizing the data\n\nAfter successfully extracting data, you should call `api.save(output: output)` to have SwiftInfo add/update a json file in the `{Infofile path}/SwiftInfo-output` folder. It's important to add this file to version control after the running the tool as this is what SwiftInfo uses to compare new pieces of information.\n\nYou can then use [SwiftInfo-Reader](https://github.com/rockbruno/SwiftInfo-Reader) to transform this output into a more visual static HTML page.\n\n\u003cimg src=\"https://i.imgur.com/62jNGdh.png\"\u003e\n\n## Customizing Providers\n\nTo be able to support different types of projects, SwiftInfo provides customization options to some providers. See the documentation for each provider to see what it supports.\nIf you wish to track something that's not handled by the default providers, you can also create your own providers. [Click here to see how](CREATING_CUSTOM_PROVIDERS.md).\n\n## Customizing Runs\n\nAny arguments you pass to SwiftInfo can be inspected inside your Infofile. This allows you to pass any custom information you want to the binary and use it to customize your runs.\n\nFor example, if you run SwiftInfo by calling `swiftinfo --myCustomArgument`, you can use `ProcessInfo` to check for its presence inside your Infofile.\n\n```swift\nif ProcessInfo.processInfo.arguments.contains(\"--myCustomArgument\") {\n    print(\"Yay, custom arguments!\")\n}\n```\n\nIf the argument has a value, you can also fetch that value with `UserDefaults`.\n\n## Installation\n\n### CocoaPods\n\n`pod 'SwiftInfo'`\n\n### [Homebrew](https://brew.sh/)\n\nTo install SwiftInfo with Homebrew the first time, simply run these commands:\n\n```bash\nbrew tap rockbruno/SwiftInfo https://github.com/rockbruno/SwiftInfo.git\nbrew install rockbruno/SwiftInfo/swiftinfo\n```\n\nTo **update** to the newest Homebrew version of SwiftInfo when you have an old version already installed, run:\n\n```bash\nbrew upgrade swiftinfo\n```\n\n### Manually\n\nDownload the [latest release](https://github.com/rockbruno/SwiftInfo/releases) and unzip the contents somewhere in your project's folder.\n\n### Swift Package Manager\n\nSwiftPM is currently not supported due to the need of shipping additional files with the binary, which SwiftPM does not support. We might find a solution for this, but for now there's no way to use the tool with it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frockbruno%2FSwiftInfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frockbruno%2FSwiftInfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frockbruno%2FSwiftInfo/lists"}