├── .gitignore ├── .spi.yml ├── .swiftformat ├── CODE_OF_CONDUCT.md ├── LICENSE.txt ├── Package.swift ├── Package@swift-5.0.swift ├── Package@swift-5.1.swift ├── Package@swift-5.2.swift ├── Package@swift-5.3.swift ├── Package@swift-5.4.swift ├── Package@swift-5.5.swift ├── README.md ├── Sources └── CoreBaggage │ ├── Baggage.swift │ ├── BaggageKey.swift │ └── Docs.docc │ └── index.md ├── Tests ├── CoreBaggageTests │ ├── BaggageTests+XCTest.swift │ └── BaggageTests.swift └── LinuxMain.swift ├── docker ├── Dockerfile ├── docker-compose.1804.50.yaml ├── docker-compose.1804.51.yaml ├── docker-compose.1804.52.yaml ├── docker-compose.1804.53.yaml ├── docker-compose.2004.54.yaml ├── docker-compose.2004.55.yaml ├── docker-compose.2004.56.yaml ├── docker-compose.2004.57.yaml ├── docker-compose.2004.58.yaml ├── docker-compose.2204.59.yaml ├── docker-compose.2204.main.yaml └── docker-compose.yaml └── scripts ├── generate_docs.sh ├── generate_linux_tests.rb ├── preview_docc.sh ├── soundness.sh ├── validate_format.sh ├── validate_language.sh ├── validate_license_headers.sh └── validate_naming.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .SourceKitten 3 | Package.resolved 4 | /.build 5 | /Packages 6 | /*.xcodeproj 7 | xcuserdata/ 8 | .swiftpm 9 | -------------------------------------------------------------------------------- /.spi.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | builder: 3 | configs: 4 | - documentation_targets: [CoreBaggage] 5 | -------------------------------------------------------------------------------- /.swiftformat: -------------------------------------------------------------------------------- 1 | # file options 2 | 3 | --swiftversion 5.0 4 | --exclude .build 5 | --exclude UseCases/.build 6 | --exclude Tests/LinuxMain.swift 7 | --exclude **/*Tests+XCTest.swift 8 | 9 | # format options 10 | 11 | --ifdef no-indent 12 | --patternlet inline 13 | --self insert 14 | --stripunusedargs closure-only 15 | --wraparguments before-first 16 | 17 | # rules 18 | 19 | --disable blankLinesAroundMark 20 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at swifttracing@slashmo.codes. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.6 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /Package@swift-5.0.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | // no dependencies 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /Package@swift-5.1.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | // no dependencies 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /Package@swift-5.2.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | // no dependencies 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /Package@swift-5.3.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | // no dependencies 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /Package@swift-5.4.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | // no dependencies 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /Package@swift-5.5.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "swift-distributed-tracing-baggage-core", 6 | products: [ 7 | .library( 8 | name: "CoreBaggage", 9 | targets: [ 10 | "CoreBaggage", 11 | ] 12 | ), 13 | ], 14 | dependencies: [ 15 | // no dependencies 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CoreBaggage", 20 | dependencies: [] 21 | ), 22 | 23 | // ==== -------------------------------------------------------------------------------------------------------- 24 | // MARK: Tests 25 | 26 | .testTarget( 27 | name: "CoreBaggageTests", 28 | dependencies: [ 29 | "CoreBaggage", 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🧳 Distributed Tracing Baggage Core 2 | 3 | > 📔 **NOTE**: It is very unlikely that you want to depend on _this_ package itself. 4 | > 5 | > Most libraries and projects should depend on and use the https://github.com/apple/swift-distributed-tracing-baggage package instead, 6 | > unless avoiding the `SwiftLog` dependency is necessary. 7 | 8 | `Baggage` is a minimal (zero-dependency) context propagation container, intended to "carry" baggage items 9 | for purposes of cross-cutting tools to be built on top of it. 10 | 11 | It is modeled after the concepts explained in [W3C Baggage](https://w3c.github.io/baggage/) and the 12 | in the spirit of [Tracing Plane](https://cs.brown.edu/~jcmace/papers/mace18universal.pdf) 's "Baggage Context" type, 13 | although by itself it does not define a specific serialization format. 14 | 15 | Please refer to [Swift Distributed Tracing Baggage](https://github.com/apple/swift-distributed-tracing-baggage) 16 | and [Swift Distributed Tracing](https://github.com/apple/swift-distributed-tracing) for usage guides of this type. 17 | 18 | ## Dependency 19 | 20 | In order to depend on this library you can use the Swift Package Manager, and add the following dependency to your `Package.swift`: 21 | 22 | ```swift 23 | dependencies: [ 24 | .package( 25 | name: "swift-baggage-context-core", 26 | url: "https://github.com/apple/swift-distributed-tracing-baggage-core.git", 27 | from: "0.1.0" 28 | ) 29 | ] 30 | ``` 31 | 32 | and depend on the module in your target: 33 | 34 | ```swift 35 | targets: [ 36 | .target( 37 | name: "MyAwesomeApp", 38 | dependencies: [ 39 | "CoreBaggage", 40 | ] 41 | ), 42 | // ... 43 | ] 44 | ``` 45 | 46 | ## Usage 47 | 48 | Please refer to [Swift Distributed Tracing Baggage](https://github.com/apple/swift-distributed-tracing-baggage) for the intended usage, 49 | and detailed guidelines. 50 | 51 | Alternatively, please refer to the API documentation of the Baggage type. 52 | 53 | ## Contributing 54 | 55 | Please make sure to run the `./scripts/soundness.sh` script when contributing, it checks formatting and similar things. 56 | 57 | You can make ensure it always is run and passes before you push by installing a pre-push hook with git: 58 | 59 | ``` 60 | echo './scripts/soundness.sh' > .git/hooks/pre-push 61 | ``` 62 | -------------------------------------------------------------------------------- /Sources/CoreBaggage/Baggage.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Distributed Tracing Baggage open source project 4 | // 5 | // Copyright (c) 2020-2022 Apple Inc. and the Swift Distributed Tracing Baggage project authors 6 | // Licensed under Apache License v2.0 7 | // 8 | // See LICENSE.txt for license information 9 | // 10 | // SPDX-License-Identifier: Apache-2.0 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | // ==== ---------------------------------------------------------------------------------------------------------------- 15 | // MARK: Baggage 16 | 17 | /// A `Baggage` is a heterogeneous storage type with value semantics for keyed values in a type-safe fashion. 18 | /// 19 | /// Its values are uniquely identified via ``BaggageKey``s (by type identity). These keys also dictate the type of 20 | /// value allowed for a specific key-value pair through their associated type `Value`. 21 | /// 22 | /// ## Defining keys and accessing values 23 | /// Baggage keys are defined as types, most commonly case-less enums (as no actual instances are actually required) 24 | /// which conform to the ``BaggageKey`` protocol: 25 | /// 26 | /// private enum TestIDKey: Baggage.Key { 27 | /// typealias Value = String 28 | /// } 29 | /// 30 | /// While defining a key, one should also immediately declare an extension on `Baggage`, 31 | /// to allow convenient and discoverable ways to interact with the baggage item, the extension should take the form of: 32 | /// 33 | /// extension Baggage { 34 | /// var testID: String? { 35 | /// get { 36 | /// self[TestIDKey.self] 37 | /// } set { 38 | /// self[TestIDKey.self] = newValue 39 | /// } 40 | /// } 41 | /// } 42 | /// 43 | /// For consistency, it is recommended to name key types with the `...Key` suffix (e.g. `SomethingKey`) and the property 44 | /// used to access a value identifier by such key the prefix of the key (e.g. `something`). Please also observe the usual 45 | /// Swift naming conventions, e.g. prefer `ID` to `Id` etc. 46 | /// 47 | /// ## Usage 48 | /// Using a baggage container is fairly straight forward, as it boils down to using the prepared computed properties: 49 | /// 50 | /// var baggage = Baggage.topLevel 51 | /// // set a new value 52 | /// baggage.testID = "abc" 53 | /// // retrieve a stored value 54 | /// let testID = baggage.testID ?? "default" 55 | /// // remove a stored value 56 | /// baggage.testIDKey = nil 57 | /// 58 | /// Note that normally a baggage should not be "created" ad-hoc by user code, but rather it should be passed to it from 59 | /// a runtime. For example, when working in an HTTP server framework, it is most likely that the baggage is already passed 60 | /// directly or indirectly (e.g. in a `FrameworkContext`) 61 | /// 62 | /// ### Accessing all values 63 | /// 64 | /// The only way to access "all" values in a baggage context is by using the `forEach` function. 65 | /// The baggage container on purpose does not expose more functions to prevent abuse and treating it as too much of an 66 | /// arbitrary value smuggling container, but only make it convenient for tracing and instrumentation systems which need 67 | /// to access either specific or all items carried inside a baggage. 68 | public struct Baggage { 69 | public typealias Key = BaggageKey 70 | 71 | private var _storage = [AnyBaggageKey: Any]() 72 | 73 | /// Internal on purpose, please use ``Baggage/TODO(_:function:file:line:)`` or ``Baggage/topLevel`` to create an "empty" context, 74 | /// which carries more meaning to other developers why an empty context was used. 75 | init() {} 76 | } 77 | 78 | extension Baggage { 79 | /// Creates a new empty "top level" baggage, generally used as an "initial" baggage to immediately be populated with 80 | /// some values by a framework or runtime. Another use case is for tasks starting in the "background" (e.g. on a timer), 81 | /// which don't have a "request context" per se that they can pick up, and as such they have to create a "top level" 82 | /// baggage for their work. 83 | /// 84 | /// ## Usage in frameworks and libraries 85 | /// This function is really only intended to be used frameworks and libraries, at the "top-level" where a request's, 86 | /// message's or task's processing is initiated. For example, a framework handling requests, should create an empty 87 | /// context when handling a request only to immediately populate it with useful trace information extracted from e.g. 88 | /// request headers. 89 | /// 90 | /// ## Usage in applications 91 | /// Application code should never have to create an empty context during the processing lifetime of any request, 92 | /// and only should create contexts if some processing is performed in the background - thus the naming of this property. 93 | /// 94 | /// Usually, a framework such as an HTTP server or similar "request handler" would already provide users 95 | /// with a context to be passed along through subsequent calls. 96 | /// 97 | /// If unsure where to obtain a context from, prefer using `.TODO("Not sure where I should get a context from here?")`, 98 | /// in order to inform other developers that the lack of context passing was not done on purpose, but rather because either 99 | /// not being sure where to obtain a context from, or other framework limitations -- e.g. the outer framework not being 100 | /// baggage context aware just yet. 101 | public static var topLevel: Baggage { 102 | return Baggage() 103 | } 104 | } 105 | 106 | extension Baggage { 107 | /// A baggage intended as a placeholder until a real value can be passed through a function call. 108 | /// 109 | /// It should ONLY be used while prototyping or when the passing of the proper context is not yet possible, 110 | /// e.g. because an external library did not pass it correctly and has to be fixed before the proper context 111 | /// can be obtained where the TO-DO is currently used. 112 | /// 113 | /// ## Crashing on TO-DO context creation 114 | /// You may set the `BAGGAGE_CRASH_TODOS` variable while compiling a project in order to make calls to this function crash 115 | /// with a fatal error, indicating where a to-do baggage context was used. This comes in handy when wanting to ensure that 116 | /// a project never ends up using with code initially was written as "was lazy, did not pass context", yet the 117 | /// project requires context passing to be done correctly throughout the application. Similar checks can be performed 118 | /// at compile time easily using linters (not yet implemented), since it is always valid enough to detect a to-do context 119 | /// being passed as illegal and warn or error when spotted. 120 | /// 121 | /// ## Example 122 | /// 123 | /// let baggage = Baggage.TODO("The framework XYZ should be modified to pass us a context here, and we'd pass it along")) 124 | /// 125 | /// - Parameters: 126 | /// - reason: Informational reason for developers, why a placeholder context was used instead of a proper one, 127 | /// - Returns: Empty "to-do" baggage context which should be eventually replaced with a carried through one, or `background`. 128 | public static func TODO(_ reason: StaticString? = "", function: String = #function, file: String = #file, line: UInt = #line) -> Baggage { 129 | var context = Baggage.topLevel 130 | #if BAGGAGE_CRASH_TODOS 131 | fatalError("BAGGAGE_CRASH_TODOS: at \(file):\(line) (function \(function)), reason: \(reason)") 132 | #else 133 | context[TODOKey.self] = .init(file: file, line: line) 134 | return context 135 | #endif 136 | } 137 | 138 | private enum TODOKey: BaggageKey { 139 | typealias Value = TODOLocation 140 | static var nameOverride: String? { 141 | return "todo" 142 | } 143 | } 144 | } 145 | 146 | extension Baggage { 147 | /// Provides type-safe access to the baggage's values. 148 | /// This API should ONLY be used inside of accessor implementations. 149 | /// 150 | /// End users rather than using this subscript should use "accessors" the key's author MUST define, following this pattern: 151 | /// 152 | /// internal enum TestID: Baggage.Key { 153 | /// typealias Value = TestID 154 | /// } 155 | /// 156 | /// extension Baggage { 157 | /// public internal(set) var testID: TestID? { 158 | /// get { 159 | /// self[TestIDKey.self] 160 | /// } 161 | /// set { 162 | /// self[TestIDKey.self] = newValue 163 | /// } 164 | /// } 165 | /// } 166 | /// 167 | /// This is in order to enforce a consistent style across projects and also allow for fine grained control over 168 | /// who may set and who may get such property. Just access control to the Key type itself lacks such fidelity. 169 | /// 170 | /// Note that specific baggage and context types MAY (and usually do), offer also a way to set baggage values, 171 | /// however in the most general case it is not required, as some frameworks may only be able to offer reading. 172 | public subscript(_ key: Key.Type) -> Key.Value? { 173 | get { 174 | guard let value = self._storage[AnyBaggageKey(key)] else { return nil } 175 | // safe to force-cast as this subscript is the only way to set a value. 176 | return (value as! Key.Value) 177 | } 178 | set { 179 | self._storage[AnyBaggageKey(key)] = newValue 180 | } 181 | } 182 | 183 | /// Number of contained baggage items. 184 | public var count: Int { 185 | return self._storage.count 186 | } 187 | 188 | public var isEmpty: Bool { 189 | return self._storage.isEmpty 190 | } 191 | 192 | /// Calls the given closure for each item contained in the underlying `Baggage`. 193 | /// 194 | /// Order of those invocations is NOT guaranteed and should not be relied on. 195 | /// 196 | /// - Parameter body: A closure invoked with the type erased key and value stored for the key in this baggage. 197 | public func forEach(_ body: (AnyBaggageKey, Any) throws -> Void) rethrows { 198 | try self._storage.forEach { key, value in 199 | try body(key, value) 200 | } 201 | } 202 | } 203 | 204 | extension Baggage: CustomStringConvertible { 205 | /// A context's description prints only keys of the contained values. 206 | /// This is in order to prevent spilling a lot of detailed information of carried values accidentally. 207 | /// 208 | /// `Baggage`s are not intended to be printed "raw" but rather inter-operate with tracing, logging and other systems, 209 | /// which can use the `forEach` function providing access to its underlying values. 210 | public var description: String { 211 | return "\(type(of: self).self)(keys: \(self._storage.map { $0.key.name }))" 212 | } 213 | } 214 | 215 | /// Carried automatically by a "to do" baggage. 216 | /// It can be used to track where a context originated and which "to do" context must be fixed into a real one to avoid this. 217 | public struct TODOLocation { 218 | /// Source file location where the to-do `Baggage` was created 219 | public let file: String 220 | /// Source line location where the to-do `Baggage` was created 221 | public let line: UInt 222 | } 223 | -------------------------------------------------------------------------------- /Sources/CoreBaggage/BaggageKey.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Distributed Tracing Baggage open source project 4 | // 5 | // Copyright (c) 2020-2022 Apple Inc. and the Swift Distributed Tracing Baggage project authors 6 | // Licensed under Apache License v2.0 7 | // 8 | // See LICENSE.txt for license information 9 | // 10 | // SPDX-License-Identifier: Apache-2.0 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | /// `BaggageKey`s are used as keys in a ``Baggage``. Their associated type `Value` guarantees type-safety. 15 | /// To give your `BaggageKey` an explicit name you may override the `name` property. 16 | /// 17 | /// In general, `BaggageKey`s should be `internal` or `private` to the part of a system using it. 18 | /// 19 | /// All access to baggage items should be performed through an accessor computed property defined as shown below: 20 | /// 21 | /// /// The Key type should be internal (or private). 22 | /// enum TestIDKey: Baggage.Key { 23 | /// typealias Value = String 24 | /// static var nameOverride: String? { "test-id" } 25 | /// } 26 | /// 27 | /// extension Baggage { 28 | /// /// This is some useful property documentation. 29 | /// public internal(set) var testID: String? { 30 | /// get { 31 | /// self[TestIDKey.self] 32 | /// } 33 | /// set { 34 | /// self[TestIDKey.self] = newValue 35 | /// } 36 | /// } 37 | /// } 38 | /// 39 | /// This pattern allows library authors fine-grained control over which values may be set, and whic only get by end-users. 40 | public protocol BaggageKey { 41 | /// The type of `Value` uniquely identified by this key. 42 | associatedtype Value 43 | 44 | /// The human-readable name of this key. 45 | /// This name will be used instead of the type name when a value is printed. 46 | /// 47 | /// It MAY also be picked up by an instrument (from Swift Tracing) which serializes baggage items and e.g. used as 48 | /// header name for carried metadata. Though generally speaking header names are NOT required to use the nameOverride, 49 | /// and MAY use their well known names for header names etc, as it depends on the specific transport and instrument used. 50 | /// 51 | /// For example, a baggage key representing the W3C "trace-state" header may want to return "trace-state" here, 52 | /// in order to achieve a consistent look and feel of this baggage item throughout logging and tracing systems. 53 | /// 54 | /// Defaults to `nil`. 55 | static var nameOverride: String? { get } 56 | } 57 | 58 | extension BaggageKey { 59 | public static var nameOverride: String? { return nil } 60 | } 61 | 62 | /// A type-erased ``BaggageKey`` used when iterating through the ``Baggage`` using its `forEach` method. 63 | public struct AnyBaggageKey { 64 | /// The key's type represented erased to an `Any.Type`. 65 | public let keyType: Any.Type 66 | 67 | private let _nameOverride: String? 68 | 69 | /// A human-readable String representation of the underlying key. 70 | /// If no explicit name has been set on the wrapped key the type name is used. 71 | public var name: String { 72 | return self._nameOverride ?? String(describing: self.keyType.self) 73 | } 74 | 75 | init(_ keyType: Key.Type) where Key: BaggageKey { 76 | self.keyType = keyType 77 | self._nameOverride = keyType.nameOverride 78 | } 79 | } 80 | 81 | extension AnyBaggageKey: Hashable { 82 | public static func == (lhs: AnyBaggageKey, rhs: AnyBaggageKey) -> Bool { 83 | return ObjectIdentifier(lhs.keyType) == ObjectIdentifier(rhs.keyType) 84 | } 85 | 86 | public func hash(into hasher: inout Hasher) { 87 | hasher.combine(ObjectIdentifier(self.keyType)) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Sources/CoreBaggage/Docs.docc/index.md: -------------------------------------------------------------------------------- 1 | # ``CoreBaggage`` 2 | 3 | Baggage for context propagation. 4 | 5 | ## Overview 6 | 7 | > 📔 **NOTE**: It is very unlikely that you want to depend on _this_ package itself. 8 | > 9 | > Most libraries and projects should depend on and use the https://github.com/apple/swift-distributed-tracing-baggage package instead, 10 | > unless avoiding the `SwiftLog` dependency is necessary. 11 | 12 | ``Baggage`` is a minimal (zero-dependency) context propagation container, intended to "carry" baggage items 13 | for purposes of cross-cutting tools to be built on top of it. 14 | 15 | It is modeled after the concepts explained in [W3C Baggage](https://w3c.github.io/baggage/) and the 16 | in the spirit of [Tracing Plane](https://cs.brown.edu/~jcmace/papers/mace18universal.pdf) 's "Baggage Context" type, 17 | although by itself it does not define a specific serialization format. 18 | 19 | Please refer to [Swift Distributed Tracing Baggage](https://github.com/apple/swift-distributed-tracing-baggage) 20 | and [Swift Distributed Tracing](https://github.com/apple/swift-distributed-tracing) for usage guides of this type. 21 | 22 | ## Getting started 23 | 24 | In order to depend on this library you can use the Swift Package Manager, and add the following dependency to your `Package.swift`: 25 | 26 | ```swift 27 | dependencies: [ 28 | .package( 29 | name: "swift-baggage-context-core", 30 | url: "https://github.com/apple/swift-distributed-tracing-baggage-core.git", 31 | from: "0.1.0" 32 | ) 33 | ] 34 | ``` 35 | 36 | and depend on the module in your target: 37 | 38 | ```swift 39 | targets: [ 40 | .target( 41 | name: "MyAwesomeApp", 42 | dependencies: [ 43 | "CoreBaggage", 44 | ] 45 | ), 46 | // ... 47 | ] 48 | ``` 49 | 50 | ## Usage 51 | 52 | Please refer to [Swift Distributed Tracing Baggage](https://github.com/apple/swift-distributed-tracing-baggage) for the intended usage, 53 | and detailed guidelines. 54 | 55 | Alternatively, please refer to the API documentation of the ``Baggage`` type. 56 | -------------------------------------------------------------------------------- /Tests/CoreBaggageTests/BaggageTests+XCTest.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Distributed Tracing Baggage open source project 4 | // 5 | // Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 6 | // Licensed under Apache License v2.0 7 | // 8 | // See LICENSE.txt for license information 9 | // 10 | // SPDX-License-Identifier: Apache-2.0 11 | // 12 | //===----------------------------------------------------------------------===// 13 | // 14 | // BaggageTests+XCTest.swift 15 | // 16 | import XCTest 17 | /// 18 | /// NOTE: This file was generated by generate_linux_tests.rb 19 | /// 20 | /// Do NOT edit this file directly as it will be regenerated automatically when needed. 21 | /// 22 | 23 | extension BaggageTests { 24 | 25 | @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings") 26 | static var allTests : [(String, (BaggageTests) -> () throws -> Void)] { 27 | return [ 28 | ("testSubscriptAccess", testSubscriptAccess), 29 | ("testRecommendedConvenienceExtension", testRecommendedConvenienceExtension), 30 | ("testEmptyBaggageDescription", testEmptyBaggageDescription), 31 | ("testSingleKeyBaggageDescription", testSingleKeyBaggageDescription), 32 | ("testMultiKeysBaggageDescription", testMultiKeysBaggageDescription), 33 | ("test_todo_context", test_todo_context), 34 | ("test_topLevel", test_topLevel), 35 | ] 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Tests/CoreBaggageTests/BaggageTests.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Distributed Tracing Baggage open source project 4 | // 5 | // Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 6 | // Licensed under Apache License v2.0 7 | // 8 | // See LICENSE.txt for license information 9 | // 10 | // SPDX-License-Identifier: Apache-2.0 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | import CoreBaggage 15 | import XCTest 16 | 17 | final class BaggageTests: XCTestCase { 18 | func testSubscriptAccess() { 19 | let testID = 42 20 | 21 | var baggage = Baggage.topLevel 22 | XCTAssertNil(baggage[TestIDKey.self]) 23 | 24 | baggage[TestIDKey.self] = testID 25 | XCTAssertEqual(baggage[TestIDKey.self], testID) 26 | 27 | baggage[TestIDKey.self] = nil 28 | XCTAssertNil(baggage[TestIDKey.self]) 29 | } 30 | 31 | func testRecommendedConvenienceExtension() { 32 | let testID = 42 33 | 34 | var baggage = Baggage.topLevel 35 | XCTAssertNil(baggage.testID) 36 | 37 | baggage.testID = testID 38 | XCTAssertEqual(baggage.testID, testID) 39 | 40 | baggage[TestIDKey.self] = nil 41 | XCTAssertNil(baggage.testID) 42 | } 43 | 44 | func testEmptyBaggageDescription() { 45 | XCTAssertEqual(String(describing: Baggage.topLevel), "Baggage(keys: [])") 46 | } 47 | 48 | func testSingleKeyBaggageDescription() { 49 | var baggage = Baggage.topLevel 50 | baggage.testID = 42 51 | 52 | XCTAssertEqual(String(describing: baggage), #"Baggage(keys: ["TestIDKey"])"#) 53 | } 54 | 55 | func testMultiKeysBaggageDescription() { 56 | var baggage = Baggage.topLevel 57 | baggage.testID = 42 58 | baggage[SecondTestIDKey.self] = "test" 59 | 60 | let description = String(describing: baggage) 61 | XCTAssert(description.starts(with: "Baggage(keys: ["), "Was: \(description)") 62 | // use contains instead of `XCTAssertEqual` because the order is non-predictable (Dictionary) 63 | XCTAssert(description.contains("TestIDKey"), "Was: \(description)") 64 | XCTAssert(description.contains("ExplicitKeyName"), "Was: \(description)") 65 | } 66 | 67 | // ==== ------------------------------------------------------------------------------------------------------------ 68 | // MARK: Factories 69 | 70 | func test_todo_context() { 71 | // the to-do context can be used to record intentions for why a context could not be passed through 72 | let context = Baggage.TODO("#1245 Some other library should be adjusted to pass us context") 73 | _ = context // avoid "not used" warning 74 | } 75 | 76 | func test_topLevel() { 77 | let context = Baggage.topLevel 78 | _ = context // avoid "not used" warning 79 | } 80 | } 81 | 82 | private enum TestIDKey: Baggage.Key { 83 | typealias Value = Int 84 | } 85 | 86 | private extension Baggage { 87 | var testID: Int? { 88 | get { 89 | return self[TestIDKey.self] 90 | } 91 | set { 92 | self[TestIDKey.self] = newValue 93 | } 94 | } 95 | } 96 | 97 | private enum SecondTestIDKey: Baggage.Key { 98 | typealias Value = String 99 | 100 | static let nameOverride: String? = "ExplicitKeyName" 101 | } 102 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Distributed Tracing Baggage open source project 4 | // 5 | // Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 6 | // Licensed under Apache License v2.0 7 | // 8 | // See LICENSE.txt for license information 9 | // 10 | // SPDX-License-Identifier: Apache-2.0 11 | // 12 | //===----------------------------------------------------------------------===// 13 | // 14 | // LinuxMain.swift 15 | // 16 | import XCTest 17 | /// 18 | /// NOTE: This file was generated by generate_linux_tests.rb 19 | /// 20 | /// Do NOT edit this file directly as it will be regenerated automatically when needed. 21 | /// 22 | 23 | #if os(Linux) || os(FreeBSD) 24 | @testable import CoreBaggageTests 25 | 26 | // This protocol is necessary to we can call the 'run' method (on an existential of this protocol) 27 | // without the compiler noticing that we're calling a deprecated function. 28 | // This hack exists so we can deprecate individual tests which test deprecated functionality without 29 | // getting a compiler warning... 30 | protocol LinuxMainRunner { func run() } 31 | class LinuxMainRunnerImpl: LinuxMainRunner { 32 | @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings") 33 | func run() { 34 | XCTMain([ 35 | testCase(BaggageTests.allTests), 36 | ]) 37 | } 38 | } 39 | (LinuxMainRunnerImpl() as LinuxMainRunner).run() 40 | #endif 41 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG swift_version=5.0 2 | ARG ubuntu_version=bionic 3 | ARG base_image=swift:$swift_version-$ubuntu_version 4 | FROM $base_image 5 | # needed to do again after FROM due to docker limitation 6 | ARG swift_version 7 | ARG ubuntu_version 8 | 9 | # set as UTF-8 10 | RUN apt-get update && apt-get install -y locales locales-all 11 | ENV LC_ALL en_US.UTF-8 12 | ENV LANG en_US.UTF-8 13 | ENV LANGUAGE en_US.UTF-8 14 | 15 | # dependencies 16 | RUN apt-get update && apt-get install -y wget 17 | RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests 18 | 19 | # ruby for docs generation 20 | RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev 21 | 22 | # tools 23 | RUN mkdir -p $HOME/.tools 24 | RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile 25 | 26 | # swiftformat (until part of the toolchain) 27 | 28 | ARG swiftformat_version=0.44.6 29 | RUN git clone --branch $swiftformat_version --depth 1 https://github.com/nicklockwood/SwiftFormat $HOME/.tools/swift-format 30 | RUN cd $HOME/.tools/swift-format && swift build -c release 31 | RUN ln -s $HOME/.tools/swift-format/.build/release/swiftformat $HOME/.tools/swiftformat 32 | -------------------------------------------------------------------------------- /docker/docker-compose.1804.50.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:18.04-5.0 7 | build: 8 | args: 9 | ubuntu_version: "bionic" 10 | swift_version: "5.0" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:18.04-5.0 14 | 15 | shell: 16 | image: swift-distributed-tracing-baggage-core:18.04-5.0 17 | -------------------------------------------------------------------------------- /docker/docker-compose.1804.51.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:18.04-5.1 7 | build: 8 | args: 9 | ubuntu_version: "bionic" 10 | swift_version: "5.1" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:18.04-5.1 14 | environment: [] 15 | #- SANITIZER_ARG=--sanitize=thread 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:18.04-5.1 19 | -------------------------------------------------------------------------------- /docker/docker-compose.1804.52.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:18.04-5.2 7 | build: 8 | args: 9 | ubuntu_version: "bionic" 10 | swift_version: "5.2" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:18.04-5.2 14 | environment: [] 15 | #- SANITIZER_ARG=--sanitize=thread 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:18.04-5.2 19 | -------------------------------------------------------------------------------- /docker/docker-compose.1804.53.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:18.04-5.3 7 | build: 8 | args: 9 | ubuntu_version: "bionic" 10 | swift_version: "5.3" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:18.04-5.3 14 | environment: [] 15 | #- SANITIZER_ARG=--sanitize=thread 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:18.04-5.3 19 | -------------------------------------------------------------------------------- /docker/docker-compose.2004.54.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:20.04-5.4 7 | build: 8 | args: 9 | ubuntu_version: "focal" 10 | swift_version: "5.4" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:20.04-5.4 14 | environment: [] 15 | #- SANITIZER_ARG=--sanitize=thread 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:20.04-5.4 19 | -------------------------------------------------------------------------------- /docker/docker-compose.2004.55.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:20.04-5.5 7 | build: 8 | args: 9 | ubuntu_version: "focal" 10 | swift_version: "5.5" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:20.04-5.5 14 | environment: [] 15 | #- SANITIZER_ARG=--sanitize=thread 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:20.04-5.5 19 | -------------------------------------------------------------------------------- /docker/docker-compose.2004.56.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:20.04-5.6 7 | build: 8 | args: 9 | ubuntu_version: "focal" 10 | swift_version: "5.6" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:20.04-5.6 14 | environment: 15 | #- SANITIZER_ARG=--sanitize=thread 16 | - FORCE_TEST_DISCOVERY=--enable-test-discovery 17 | 18 | shell: 19 | image: swift-distributed-tracing-baggage-core:20.04-5.6 20 | -------------------------------------------------------------------------------- /docker/docker-compose.2004.57.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:20.04-5.7 7 | build: 8 | args: 9 | ubuntu_version: "focal" 10 | swift_version: "5.7" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:20.04-5.7 14 | environment: 15 | #- SANITIZER_ARG=--sanitize=thread 16 | - FORCE_TEST_DISCOVERY=--enable-test-discovery 17 | 18 | shell: 19 | image: swift-distributed-tracing-baggage-core:20.04-5.7 20 | -------------------------------------------------------------------------------- /docker/docker-compose.2004.58.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:20.04-5.8 7 | build: 8 | args: 9 | ubuntu_version: "focal" 10 | swift_version: "5.8" 11 | 12 | test: 13 | image: swift-distributed-tracing-baggage-core:20.04-5.8 14 | environment: 15 | #- SANITIZER_ARG=--sanitize=thread 16 | - FORCE_TEST_DISCOVERY=--enable-test-discovery 17 | 18 | shell: 19 | image: swift-distributed-tracing-baggage-core:20.04-5.8 20 | -------------------------------------------------------------------------------- /docker/docker-compose.2204.59.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:22.04-5.9 7 | build: 8 | args: 9 | base_image: "swiftlang/swift:nightly-5.9-jammy" 10 | 11 | test: 12 | image: swift-distributed-tracing-baggage-core:22.04-5.9 13 | environment: 14 | #- SANITIZER_ARG=--sanitize=thread 15 | - FORCE_TEST_DISCOVERY=--enable-test-discovery 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:22.04-5.9 19 | -------------------------------------------------------------------------------- /docker/docker-compose.2204.main.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | runtime-setup: 6 | image: swift-distributed-tracing-baggage-core:22.04-main 7 | build: 8 | args: 9 | base_image: "swiftlang/swift:nightly-main-jammy" 10 | 11 | test: 12 | image: swift-distributed-tracing-baggage-core:22.04-main 13 | environment: 14 | #- SANITIZER_ARG=--sanitize=thread 15 | - FORCE_TEST_DISCOVERY=--enable-test-discovery 16 | 17 | shell: 18 | image: swift-distributed-tracing-baggage-core:22.04-main 19 | -------------------------------------------------------------------------------- /docker/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | # this file is not designed to be run directly 2 | # instead, use the docker-compose.. files 3 | # eg docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.1804.50.yaml run test 4 | version: "3" 5 | 6 | services: 7 | 8 | runtime-setup: 9 | image: swift-distributed-tracing-baggage-core:default 10 | build: 11 | context: . 12 | dockerfile: Dockerfile 13 | 14 | common: &common 15 | image: swift-distributed-tracing-baggage-core:default 16 | depends_on: [runtime-setup] 17 | volumes: 18 | - ~/.ssh:/root/.ssh 19 | - ..:/code:z 20 | working_dir: /code 21 | cap_drop: 22 | - CAP_NET_RAW 23 | - CAP_NET_BIND_SERVICE 24 | 25 | soundness: 26 | <<: *common 27 | command: /bin/bash -xcl "./scripts/soundness.sh" 28 | 29 | docs: 30 | <<: *common 31 | environment: 32 | - CI 33 | command: /bin/bash -xcl "./scripts/generate_docs.sh" 34 | 35 | test: 36 | <<: *common 37 | command: /bin/bash -xcl "swift test -Xswiftc -warnings-as-errors $${FORCE_TEST_DISCOVERY-} $${SANITIZER_ARG-}" 38 | 39 | # util 40 | 41 | shell: 42 | <<: *common 43 | entrypoint: /bin/bash 44 | -------------------------------------------------------------------------------- /scripts/generate_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | set -e 16 | 17 | my_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 18 | declare -r root_path="$my_path/.." 19 | version=$(git describe --abbrev=0 --tags || echo "0.0.0") 20 | declare -r modules=(CoreBaggage) 21 | main_module="CoreBaggage" 22 | declare -r project_xcodeproj_name="swift-distributed-tracing-baggage-core" 23 | declare -r project_gh_name="swift-distributed-tracing-baggage-core" 24 | 25 | if [[ "$(uname -s)" == "Linux" ]]; then 26 | # build code if required 27 | if [[ ! -d "$root_path/.build/x86_64-unknown-linux-gnu" ]]; then 28 | swift build 29 | fi 30 | # setup source-kitten if required 31 | source_kitten_source_path="$root_path/.build/.SourceKitten" 32 | if [[ ! -d "$source_kitten_source_path" ]]; then 33 | git clone https://github.com/jpsim/SourceKitten.git "$source_kitten_source_path" 34 | fi 35 | source_kitten_path="$source_kitten_source_path/.build/x86_64-unknown-linux-gnu/debug" 36 | if [[ ! -d "$source_kitten_path" ]]; then 37 | rm -rf "$source_kitten_source_path/.swift-version" 38 | cd "$source_kitten_source_path" && swift build && cd "$root_path" 39 | fi 40 | # generate 41 | mkdir -p "$root_path/.build/sourcekitten" 42 | for module in "${modules[@]}"; do 43 | if [[ ! -f "$root_path/.build/sourcekitten/$module.json" ]]; then 44 | "$source_kitten_path/sourcekitten" doc --spm --module-name $module > "$root_path/.build/sourcekitten/$module.json" 45 | fi 46 | done 47 | fi 48 | 49 | [[ -d docs/$version ]] || mkdir -p docs/$version 50 | [[ -d "$project_xcodeproj_name.xcodeproj" ]] || swift package generate-xcodeproj 51 | 52 | # run jazzy 53 | if ! command -v jazzy > /dev/null; then 54 | gem install jazzy --no-ri --no-rdoc 55 | fi 56 | 57 | jazzy_dir="$root_path/.build/jazzy" 58 | rm -rf "$jazzy_dir" 59 | mkdir -p "$jazzy_dir" 60 | 61 | module_switcher="$jazzy_dir/README.md" 62 | jazzy_args=(--clean 63 | --author 'Swift Distributed Tracing team' 64 | --readme "$module_switcher" 65 | --author_url https://github.com/apple/$project_gh_name 66 | --github_url https://github.com/apple/$project_gh_name 67 | --github-file-prefix https://github.com/apple/$project_gh_name/tree/$version 68 | --theme fullwidth 69 | --xcodebuild-arguments -scheme,$project_xcodeproj_name-Package) 70 | cat > "$module_switcher" <<"EOF" 71 | # Swift Distributed Tracing Baggage Docs 72 | 73 | This project contains modules: 74 | EOF 75 | 76 | for module in "${modules[@]}"; do 77 | echo " - [$module](../$module/index.html)" >> "$module_switcher" 78 | done 79 | 80 | for module in "${modules[@]}"; do 81 | echo "processing $module" 82 | args=("${jazzy_args[@]}" --output "$jazzy_dir/docs/$version/$module" --docset-path "$jazzy_dir/docset/$version/$module" 83 | --module "$module" --module-version $version 84 | --root-url "https://apple.github.io/$project_gh_name/docs/$version/$module/") 85 | if [[ -f "$root_path/.build/sourcekitten/$module.json" ]]; then 86 | args+=(--sourcekitten-sourcefile "$root_path/.build/sourcekitten/$module.json") 87 | fi 88 | 89 | jazzy "${args[@]}" 90 | 91 | if [[ $(cat $root_path/.build/sourcekitten/$module.json) == "0" ]]; then 92 | echo "processing module $module ($root_path/.build/sourcekitten/$module.json) yielded EMPTY module json file!" 93 | exit 1 94 | fi 95 | done 96 | 97 | # push to github pages 98 | if [[ $PUSH == true ]]; then 99 | BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) 100 | GIT_AUTHOR=$(git --no-pager show -s --format='%an <%ae>' HEAD) 101 | git fetch origin +gh-pages:gh-pages 102 | git checkout gh-pages 103 | rm -rf "docs/$version" 104 | rm -rf "docs/current" 105 | cp -r "$jazzy_dir/docs/$version" docs/ 106 | cp -r "docs/$version" docs/current 107 | git add --all docs 108 | echo "" > index.html 109 | git add index.html 110 | touch .nojekyll 111 | git add .nojekyll 112 | changes=$(git diff-index --name-only HEAD) 113 | if [[ -n "$changes" ]]; then 114 | echo -e "changes detected\n$changes" 115 | git commit --author="$GIT_AUTHOR" -m "publish $version docs" 116 | git push origin gh-pages 117 | else 118 | echo "no changes detected" 119 | fi 120 | git checkout -f $BRANCH_NAME 121 | fi 122 | -------------------------------------------------------------------------------- /scripts/generate_linux_tests.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # 4 | # process_test_files.rb 5 | # 6 | # Copyright 2016 Tony Stone 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | # Created by Tony Stone on 5/4/16. 21 | # 22 | require 'getoptlong' 23 | require 'fileutils' 24 | require 'pathname' 25 | 26 | include FileUtils 27 | 28 | # 29 | # This ruby script will auto generate LinuxMain.swift and the +XCTest.swift extension files for Swift Package Manager on Linux platforms. 30 | # 31 | # See https://github.com/apple/swift-corelibs-xctest/blob/master/Documentation/Linux.md 32 | # 33 | def header(fileName) 34 | string = <<-eos 35 | //===----------------------------------------------------------------------===// 36 | // 37 | // This source file is part of the Swift Distributed Tracing Baggage open source project 38 | // 39 | // Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 40 | // Licensed under Apache License v2.0 41 | // 42 | // See LICENSE.txt for license information 43 | // 44 | // SPDX-License-Identifier: Apache-2.0 45 | // 46 | //===----------------------------------------------------------------------===// 47 | // 48 | // 49 | // 50 | import XCTest 51 | /// 52 | /// NOTE: This file was generated by generate_linux_tests.rb 53 | /// 54 | /// Do NOT edit this file directly as it will be regenerated automatically when needed. 55 | /// 56 | eos 57 | 58 | string 59 | .sub('', File.basename(fileName)) 60 | .sub('', Time.now.to_s) 61 | end 62 | 63 | def createExtensionFile(fileName, classes) 64 | extensionFile = fileName.sub! '.swift', '+XCTest.swift' 65 | print 'Creating file: ' + extensionFile + "\n" 66 | 67 | File.open(extensionFile, 'w') do |file| 68 | file.write header(extensionFile) 69 | file.write "\n" 70 | 71 | for classArray in classes 72 | file.write 'extension ' + classArray[0] + " {\n\n" 73 | file.write ' @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' +"\n" 74 | file.write ' static var allTests : [(String, (' + classArray[0] + ") -> () throws -> Void)] {\n" 75 | file.write " return [\n" 76 | 77 | for funcName in classArray[1] 78 | file.write ' ("' + funcName + '", ' + funcName + "),\n" 79 | end 80 | 81 | file.write " ]\n" 82 | file.write " }\n" 83 | file.write "}\n\n" 84 | end 85 | end 86 | end 87 | 88 | def createLinuxMain(testsDirectory, allTestSubDirectories, files) 89 | fileName = testsDirectory + '/LinuxMain.swift' 90 | print 'Creating file: ' + fileName + "\n" 91 | 92 | File.open(fileName, 'w') do |file| 93 | file.write header(fileName) 94 | file.write "\n" 95 | 96 | file.write "#if os(Linux) || os(FreeBSD)\n" 97 | for testSubDirectory in allTestSubDirectories.sort { |x, y| x <=> y } 98 | file.write ' @testable import ' + testSubDirectory + "\n" 99 | end 100 | file.write "\n" 101 | file.write "// This protocol is necessary to we can call the 'run' method (on an existential of this protocol)\n" 102 | file.write "// without the compiler noticing that we're calling a deprecated function.\n" 103 | file.write "// This hack exists so we can deprecate individual tests which test deprecated functionality without\n" 104 | file.write "// getting a compiler warning...\n" 105 | file.write "protocol LinuxMainRunner { func run() }\n" 106 | file.write "class LinuxMainRunnerImpl: LinuxMainRunner {\n" 107 | file.write ' @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' + "\n" 108 | file.write " func run() {\n" 109 | file.write " XCTMain([\n" 110 | 111 | testCases = [] 112 | for classes in files 113 | for classArray in classes 114 | testCases << classArray[0] 115 | end 116 | end 117 | 118 | for testCase in testCases.sort { |x, y| x <=> y } 119 | file.write ' testCase(' + testCase + ".allTests),\n" 120 | end 121 | file.write " ])\n" 122 | file.write " }\n" 123 | file.write "}\n" 124 | file.write "(LinuxMainRunnerImpl() as LinuxMainRunner).run()\n" 125 | file.write "#endif\n" 126 | end 127 | end 128 | 129 | def parseSourceFile(fileName) 130 | puts 'Parsing file: ' + fileName + "\n" 131 | 132 | classes = [] 133 | currentClass = nil 134 | inIfLinux = false 135 | inElse = false 136 | ignore = false 137 | 138 | # 139 | # Read the file line by line 140 | # and parse to find the class 141 | # names and func names 142 | # 143 | File.readlines(fileName).each do |line| 144 | if inIfLinux 145 | if /\#else/.match(line) 146 | inElse = true 147 | ignore = true 148 | else 149 | if /\#end/.match(line) 150 | inElse = false 151 | inIfLinux = false 152 | ignore = false 153 | end 154 | end 155 | else 156 | if /\#if[ \t]+os\(Linux\)/.match(line) 157 | inIfLinux = true 158 | ignore = false 159 | end 160 | end 161 | 162 | next if ignore 163 | # Match class or func 164 | match = line[/class[ \t]+[a-zA-Z0-9_]*(?=[ \t]*:[ \t]*XCTestCase)|func[ \t]+test[a-zA-Z0-9_]*(?=[ \t]*\(\))/, 0] 165 | if match 166 | 167 | if match[/class/, 0] == 'class' 168 | className = match.sub(/^class[ \t]+/, '') 169 | # 170 | # Create a new class / func structure 171 | # and add it to the classes array. 172 | # 173 | currentClass = [className, []] 174 | classes << currentClass 175 | else # Must be a func 176 | funcName = match.sub(/^func[ \t]+/, '') 177 | # 178 | # Add each func name the the class / func 179 | # structure created above. 180 | # 181 | currentClass[1] << funcName 182 | end 183 | end 184 | end 185 | classes 186 | end 187 | 188 | # 189 | # Main routine 190 | # 191 | # 192 | 193 | testsDirectory = 'Tests' 194 | 195 | options = GetoptLong.new(['--tests-dir', GetoptLong::OPTIONAL_ARGUMENT]) 196 | options.quiet = true 197 | 198 | begin 199 | options.each do |option, value| 200 | case option 201 | when '--tests-dir' 202 | testsDirectory = value 203 | end 204 | end 205 | rescue GetoptLong::InvalidOption 206 | end 207 | 208 | allTestSubDirectories = [] 209 | allFiles = [] 210 | 211 | Dir[testsDirectory + '/*'].each do |subDirectory| 212 | next unless File.directory?(subDirectory) 213 | directoryHasClasses = false 214 | Dir[subDirectory + '/*Test{s,}.swift'].each do |fileName| 215 | next unless File.file? fileName 216 | fileClasses = parseSourceFile(fileName) 217 | 218 | # 219 | # If there are classes in the 220 | # test source file, create an extension 221 | # file for it. 222 | # 223 | next unless fileClasses.count > 0 224 | createExtensionFile(fileName, fileClasses) 225 | directoryHasClasses = true 226 | allFiles << fileClasses 227 | end 228 | 229 | if directoryHasClasses 230 | allTestSubDirectories << Pathname.new(subDirectory).split.last.to_s 231 | end 232 | end 233 | 234 | # 235 | # Last step is the create a LinuxMain.swift file that 236 | # references all the classes and funcs in the source files. 237 | # 238 | if allFiles.count > 0 239 | createLinuxMain(testsDirectory, allTestSubDirectories, allFiles) 240 | end 241 | # eof 242 | -------------------------------------------------------------------------------- /scripts/preview_docc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2022 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | ##===----------------------------------------------------------------------===## 16 | ## 17 | ## This source file is part of the Swift Distributed Actors open source project 18 | ## 19 | ## Copyright (c) 2018-2019 Apple Inc. and the Swift Distributed Actors project authors 20 | ## Licensed under Apache License v2.0 21 | ## 22 | ## See LICENSE.txt for license information 23 | ## See CONTRIBUTORS.md for the list of Swift Distributed Actors project authors 24 | ## 25 | ## SPDX-License-Identifier: Apache-2.0 26 | ## 27 | ##===----------------------------------------------------------------------===## 28 | 29 | swift package --disable-sandbox preview-documentation --target $1 30 | -------------------------------------------------------------------------------- /scripts/soundness.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | set -eu 16 | here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 17 | 18 | printf "=> Checking linux tests... " 19 | FIRST_OUT="$(git status --porcelain)" 20 | ruby "$here/../scripts/generate_linux_tests.rb" > /dev/null 21 | SECOND_OUT="$(git status --porcelain)" 22 | if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then 23 | printf "\033[0;31mmissing changes!\033[0m\n" 24 | git --no-pager diff 25 | exit 1 26 | else 27 | printf "\033[0;32mokay.\033[0m\n" 28 | fi 29 | 30 | bash $here/validate_license_headers.sh 31 | bash $here/validate_language.sh 32 | bash $here/validate_format.sh 33 | bash $here/validate_naming.sh 34 | -------------------------------------------------------------------------------- /scripts/validate_format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | ##===----------------------------------------------------------------------===## 16 | ## 17 | ## This source file is part of the SwiftNIO open source project 18 | ## 19 | ## Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors 20 | ## Licensed under Apache License v2.0 21 | ## 22 | ## See LICENSE.txt for license information 23 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 24 | ## 25 | ## SPDX-License-Identifier: Apache-2.0 26 | ## 27 | ##===----------------------------------------------------------------------===## 28 | 29 | set -u 30 | 31 | # verify that swiftformat is on the PATH 32 | command -v swiftformat >/dev/null 2>&1 || { echo >&2 "'swiftformat' could not be found. Please ensure it is installed and on the PATH."; exit 1; } 33 | 34 | printf "=> Checking format\n" 35 | FIRST_OUT="$(git status --porcelain)" 36 | # swiftformat does not scale so we loop ourselves 37 | shopt -u dotglob 38 | find Sources/* Tests/* -type d | while IFS= read -r d; do 39 | printf " * checking $d... " 40 | out=$(swiftformat $d 2>&1) 41 | SECOND_OUT="$(git status --porcelain)" 42 | if [[ "$out" == *"error"*] && ["$out" != "*No eligible files" ]]; then 43 | printf "\033[0;31merror!\033[0m\n" 44 | echo $out 45 | exit 1 46 | fi 47 | if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then 48 | printf "\033[0;31mformatting issues!\033[0m\n" 49 | git --no-pager diff 50 | exit 1 51 | fi 52 | printf "\033[0;32mokay.\033[0m\n" 53 | done 54 | -------------------------------------------------------------------------------- /scripts/validate_language.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2021 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | set -eu 16 | 17 | printf "=> Checking for unacceptable language... " 18 | # This greps for unacceptable terminology. The square bracket[s] are so that 19 | # "git grep" doesn't find the lines that greps :). 20 | unacceptable_terms=( 21 | -e blacklis[t] 22 | -e whitelis[t] 23 | -e slav[e] 24 | -e sanit[y] 25 | ) 26 | if git grep --color=never -i "${unacceptable_terms[@]}" > /dev/null; then 27 | printf "\033[0;31mUnacceptable language found.\033[0m\n" 28 | git grep -i "${unacceptable_terms[@]}" 29 | exit 1 30 | fi 31 | printf "\033[0;32mokay.\033[0m\n" 32 | -------------------------------------------------------------------------------- /scripts/validate_license_headers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2020-2022 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | ##===----------------------------------------------------------------------===## 16 | ## 17 | ## This source file is part of the SwiftNIO open source project 18 | ## 19 | ## Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors 20 | ## Licensed under Apache License v2.0 21 | ## 22 | ## See LICENSE.txt for license information 23 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 24 | ## 25 | ## SPDX-License-Identifier: Apache-2.0 26 | ## 27 | ##===----------------------------------------------------------------------===## 28 | 29 | set -eu 30 | here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 31 | 32 | function replace_acceptable_years() { 33 | # this needs to replace all acceptable forms with 'YEARS' 34 | sed -e 's/20[12][901]-202[012]/YEARS/' -e 's/2019/YEARS/' -e 's/202[012]/YEARS/' 35 | } 36 | 37 | printf "=> Checking license headers\n" 38 | tmp=$(mktemp /tmp/.swift-baggage-context-soundness_XXXXXX) 39 | 40 | for language in swift-or-c bash dtrace; do 41 | printf " * $language... " 42 | declare -a matching_files 43 | declare -a exceptions 44 | expections=( ) 45 | matching_files=( -name '*' ) 46 | case "$language" in 47 | swift-or-c) 48 | exceptions=( -name Package.swift -o -name 'Package@*.swift' ) 49 | matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' ) 50 | cat > "$tmp" <<"EOF" 51 | //===----------------------------------------------------------------------===// 52 | // 53 | // This source file is part of the Swift Distributed Tracing Baggage open source project 54 | // 55 | // Copyright (c) YEARS Apple Inc. and the Swift Distributed Tracing Baggage project authors 56 | // Licensed under Apache License v2.0 57 | // 58 | // See LICENSE.txt for license information 59 | // 60 | // SPDX-License-Identifier: Apache-2.0 61 | // 62 | //===----------------------------------------------------------------------===// 63 | EOF 64 | ;; 65 | bash) 66 | matching_files=( -name '*.sh' ) 67 | cat > "$tmp" <<"EOF" 68 | #!/bin/bash 69 | ##===----------------------------------------------------------------------===## 70 | ## 71 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 72 | ## 73 | ## Copyright (c) YEARS Apple Inc. and the Swift Distributed Tracing Baggage project authors 74 | ## Licensed under Apache License v2.0 75 | ## 76 | ## See LICENSE.txt for license information 77 | ## 78 | ## SPDX-License-Identifier: Apache-2.0 79 | ## 80 | ##===----------------------------------------------------------------------===## 81 | EOF 82 | ;; 83 | dtrace) 84 | matching_files=( -name '*.d' ) 85 | cat > "$tmp" <<"EOF" 86 | #!/usr/sbin/dtrace -q -s 87 | /*===----------------------------------------------------------------------===* 88 | * 89 | * This source file is part of the Swift Distributed Tracing Baggage open source project 90 | * 91 | * Copyright (c) YEARS Apple Inc. and the Swift Distributed Tracing Baggage project authors 92 | * Licensed under Apache License v2.0 93 | * 94 | * See LICENSE.txt for license information 95 | * 96 | * SPDX-License-Identifier: Apache-2.0 97 | * 98 | *===----------------------------------------------------------------------===*/ 99 | EOF 100 | ;; 101 | *) 102 | echo >&2 "ERROR: unknown language '$language'" 103 | ;; 104 | esac 105 | 106 | expected_lines=$(cat "$tmp" | wc -l) 107 | expected_sha=$(cat "$tmp" | shasum) 108 | 109 | ( 110 | cd "$here/.." 111 | find . \ 112 | \( \! -path './.build/*' -a \ 113 | \( "${matching_files[@]}" \) -a \ 114 | \( \! \( "${exceptions[@]}" \) \) \) | while read line; do 115 | if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then 116 | printf "\033[0;31mmissing headers in file '$line'!\033[0m\n" 117 | diff -u <(cat "$line" | replace_acceptable_years | head -n $expected_lines) "$tmp" 118 | exit 1 119 | fi 120 | done 121 | printf "\033[0;32mokay.\033[0m\n" 122 | ) 123 | done 124 | 125 | rm "$tmp" 126 | -------------------------------------------------------------------------------- /scripts/validate_naming.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the Swift Distributed Tracing Baggage open source project 5 | ## 6 | ## Copyright (c) 2020 Apple Inc. and the Swift Distributed Tracing Baggage project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## 11 | ## SPDX-License-Identifier: Apache-2.0 12 | ## 13 | ##===----------------------------------------------------------------------===## 14 | 15 | ##===----------------------------------------------------------------------===## 16 | ## 17 | ## This source file is part of the SwiftNIO open source project 18 | ## 19 | ## Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors 20 | ## Licensed under Apache License v2.0 21 | ## 22 | ## See LICENSE.txt for license information 23 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 24 | ## 25 | ## SPDX-License-Identifier: Apache-2.0 26 | ## 27 | ##===----------------------------------------------------------------------===## 28 | 29 | printf "=> Checking for unacceptable language... " 30 | # This greps for unacceptable terminology. The square bracket[s] are so that 31 | # "git grep" doesn't find the lines that greps :). 32 | unacceptable_terms=( 33 | -e blacklis[t] 34 | -e whitelis[t] 35 | -e slav[e] 36 | ) 37 | if git grep --color=never -i "${unacceptable_terms[@]}" > /dev/null; then 38 | printf "\033[0;31mUnacceptable language found.\033[0m\n" 39 | git grep -i "${unacceptable_terms[@]}" 40 | exit 1 41 | fi 42 | printf "\033[0;32mokay.\033[0m\n" 43 | --------------------------------------------------------------------------------