{"id":13995366,"url":"https://github.com/americanexpress/xcprojectlint","last_synced_at":"2025-04-04T20:10:56.727Z","repository":{"id":47322153,"uuid":"132954924","full_name":"americanexpress/xcprojectlint","owner":"americanexpress","description":"A security blanket for Xcode project files","archived":false,"fork":false,"pushed_at":"2024-03-12T07:12:01.000Z","size":255,"stargazers_count":505,"open_issues_count":9,"forks_count":19,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-03-28T19:07:39.756Z","etag":null,"topics":["xcode","xcode-lint"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/americanexpress.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-10T21:12:35.000Z","updated_at":"2024-11-26T17:53:13.000Z","dependencies_parsed_at":"2024-11-10T13:12:16.840Z","dependency_job_id":"b6795d03-d437-4963-8953-fee506565f0c","html_url":"https://github.com/americanexpress/xcprojectlint","commit_stats":{"total_commits":92,"total_committers":14,"mean_commits":6.571428571428571,"dds":0.5760869565217391,"last_synced_commit":"e0f3d9383d8f56d76b5b1dd9819f1ba32a3b3bc1"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/americanexpress%2Fxcprojectlint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/americanexpress%2Fxcprojectlint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/americanexpress%2Fxcprojectlint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/americanexpress%2Fxcprojectlint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/americanexpress","download_url":"https://codeload.github.com/americanexpress/xcprojectlint/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242678,"owners_count":20907134,"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":["xcode","xcode-lint"],"created_at":"2024-08-09T14:03:22.128Z","updated_at":"2025-04-04T20:10:56.705Z","avatar_url":"https://github.com/americanexpress.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# Xcode Project Linter (xcprojectlint)\n\n## Overview\n\nThis project provides a security blanket, ensuring neither your co-workers, nor\ngit screw up your Xcode project file. Some of the settings are arguably a matter\nof personal taste. Fortunately, each option can be enabled separately. `xcprojectlint`\ncurrently supports these checks:\n\n- `build-settings-externalized`\n\n    This mode ensures there are no settings configured at the project level,\n    instead encouraging the use of xcconfig files.\n    \n- `dangling-source-files`\n    \n    Ensures all source code files are members of a target.\n\n- `disk-layout-matches-project`\n\n    This mode ensures the project references reflect actual file system\n    locations. There are some occasions where you may not be able to exactly map\n    a folder to disk (Frameworks and Products are common examples). For this,\n    there is an additional parameter you can pass: `--skip-folders`, followed by\n    a list of folders to ignore.\n\n- `files-exist-on-disk`\n\n    This mode finds file references in the project which are not backed by files.\n\n- `empty-groups`\n\n    This mode reports groups that contain no additional items.\n\n- `items-in-alpha-order`\n\n    This mode ensures the project files and folders are in proper order. \n    There are some occasions where you may not be able to exactly sort items\n    in specific folders (Frameworks and Products are common examples). For this,\n    there is an additional parameter you can pass: `--skip-folders`, followed by\n    a list of folders to ignore.\n\n- `no-white-space-specifications`\n\n    This mode ensures that no file or project contains whitespace specifications of:\n    indentWidth, tabWidth, usesTabs, or lineEnding.\n\n- `all`\n\n    For convenience, this mode runs all of the above tests.\n\nWhen a failing condition is detected, as much useful context as possible is\nemitted to `STDOUT`, enabling Xcode to display the errors, in place. Further, it\noptionally can return `EX_SOFTWARE`, preventing the build from succeeding until\nthe problem is addressed.\n\n## Building the Code\n\nTo build `xcprojectlint` tool, run\n\n``` bash\n$ swift package update\n$ make build\n```\n\nTo work with the projects and tests in Xcode, run\n\n``` bash\n$ xed .\n```\n\n## Usage Examples\n\nas a build script phase:\n\n``` bash\nbin/xcprojectlint --report error --validations all --project $PROJECT_FILE_PATH\n```\n\nas a shell command:\n\n``` bash\nxcprojectlint --report error --validations files-exist-on-disk items-in-alpha-order\n--project /tmp/Example/Example.xcproject\n```\n\n## The Nitty Gritty\n\n`xcprojectlint` is operating on an undocumented file format. Years of looking at broken\ngit merges has given us a reasonable confidence that we know how the parts all\nwork together. That said, it is still a best guess, so there may be oversights.\nFortunately, these linting operations are read-only, and will not modify your\nproject file.\n\nEach run starts by parsing the project file into a series of collections, which\nrepresent our understanding of how a project file is composed. It uses both the\nproperty list structure, and the comments Xcode writes into the project to\nassemble its data. Afterwards, xcprojectlint applies validity tests to the extracted\ncollections, ensuring that the rules specified are met.\n\n## Clues to Fix By\n\nAs much as possible, xcprojectlint will attempt to tell you how to locate the problem.\nIt’ll tell you which build configuration has settings, what the expected order\nof a group is, and whatever else it can squeeze out of the available context.\nSometimes, it’ll even tell you the line number in the project file to look at.\nThis is great, but *do not attempt to view the project within Xcode.* Terrible,\nterrible things will happen. Instead, use your favorite text editor to peer\ninside.\n\n## The Rules\n\n- Build Settings Externalized\n\n    We iterate all the `BuildConfiguration` blobs, and investigate their\n    `BuildSettings` entry. Empty settings are A-OK. Any found settings are in\n    error.\n\n- Dangling Source Files\n\n    Iterating through all the source files that appear in the Project Navigator of\n    a project file, and ensures all are associated with a target within the same\n    project/workspace. Any dangling files found will result in an error. This is\n    particularly useful for test files.\n\n- Disk Layout Matches Project\n\n    This test grabs the `MainGroup` out of the project, then recursively\n    traverses the children. If the child node is a file, we retrieve the\n    `FileReference` by id, then check for a `name` value. The presence of a name\n    indicates this file reference does not have a matching file on disk.\n\n- Files Exist on Disk\n\n    This uses a similar recursion to the Layout test, but instead of\n    investigating the `name` value, it builds a URL to where the file should\n    appear on disk. This is done by assembling the path that led to the file,\n    then appending that to a path derived from the project’s path on disk, then\n    finally testing for the presence of a file at that location.\n\n- Empty Groups\n\n    One of the simpler tests. We again recurse the `MainGroup`, but this time\n    look for entries that have zero children.\n\n- Items in Alpha Order\n\n    We expect our project nodes to contain alphabetized Folders, followed by\n    alphabetized files. We check on that by again recursing the groups, and at\n    each level sifting the entries into `groupNames`, `fileNames`, and\n    `allNames`. We sort the groups and files, contatenate them, then compare\n    that to the list of everything.\n\n- No White Space Specifications\n\n    Xcode has a way to, at the user-level, specify custom settings for tabs, spaces,\n    indentation amount, and line endings within `Preferences -\u003e Text Editing -\u003e\n    Indentation`.  Formatting preferences can also be set at a file or project level,\n    altering the experience for team-members if passed through PR unnoticed.  This\n    rule aims to alieviate the existence of any whitespace specification and provides\n    the appropriate messages for each and their location within the project file.\n\n## Contributing\n\nWe welcome your interest in the American Express Open Source Community on Github.\nAny contributor to any Open Source Project managed by the American Express Open\nSource Community must accept and sign an agreement indicating agreement to the\nterms below. Except for the rights granted in this agreement to American Express\nand to recipients of software distributed by American Express, You reserve all\nright, title, and interest, if any, in and to your contributions. Please [fill\nout the agreement](https://cla-assistant.io/americanexpress/xcprojectlint).\n\nPlease feel free to open pull requests.  Before submitting a PR, please run your\ncode through `swiftformat` with the config file provided:\n`swiftformat --config swiftformat.config Sources/ Tests/`\n\n## License\n\nAny contributions made under this project will be governed by the [Apache License\n2.0](./LICENSE.txt).\n\n## Code of Conduct\n\nThis project adheres to the [American Express Community\nGuidelines](./CODE_OF_CONDUCT.md).\nBy participating, you are expected to honor these guidelines.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famericanexpress%2Fxcprojectlint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famericanexpress%2Fxcprojectlint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famericanexpress%2Fxcprojectlint/lists"}