├── .circleci └── config.yml ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── cococo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved └── xcshareddata │ └── xcschemes │ ├── cococo.xcscheme │ └── cococoLibrary.xcscheme ├── cococo ├── Cli.swift └── main.swift ├── cococoLibrary ├── Bash.swift ├── Converter.swift ├── IO.swift └── XMLEscaper.swift ├── cococoLibraryTests ├── Assets │ ├── Example.xcresult │ │ ├── Data │ │ │ ├── data.0~-_8T-OEcNdhNpew23wZ1ZB7LgoiZPincZVDUFRQy387NyUQwImjY_xrgx8FMFiN2ySYVHX3aYyZ3C4EdTcQphA== │ │ │ ├── data.0~-qtwNp_f2fZo_-ax58Um1nBOqq_LawMVrHsxkHl3sadhvHaKZnODnZCWKpoquAH6Vf0PkeJwUW9m4yq0Wiguyg== │ │ │ ├── data.0~24sw3mMVu0yiZqYlmUscqy9CMHTOJT9PXCqC1XYlhqeOtmN-b-LVlSyTWQQZWphu_s6HSqSAe1jV10p_3rM-vw== │ │ │ ├── data.0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g== │ │ │ ├── data.0~50zlzOBEe6Cggikt3hzMlOoqNy0Meu30qJuV2Atupzh-yUUNGc6t3DnmQGDsepvnUItUjQEcQrH3omfmHAlddg== │ │ │ ├── data.0~6NUkuq5en2H9TIGnPhxm_XI1mTyGbp0mk2xmlGFS_fE1w83m-s0eaAgzT8jLavDVsomSV_fj3gyEeNz8-l-0AQ== │ │ │ ├── data.0~7f9IXX-kICx4FpA_jCXfMN3T08MzcfpJPwzSE-n0RbJq0p4hxnOwjikwCbtaAhHizMMskKlJlSABi-XFz0jKcg== │ │ │ ├── data.0~94NzaW5woF3BNyOqqO5h7zYhCpT07MiSMMoxX6UKCSHls-vMuhwbQYXqafiT24bg3H0z1Yo3ipuEbGDScBzgMw== │ │ │ ├── data.0~Fj0rfCSRA48VhQeVbAmTtZ604Np3pmc3onOZo6caSAtdAZuHhRYHwV8OW6W_jfZeZvYUJYiM4I1rfgm2leBryw== │ │ │ ├── data.0~G68qXmZVzZXiHq_T2TlEzOiM8RWBNp319rR966JqSeWnlS5tvNi1ZnsHs0X6MM1Nqt8lT2PGce0VBQEZGEPWDw== │ │ │ ├── data.0~SLeLt8lKVQCChtgVef_SA3X4FpyKn2Oogk9YHpVbChFyzoOO3kTi3lsAHg5HUTdtO-52Kom1sv1YFBuYe83X9A== │ │ │ ├── data.0~U-MMVGlo6VNjyI9x3g9-HsSrRB4iLjo-Ss1ma8FuydvBPbrRuTeOsnl678_GHdBv7qKb40vbODYiXixRHaL4cg== │ │ │ ├── data.0~UqU2a4503F4gImKaTQC3-NvC-hvKwXLLKn2jvU777iA5u2wnpWfRvhQcXfk7BNfemW2tB-vHEzEmsv2yxTvbSw== │ │ │ ├── data.0~V5N20g2tbfNtC6P_FOmeIJzg9OaMCjCPtB1sE1SsOq9GEEOnP3yh_eCLeqJy7teeZYU3Uq8jWbqqnJ3zpJWVqQ== │ │ │ ├── data.0~XFNRKtSxJZ8r0lwLSEqTziyzqR8_7d5BblTSp4ItyJFPvDRGVaUec4oekqfCXJEVO9a6ujXmBsjlCrwHWNuIgA== │ │ │ ├── data.0~Y0VetVEvhnBc2qz8RJCUYcL842qfqvSevY8OB-wcQvAP_H4On3JScWWWn6uPGt-810JiN5qqaNQg4oRO0-jpDw== │ │ │ ├── data.0~YrizJ0L-df_j4QZQ4ML2mZIil7N8h1aB8MleOBoyrf_r1l8CwpYwivatCeSvqbBf05A_-UQlAV1xT2qMeC-VVg== │ │ │ ├── data.0~aQuuYLb-TKyYZtcAWj6Fx63Y1DomF-ssVZor3npByulK0GATZfYViD8JboHNjz6BwV0xbcVp7R0yt6OYVrTFMQ== │ │ │ ├── data.0~cPmsKVMixUukUBjUrD2QkE7mOethVpIPNH_RUshp-3qj1X7zIPv6PzNpo_evtT1HGn1vyZ5Nc9n2wliy4HBfzQ== │ │ │ ├── data.0~cm12k-Ps7aJ4GrJt7wyuRj8XNsiWydV7wx4SMBnv0HCA8tsaQSL0gtrryRqtR-1t5Zvk3SzNhSG5DSvj84X75Q== │ │ │ ├── data.0~fnScc6uwLeUOtP1wtZlnqtFmvEGAllShITIhX3BeZgyOFeOB2gl5_o449t_l-eg3Qi421YTdEshk3I9x0ZOCGg== │ │ │ ├── data.0~gsDKNmFTosKDqM22lZ1qRkVmAfnfo0oULz3_43S_9WPMFZIycyK38DKyUVr5CqpYYHsR7ACb4ptkTgpAwmqOBg== │ │ │ ├── data.0~juhI1raJ5S700ABcImgZVK-YOVPZ8e4gO3uZCVa0C1l34a18auJLksa8Hj6d8yZwSpB-05wwBB0vDxNP-JCZZA== │ │ │ ├── data.0~oKjVlRvWisdmloxst_ebPvfm1egBj903jOxknh_ZmlJJiktpEA3NkCUU1-ovPZQPFbpIKHXAnvBzTFfPB6ZzhQ== │ │ │ ├── data.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA== │ │ │ ├── data.0~p6GGgLAcpnkTXmB_i0bgIdxUy1UY07e5xHTA1r_zNkzMe_CK5w9WUbIq9lm9MtSPEaQT8LAoflr6rpKsu5_PnA== │ │ │ ├── data.0~qd9e6ooeKrMz43BCHtdlFtGqUm29HTUedZV34c6zJC_2Yo3KjW8IR398N7y6SmofRF93y4GvY9QW5YuFdo8wZg== │ │ │ ├── data.0~rlyQM6UGPphiQJf3tw_DH-YdR9H1fREkapmc4-sI_JwVXqKPOXUgcgyM1SqgFvw1ItJb8k3VdNKCFwpsNFY10g== │ │ │ ├── data.0~tFDRQK08gMZAKbFKrDwZPg17dEe4Fcef4Wfh0Ui7F653X9zGL1xbAGp7w3Uzb4hb73cy-PzWFJzgVxZiRiXO8w== │ │ │ ├── data.0~tta5TbL6EQkBtFy54Qdw7uKPBlHi7NMWXXwtEsYlPz5AQCtEwWUVd1xkCOJA60KgRr5N4gimH2yp54_QiE0Jfg== │ │ │ ├── data.0~wwEG-hauljIcgt3ZtMdcQfbmdDVGUzs2boUcNrlJ4kEWkqgFzw4FRJLQbfGZV_x8NUOqaPD54BkdPBdIivQprQ== │ │ │ ├── refs.0~-_8T-OEcNdhNpew23wZ1ZB7LgoiZPincZVDUFRQy387NyUQwImjY_xrgx8FMFiN2ySYVHX3aYyZ3C4EdTcQphA== │ │ │ ├── refs.0~-qtwNp_f2fZo_-ax58Um1nBOqq_LawMVrHsxkHl3sadhvHaKZnODnZCWKpoquAH6Vf0PkeJwUW9m4yq0Wiguyg== │ │ │ ├── refs.0~24sw3mMVu0yiZqYlmUscqy9CMHTOJT9PXCqC1XYlhqeOtmN-b-LVlSyTWQQZWphu_s6HSqSAe1jV10p_3rM-vw== │ │ │ ├── refs.0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g== │ │ │ ├── refs.0~50zlzOBEe6Cggikt3hzMlOoqNy0Meu30qJuV2Atupzh-yUUNGc6t3DnmQGDsepvnUItUjQEcQrH3omfmHAlddg== │ │ │ ├── refs.0~6NUkuq5en2H9TIGnPhxm_XI1mTyGbp0mk2xmlGFS_fE1w83m-s0eaAgzT8jLavDVsomSV_fj3gyEeNz8-l-0AQ== │ │ │ ├── refs.0~7f9IXX-kICx4FpA_jCXfMN3T08MzcfpJPwzSE-n0RbJq0p4hxnOwjikwCbtaAhHizMMskKlJlSABi-XFz0jKcg== │ │ │ ├── refs.0~94NzaW5woF3BNyOqqO5h7zYhCpT07MiSMMoxX6UKCSHls-vMuhwbQYXqafiT24bg3H0z1Yo3ipuEbGDScBzgMw== │ │ │ ├── refs.0~Fj0rfCSRA48VhQeVbAmTtZ604Np3pmc3onOZo6caSAtdAZuHhRYHwV8OW6W_jfZeZvYUJYiM4I1rfgm2leBryw== │ │ │ ├── refs.0~G68qXmZVzZXiHq_T2TlEzOiM8RWBNp319rR966JqSeWnlS5tvNi1ZnsHs0X6MM1Nqt8lT2PGce0VBQEZGEPWDw== │ │ │ ├── refs.0~SLeLt8lKVQCChtgVef_SA3X4FpyKn2Oogk9YHpVbChFyzoOO3kTi3lsAHg5HUTdtO-52Kom1sv1YFBuYe83X9A== │ │ │ ├── refs.0~U-MMVGlo6VNjyI9x3g9-HsSrRB4iLjo-Ss1ma8FuydvBPbrRuTeOsnl678_GHdBv7qKb40vbODYiXixRHaL4cg== │ │ │ ├── refs.0~UqU2a4503F4gImKaTQC3-NvC-hvKwXLLKn2jvU777iA5u2wnpWfRvhQcXfk7BNfemW2tB-vHEzEmsv2yxTvbSw== │ │ │ ├── refs.0~V5N20g2tbfNtC6P_FOmeIJzg9OaMCjCPtB1sE1SsOq9GEEOnP3yh_eCLeqJy7teeZYU3Uq8jWbqqnJ3zpJWVqQ== │ │ │ ├── refs.0~XFNRKtSxJZ8r0lwLSEqTziyzqR8_7d5BblTSp4ItyJFPvDRGVaUec4oekqfCXJEVO9a6ujXmBsjlCrwHWNuIgA== │ │ │ ├── refs.0~Y0VetVEvhnBc2qz8RJCUYcL842qfqvSevY8OB-wcQvAP_H4On3JScWWWn6uPGt-810JiN5qqaNQg4oRO0-jpDw== │ │ │ ├── refs.0~YrizJ0L-df_j4QZQ4ML2mZIil7N8h1aB8MleOBoyrf_r1l8CwpYwivatCeSvqbBf05A_-UQlAV1xT2qMeC-VVg== │ │ │ ├── refs.0~aQuuYLb-TKyYZtcAWj6Fx63Y1DomF-ssVZor3npByulK0GATZfYViD8JboHNjz6BwV0xbcVp7R0yt6OYVrTFMQ== │ │ │ ├── refs.0~cPmsKVMixUukUBjUrD2QkE7mOethVpIPNH_RUshp-3qj1X7zIPv6PzNpo_evtT1HGn1vyZ5Nc9n2wliy4HBfzQ== │ │ │ ├── refs.0~cm12k-Ps7aJ4GrJt7wyuRj8XNsiWydV7wx4SMBnv0HCA8tsaQSL0gtrryRqtR-1t5Zvk3SzNhSG5DSvj84X75Q== │ │ │ ├── refs.0~fnScc6uwLeUOtP1wtZlnqtFmvEGAllShITIhX3BeZgyOFeOB2gl5_o449t_l-eg3Qi421YTdEshk3I9x0ZOCGg== │ │ │ ├── refs.0~gsDKNmFTosKDqM22lZ1qRkVmAfnfo0oULz3_43S_9WPMFZIycyK38DKyUVr5CqpYYHsR7ACb4ptkTgpAwmqOBg== │ │ │ ├── refs.0~juhI1raJ5S700ABcImgZVK-YOVPZ8e4gO3uZCVa0C1l34a18auJLksa8Hj6d8yZwSpB-05wwBB0vDxNP-JCZZA== │ │ │ ├── refs.0~oKjVlRvWisdmloxst_ebPvfm1egBj903jOxknh_ZmlJJiktpEA3NkCUU1-ovPZQPFbpIKHXAnvBzTFfPB6ZzhQ== │ │ │ ├── refs.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA== │ │ │ ├── refs.0~p6GGgLAcpnkTXmB_i0bgIdxUy1UY07e5xHTA1r_zNkzMe_CK5w9WUbIq9lm9MtSPEaQT8LAoflr6rpKsu5_PnA== │ │ │ ├── refs.0~qd9e6ooeKrMz43BCHtdlFtGqUm29HTUedZV34c6zJC_2Yo3KjW8IR398N7y6SmofRF93y4GvY9QW5YuFdo8wZg== │ │ │ ├── refs.0~rlyQM6UGPphiQJf3tw_DH-YdR9H1fREkapmc4-sI_JwVXqKPOXUgcgyM1SqgFvw1ItJb8k3VdNKCFwpsNFY10g== │ │ │ ├── refs.0~tFDRQK08gMZAKbFKrDwZPg17dEe4Fcef4Wfh0Ui7F653X9zGL1xbAGp7w3Uzb4hb73cy-PzWFJzgVxZiRiXO8w== │ │ │ ├── refs.0~tta5TbL6EQkBtFy54Qdw7uKPBlHi7NMWXXwtEsYlPz5AQCtEwWUVd1xkCOJA60KgRr5N4gimH2yp54_QiE0Jfg== │ │ │ └── refs.0~wwEG-hauljIcgt3ZtMdcQfbmdDVGUzs2boUcNrlJ4kEWkqgFzw4FRJLQbfGZV_x8NUOqaPD54BkdPBdIivQprQ== │ │ └── Info.plist │ └── ExampleResult.xml ├── BashTests.swift ├── ConverterTests.swift ├── Info.plist ├── XCResultExamples.swift ├── XMLEscaperExamples.swift └── XMLEscaperTests.swift └── fastlane ├── Appfile ├── Fastfile └── README.md /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | references: 4 | xcode_version: &xcode_version 11.3.0 5 | 6 | commands: 7 | prepare_for_spm: 8 | steps: 9 | - run: 10 | name: Prepare for Swift Package Manager 11 | command: | 12 | for ip in $(dig @8.8.8.8 bitbucket.org +short); do ssh-keyscan bitbucket.org,$ip; ssh-keyscan $ip; done 2>/dev/null >> ~/.ssh/known_hosts 13 | xcodebuild -resolvePackageDependencies 14 | prepare_and_fastlane: 15 | description: "Sets up the environment before starting the given fastlane lane" 16 | parameters: 17 | lane: 18 | type: string 19 | default: "test" 20 | steps: 21 | - run: bundle install 22 | - prepare_for_spm 23 | - run: 24 | name: Fastlane 25 | command: bundle exec fastlane << parameters.lane >> 26 | environment: 27 | FL_OUTPUT_DIR: output 28 | create_github_release: 29 | description: "Create Github release and upload binary" 30 | steps: 31 | - run: 32 | name: ghr - create Github release 33 | command: | 34 | brew install ghr 35 | ghr \ 36 | -t $GITHUB_CI_TOKEN \ 37 | -u $CIRCLE_PROJECT_USERNAME \ 38 | -r $CIRCLE_PROJECT_REPONAME \ 39 | -c $CIRCLE_SHA1 \ 40 | -delete \ 41 | -replace \ 42 | $CIRCLE_TAG ./output/ 43 | 44 | jobs: 45 | build_and_test: 46 | macos: 47 | xcode: *xcode_version 48 | steps: 49 | - checkout 50 | - prepare_and_fastlane: 51 | lane: "test" 52 | - store_artifacts: 53 | path: output 54 | - store_test_results: 55 | path: output/scan 56 | 57 | publish_github_release: 58 | macos: 59 | xcode: *xcode_version 60 | steps: 61 | - checkout 62 | - prepare_and_fastlane: 63 | lane: "build" 64 | - create_github_release 65 | - store_artifacts: 66 | path: output 67 | 68 | workflows: 69 | version: 2.1 70 | test: 71 | jobs: 72 | - build_and_test 73 | release: 74 | jobs: 75 | - publish_github_release: 76 | filters: 77 | branches: 78 | ignore: /.*/ 79 | tags: 80 | only: /^v\d+\.\d+\.\d+$/ 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | ## User settings 4 | xcuserdata/ 5 | 6 | ## Obj-C/Swift specific 7 | *.hmap 8 | 9 | ## App packaging 10 | *.ipa 11 | *.dSYM.zip 12 | *.dSY 13 | derived_data 14 | 15 | ## fastlane 16 | fastlane/test_output 17 | fastlane/report.xml 18 | fastlane/Preview.html 19 | fastlane/screenshots 20 | fastlane/test_output 21 | build_artifacts 22 | output 23 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane", "2.140.0" 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.2) 5 | addressable (2.7.0) 6 | public_suffix (>= 2.0.2, < 5.0) 7 | atomos (0.1.3) 8 | babosa (1.0.3) 9 | claide (1.0.3) 10 | colored (1.2) 11 | colored2 (3.1.2) 12 | commander-fastlane (4.4.6) 13 | highline (~> 1.7.2) 14 | declarative (0.0.10) 15 | declarative-option (0.1.0) 16 | digest-crc (0.4.1) 17 | domain_name (0.5.20190701) 18 | unf (>= 0.0.5, < 1.0.0) 19 | dotenv (2.7.5) 20 | emoji_regex (1.0.1) 21 | excon (0.71.1) 22 | faraday (0.17.3) 23 | multipart-post (>= 1.2, < 3) 24 | faraday-cookie_jar (0.0.6) 25 | faraday (>= 0.7.4) 26 | http-cookie (~> 1.0.0) 27 | faraday_middleware (0.13.1) 28 | faraday (>= 0.7.4, < 1.0) 29 | fastimage (2.1.7) 30 | fastlane (2.140.0) 31 | CFPropertyList (>= 2.3, < 4.0.0) 32 | addressable (>= 2.3, < 3.0.0) 33 | babosa (>= 1.0.2, < 2.0.0) 34 | bundler (>= 1.12.0, < 3.0.0) 35 | colored 36 | commander-fastlane (>= 4.4.6, < 5.0.0) 37 | dotenv (>= 2.1.1, < 3.0.0) 38 | emoji_regex (>= 0.1, < 2.0) 39 | excon (>= 0.71.0, < 1.0.0) 40 | faraday (~> 0.17) 41 | faraday-cookie_jar (~> 0.0.6) 42 | faraday_middleware (~> 0.13.1) 43 | fastimage (>= 2.1.0, < 3.0.0) 44 | gh_inspector (>= 1.1.2, < 2.0.0) 45 | google-api-client (>= 0.29.2, < 0.37.0) 46 | google-cloud-storage (>= 1.15.0, < 2.0.0) 47 | highline (>= 1.7.2, < 2.0.0) 48 | json (< 3.0.0) 49 | jwt (~> 2.1.0) 50 | mini_magick (>= 4.9.4, < 5.0.0) 51 | multi_xml (~> 0.5) 52 | multipart-post (~> 2.0.0) 53 | plist (>= 3.1.0, < 4.0.0) 54 | public_suffix (~> 2.0.0) 55 | rubyzip (>= 1.3.0, < 2.0.0) 56 | security (= 0.1.3) 57 | simctl (~> 1.6.3) 58 | slack-notifier (>= 2.0.0, < 3.0.0) 59 | terminal-notifier (>= 2.0.0, < 3.0.0) 60 | terminal-table (>= 1.4.5, < 2.0.0) 61 | tty-screen (>= 0.6.3, < 1.0.0) 62 | tty-spinner (>= 0.8.0, < 1.0.0) 63 | word_wrap (~> 1.0.0) 64 | xcodeproj (>= 1.13.0, < 2.0.0) 65 | xcpretty (~> 0.3.0) 66 | xcpretty-travis-formatter (>= 0.0.3) 67 | gh_inspector (1.1.3) 68 | google-api-client (0.36.4) 69 | addressable (~> 2.5, >= 2.5.1) 70 | googleauth (~> 0.9) 71 | httpclient (>= 2.8.1, < 3.0) 72 | mini_mime (~> 1.0) 73 | representable (~> 3.0) 74 | retriable (>= 2.0, < 4.0) 75 | signet (~> 0.12) 76 | google-cloud-core (1.5.0) 77 | google-cloud-env (~> 1.0) 78 | google-cloud-errors (~> 1.0) 79 | google-cloud-env (1.3.0) 80 | faraday (~> 0.11) 81 | google-cloud-errors (1.0.0) 82 | google-cloud-storage (1.25.1) 83 | addressable (~> 2.5) 84 | digest-crc (~> 0.4) 85 | google-api-client (~> 0.33) 86 | google-cloud-core (~> 1.2) 87 | googleauth (~> 0.9) 88 | mini_mime (~> 1.0) 89 | googleauth (0.10.0) 90 | faraday (~> 0.12) 91 | jwt (>= 1.4, < 3.0) 92 | memoist (~> 0.16) 93 | multi_json (~> 1.11) 94 | os (>= 0.9, < 2.0) 95 | signet (~> 0.12) 96 | highline (1.7.10) 97 | http-cookie (1.0.3) 98 | domain_name (~> 0.5) 99 | httpclient (2.8.3) 100 | json (2.3.0) 101 | jwt (2.1.0) 102 | memoist (0.16.2) 103 | mini_magick (4.10.1) 104 | mini_mime (1.0.2) 105 | multi_json (1.14.1) 106 | multi_xml (0.6.0) 107 | multipart-post (2.0.0) 108 | nanaimo (0.2.6) 109 | naturally (2.2.0) 110 | os (1.0.1) 111 | plist (3.5.0) 112 | public_suffix (2.0.5) 113 | representable (3.0.4) 114 | declarative (< 0.1.0) 115 | declarative-option (< 0.2.0) 116 | uber (< 0.2.0) 117 | retriable (3.1.2) 118 | rouge (2.0.7) 119 | rubyzip (1.3.0) 120 | security (0.1.3) 121 | signet (0.12.0) 122 | addressable (~> 2.3) 123 | faraday (~> 0.9) 124 | jwt (>= 1.5, < 3.0) 125 | multi_json (~> 1.10) 126 | simctl (1.6.7) 127 | CFPropertyList 128 | naturally 129 | slack-notifier (2.3.2) 130 | terminal-notifier (2.0.0) 131 | terminal-table (1.8.0) 132 | unicode-display_width (~> 1.1, >= 1.1.1) 133 | tty-cursor (0.7.0) 134 | tty-screen (0.7.0) 135 | tty-spinner (0.9.2) 136 | tty-cursor (~> 0.7) 137 | uber (0.1.0) 138 | unf (0.1.4) 139 | unf_ext 140 | unf_ext (0.0.7.6) 141 | unicode-display_width (1.6.0) 142 | word_wrap (1.0.0) 143 | xcodeproj (1.14.0) 144 | CFPropertyList (>= 2.3.3, < 4.0) 145 | atomos (~> 0.1.3) 146 | claide (>= 1.0.2, < 2.0) 147 | colored2 (~> 3.1) 148 | nanaimo (~> 0.2.6) 149 | xcpretty (0.3.0) 150 | rouge (~> 2.0.7) 151 | xcpretty-travis-formatter (1.0.0) 152 | xcpretty (~> 0.2, >= 0.0.7) 153 | 154 | PLATFORMS 155 | ruby 156 | 157 | DEPENDENCIES 158 | fastlane (= 2.140.0) 159 | 160 | BUNDLED WITH 161 | 2.0.2 162 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 mySugr GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ This repository is deprecated 2 | 3 | Since we use a different approach this script/repo is deprecated and will no longer be maintained. 4 | I will outline our new approach here since it is probably useful to other people as well. 5 | 6 | Instead of using SonarQube's generic code coverage format, we use the `llvm-cov` format which is directly supported. No conversion needed! 7 | 8 | - Merge all .profdata files into one 9 | - They are located here: `/Build/ProfileData/*/*.profdata` 10 | - Use: `xcrun llvm-profdata merge -output ` 11 | - Collect all relevant binaries to extract code coverage data 12 | - They are located here: `/Build/Products/Debug-iphonesimulator/` 13 | - Include the `*.app` binary (includes statically-linked frameworks) 14 | - Collect remaining dynamic framework binaries (You probably want to exclude external depdencies like pods) 15 | - Iterate over relevant binaries and append code coverage data to a file 16 | - `xcrun --run llvm-cov show --instr-profile >> ` 17 | - The file can then be passed to `sonar-scanner` 18 | - `sonar.cfamily.llvm-cov.reportPath` (for Obj-C code coverage) 19 | - `sonar.swift.coverage.reportPaths` (for Swift code coverage) 20 | 21 | # cococo - **co**de **co**verage **co**nverter from Xcode 11 to SonarQube 22 | 23 | [![mysugr](https://circleci.com/gh/mysugr/cococo.svg?style=svg)](https://circleci.com/gh/mySugr/cococo) 24 | ![GitHub release (latest by date)](https://img.shields.io/github/v/release/mysugr/cococo) 25 | 26 | cococo is a command line tool to convert Xcode 11's code coverage data to [SonarQube's generic code coverage format](https://docs.sonarqube.org/latest/analysis/generic-test/). It is written in Swift and makes use of multiple threads to speed up the computation. 27 | 28 | ## Usage 29 | ``` 30 | USAGE: cococo [-e ...] 31 | 32 | OPTIONS: 33 | --excluded, -e Multiple file extensions which are excluded from processing 34 | --help Display available options 35 | ``` 36 | 37 | ## Example 38 | Run the tool for a given `xcresult` archive, exclude `.h` and `.m` files from processing and save the result to `sonarqube-generic-coverage.xml`. 39 | ``` 40 | cococo myproject.xcresult --excluded .h .m > sonarqube-generic-coverage.xml 41 | ``` 42 | 43 | The Xcode 11's `xcresult` archive can be found in the derived data folder: 44 | ``` 45 | DerivedData/YourProject/Logs/Test/*.xcresult 46 | ``` 47 | 48 | ## Installation 49 | 50 | You can download the latest release from [here](https://github.com/mysugr/cococo/releases/latest). 51 | -------------------------------------------------------------------------------- /cococo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D803E01A23BF671000AAF2D0 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D803E01923BF671000AAF2D0 /* main.swift */; }; 11 | D83494BA23CCC7B70056A42F /* SPMUtility in Frameworks */ = {isa = PBXBuildFile; productRef = D83494B923CCC7B70056A42F /* SPMUtility */; }; 12 | D834951F23CE096E0056A42F /* Cli.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494B123C878610056A42F /* Cli.swift */; }; 13 | D834952D23CE0EB70056A42F /* XMLEscaper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494F023CDA7DD0056A42F /* XMLEscaper.swift */; }; 14 | D834952E23CE0EB70056A42F /* Bash.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8764DD723C6335900FB72A4 /* Bash.swift */; }; 15 | D834952F23CE0EB70056A42F /* Converter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494AF23C857AC0056A42F /* Converter.swift */; }; 16 | D834953023CE0EB70056A42F /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494AD23C8568B0056A42F /* IO.swift */; }; 17 | D834953123CE0ED70056A42F /* libcococoLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D834952423CE0E5E0056A42F /* libcococoLibrary.a */; }; 18 | D834953D23CE102F0056A42F /* libcococoLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D834952423CE0E5E0056A42F /* libcococoLibrary.a */; }; 19 | D834954323CE10450056A42F /* XMLEscaperExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494F223CDAAF60056A42F /* XMLEscaperExamples.swift */; }; 20 | D834954423CE10450056A42F /* ConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494F623CDAF850056A42F /* ConverterTests.swift */; }; 21 | D834954523CE10450056A42F /* XCResultExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494F923CDB5390056A42F /* XCResultExamples.swift */; }; 22 | D834954623CE10450056A42F /* XMLEscaperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83494DE23CDA5E00056A42F /* XMLEscaperTests.swift */; }; 23 | D834954723CE10A60056A42F /* Example.xcresult in Resources */ = {isa = PBXBuildFile; fileRef = D83494F423CDAF280056A42F /* Example.xcresult */; }; 24 | D834954823CE10AB0056A42F /* ExampleResult.xml in Resources */ = {isa = PBXBuildFile; fileRef = D83494FB23CDB62C0056A42F /* ExampleResult.xml */; }; 25 | D834954B23CE15920056A42F /* BashTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D834954A23CE15920056A42F /* BashTests.swift */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | D834953223CE0ED70056A42F /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = D803E00E23BF671000AAF2D0 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = D834952323CE0E5E0056A42F; 34 | remoteInfo = cococoLibrary; 35 | }; 36 | D834953E23CE102F0056A42F /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = D803E00E23BF671000AAF2D0 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = D834952323CE0E5E0056A42F; 41 | remoteInfo = cococoLibrary; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXCopyFilesBuildPhase section */ 46 | D803E01423BF671000AAF2D0 /* CopyFiles */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 12; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXCopyFilesBuildPhase section */ 56 | 57 | /* Begin PBXFileReference section */ 58 | D803E01623BF671000AAF2D0 /* cococo */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cococo; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | D803E01923BF671000AAF2D0 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 60 | D83494AD23C8568B0056A42F /* IO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IO.swift; sourceTree = ""; }; 61 | D83494AF23C857AC0056A42F /* Converter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Converter.swift; sourceTree = ""; }; 62 | D83494B123C878610056A42F /* Cli.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cli.swift; sourceTree = ""; }; 63 | D83494DE23CDA5E00056A42F /* XMLEscaperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLEscaperTests.swift; sourceTree = ""; }; 64 | D83494F023CDA7DD0056A42F /* XMLEscaper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLEscaper.swift; sourceTree = ""; }; 65 | D83494F223CDAAF60056A42F /* XMLEscaperExamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLEscaperExamples.swift; sourceTree = ""; }; 66 | D83494F423CDAF280056A42F /* Example.xcresult */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Example.xcresult; sourceTree = ""; }; 67 | D83494F623CDAF850056A42F /* ConverterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConverterTests.swift; sourceTree = ""; }; 68 | D83494F923CDB5390056A42F /* XCResultExamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCResultExamples.swift; sourceTree = ""; }; 69 | D83494FB23CDB62C0056A42F /* ExampleResult.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = ExampleResult.xml; sourceTree = ""; }; 70 | D83494FD23CDF8D70056A42F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 71 | D834952423CE0E5E0056A42F /* libcococoLibrary.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcococoLibrary.a; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | D834953823CE102F0056A42F /* cococoLibraryTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = cococoLibraryTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | D834953C23CE102F0056A42F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | D834954A23CE15920056A42F /* BashTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BashTests.swift; sourceTree = ""; }; 75 | D8764DD723C6335900FB72A4 /* Bash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bash.swift; sourceTree = ""; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | D803E01323BF671000AAF2D0 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | D83494BA23CCC7B70056A42F /* SPMUtility in Frameworks */, 84 | D834953123CE0ED70056A42F /* libcococoLibrary.a in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | D834952223CE0E5E0056A42F /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | D834953523CE102F0056A42F /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | D834953D23CE102F0056A42F /* libcococoLibrary.a in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | /* End PBXFrameworksBuildPhase section */ 104 | 105 | /* Begin PBXGroup section */ 106 | D803E00D23BF671000AAF2D0 = { 107 | isa = PBXGroup; 108 | children = ( 109 | D83494FD23CDF8D70056A42F /* README.md */, 110 | D803E01823BF671000AAF2D0 /* cococo */, 111 | D834952523CE0E5E0056A42F /* cococoLibrary */, 112 | D834953923CE102F0056A42F /* cococoLibraryTests */, 113 | D803E01723BF671000AAF2D0 /* Products */, 114 | D83494C723CDA2E10056A42F /* Frameworks */, 115 | ); 116 | sourceTree = ""; 117 | }; 118 | D803E01723BF671000AAF2D0 /* Products */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | D803E01623BF671000AAF2D0 /* cococo */, 122 | D834952423CE0E5E0056A42F /* libcococoLibrary.a */, 123 | D834953823CE102F0056A42F /* cococoLibraryTests.xctest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | D803E01823BF671000AAF2D0 /* cococo */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | D803E01923BF671000AAF2D0 /* main.swift */, 132 | D83494B123C878610056A42F /* Cli.swift */, 133 | ); 134 | path = cococo; 135 | sourceTree = ""; 136 | }; 137 | D83494C723CDA2E10056A42F /* Frameworks */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | ); 141 | name = Frameworks; 142 | sourceTree = ""; 143 | }; 144 | D834952523CE0E5E0056A42F /* cococoLibrary */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | D83494AF23C857AC0056A42F /* Converter.swift */, 148 | D8764DD723C6335900FB72A4 /* Bash.swift */, 149 | D83494AD23C8568B0056A42F /* IO.swift */, 150 | D83494F023CDA7DD0056A42F /* XMLEscaper.swift */, 151 | ); 152 | path = cococoLibrary; 153 | sourceTree = ""; 154 | }; 155 | D834953923CE102F0056A42F /* cococoLibraryTests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | D83494DE23CDA5E00056A42F /* XMLEscaperTests.swift */, 159 | D83494F223CDAAF60056A42F /* XMLEscaperExamples.swift */, 160 | D83494F623CDAF850056A42F /* ConverterTests.swift */, 161 | D83494F923CDB5390056A42F /* XCResultExamples.swift */, 162 | D834954A23CE15920056A42F /* BashTests.swift */, 163 | D834954923CE11AF0056A42F /* Assets */, 164 | D834953C23CE102F0056A42F /* Info.plist */, 165 | ); 166 | path = cococoLibraryTests; 167 | sourceTree = ""; 168 | }; 169 | D834954923CE11AF0056A42F /* Assets */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | D83494F423CDAF280056A42F /* Example.xcresult */, 173 | D83494FB23CDB62C0056A42F /* ExampleResult.xml */, 174 | ); 175 | path = Assets; 176 | sourceTree = ""; 177 | }; 178 | /* End PBXGroup section */ 179 | 180 | /* Begin PBXHeadersBuildPhase section */ 181 | D834952023CE0E5E0056A42F /* Headers */ = { 182 | isa = PBXHeadersBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXHeadersBuildPhase section */ 189 | 190 | /* Begin PBXNativeTarget section */ 191 | D803E01523BF671000AAF2D0 /* cococo */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = D803E01D23BF671000AAF2D0 /* Build configuration list for PBXNativeTarget "cococo" */; 194 | buildPhases = ( 195 | D803E01223BF671000AAF2D0 /* Sources */, 196 | D803E01323BF671000AAF2D0 /* Frameworks */, 197 | D803E01423BF671000AAF2D0 /* CopyFiles */, 198 | ); 199 | buildRules = ( 200 | ); 201 | dependencies = ( 202 | D834953323CE0ED70056A42F /* PBXTargetDependency */, 203 | ); 204 | name = cococo; 205 | packageProductDependencies = ( 206 | D83494B923CCC7B70056A42F /* SPMUtility */, 207 | ); 208 | productName = cococo; 209 | productReference = D803E01623BF671000AAF2D0 /* cococo */; 210 | productType = "com.apple.product-type.tool"; 211 | }; 212 | D834952323CE0E5E0056A42F /* cococoLibrary */ = { 213 | isa = PBXNativeTarget; 214 | buildConfigurationList = D834952A23CE0E5E0056A42F /* Build configuration list for PBXNativeTarget "cococoLibrary" */; 215 | buildPhases = ( 216 | D834952023CE0E5E0056A42F /* Headers */, 217 | D834952123CE0E5E0056A42F /* Sources */, 218 | D834952223CE0E5E0056A42F /* Frameworks */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | ); 224 | name = cococoLibrary; 225 | productName = cococoLibrary; 226 | productReference = D834952423CE0E5E0056A42F /* libcococoLibrary.a */; 227 | productType = "com.apple.product-type.library.static"; 228 | }; 229 | D834953723CE102F0056A42F /* cococoLibraryTests */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = D834954023CE102F0056A42F /* Build configuration list for PBXNativeTarget "cococoLibraryTests" */; 232 | buildPhases = ( 233 | D834953423CE102F0056A42F /* Sources */, 234 | D834953523CE102F0056A42F /* Frameworks */, 235 | D834953623CE102F0056A42F /* Resources */, 236 | ); 237 | buildRules = ( 238 | ); 239 | dependencies = ( 240 | D834953F23CE102F0056A42F /* PBXTargetDependency */, 241 | ); 242 | name = cococoLibraryTests; 243 | productName = cococoLibraryTests; 244 | productReference = D834953823CE102F0056A42F /* cococoLibraryTests.xctest */; 245 | productType = "com.apple.product-type.bundle.unit-test"; 246 | }; 247 | /* End PBXNativeTarget section */ 248 | 249 | /* Begin PBXProject section */ 250 | D803E00E23BF671000AAF2D0 /* Project object */ = { 251 | isa = PBXProject; 252 | attributes = { 253 | LastSwiftUpdateCheck = 1130; 254 | LastUpgradeCheck = 1130; 255 | ORGANIZATIONNAME = "mySugr GmbH"; 256 | TargetAttributes = { 257 | D803E01523BF671000AAF2D0 = { 258 | CreatedOnToolsVersion = 11.3; 259 | }; 260 | D834952323CE0E5E0056A42F = { 261 | CreatedOnToolsVersion = 11.3; 262 | }; 263 | D834953723CE102F0056A42F = { 264 | CreatedOnToolsVersion = 11.3; 265 | }; 266 | }; 267 | }; 268 | buildConfigurationList = D803E01123BF671000AAF2D0 /* Build configuration list for PBXProject "cococo" */; 269 | compatibilityVersion = "Xcode 9.3"; 270 | developmentRegion = en; 271 | hasScannedForEncodings = 0; 272 | knownRegions = ( 273 | en, 274 | Base, 275 | ); 276 | mainGroup = D803E00D23BF671000AAF2D0; 277 | packageReferences = ( 278 | D83494B823CCC7B70056A42F /* XCRemoteSwiftPackageReference "swift-package-manager" */, 279 | ); 280 | productRefGroup = D803E01723BF671000AAF2D0 /* Products */; 281 | projectDirPath = ""; 282 | projectRoot = ""; 283 | targets = ( 284 | D803E01523BF671000AAF2D0 /* cococo */, 285 | D834952323CE0E5E0056A42F /* cococoLibrary */, 286 | D834953723CE102F0056A42F /* cococoLibraryTests */, 287 | ); 288 | }; 289 | /* End PBXProject section */ 290 | 291 | /* Begin PBXResourcesBuildPhase section */ 292 | D834953623CE102F0056A42F /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | D834954723CE10A60056A42F /* Example.xcresult in Resources */, 297 | D834954823CE10AB0056A42F /* ExampleResult.xml in Resources */, 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | }; 301 | /* End PBXResourcesBuildPhase section */ 302 | 303 | /* Begin PBXSourcesBuildPhase section */ 304 | D803E01223BF671000AAF2D0 /* Sources */ = { 305 | isa = PBXSourcesBuildPhase; 306 | buildActionMask = 2147483647; 307 | files = ( 308 | D834951F23CE096E0056A42F /* Cli.swift in Sources */, 309 | D803E01A23BF671000AAF2D0 /* main.swift in Sources */, 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | D834952123CE0E5E0056A42F /* Sources */ = { 314 | isa = PBXSourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | D834952E23CE0EB70056A42F /* Bash.swift in Sources */, 318 | D834952F23CE0EB70056A42F /* Converter.swift in Sources */, 319 | D834953023CE0EB70056A42F /* IO.swift in Sources */, 320 | D834952D23CE0EB70056A42F /* XMLEscaper.swift in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | D834953423CE102F0056A42F /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | D834954623CE10450056A42F /* XMLEscaperTests.swift in Sources */, 329 | D834954423CE10450056A42F /* ConverterTests.swift in Sources */, 330 | D834954323CE10450056A42F /* XMLEscaperExamples.swift in Sources */, 331 | D834954523CE10450056A42F /* XCResultExamples.swift in Sources */, 332 | D834954B23CE15920056A42F /* BashTests.swift in Sources */, 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | }; 336 | /* End PBXSourcesBuildPhase section */ 337 | 338 | /* Begin PBXTargetDependency section */ 339 | D834953323CE0ED70056A42F /* PBXTargetDependency */ = { 340 | isa = PBXTargetDependency; 341 | target = D834952323CE0E5E0056A42F /* cococoLibrary */; 342 | targetProxy = D834953223CE0ED70056A42F /* PBXContainerItemProxy */; 343 | }; 344 | D834953F23CE102F0056A42F /* PBXTargetDependency */ = { 345 | isa = PBXTargetDependency; 346 | target = D834952323CE0E5E0056A42F /* cococoLibrary */; 347 | targetProxy = D834953E23CE102F0056A42F /* PBXContainerItemProxy */; 348 | }; 349 | /* End PBXTargetDependency section */ 350 | 351 | /* Begin XCBuildConfiguration section */ 352 | D803E01B23BF671000AAF2D0 /* Debug */ = { 353 | isa = XCBuildConfiguration; 354 | buildSettings = { 355 | ALWAYS_SEARCH_USER_PATHS = NO; 356 | CLANG_ANALYZER_NONNULL = YES; 357 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 358 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 359 | CLANG_CXX_LIBRARY = "libc++"; 360 | CLANG_ENABLE_MODULES = YES; 361 | CLANG_ENABLE_OBJC_ARC = YES; 362 | CLANG_ENABLE_OBJC_WEAK = YES; 363 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 364 | CLANG_WARN_BOOL_CONVERSION = YES; 365 | CLANG_WARN_COMMA = YES; 366 | CLANG_WARN_CONSTANT_CONVERSION = YES; 367 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 368 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 369 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 370 | CLANG_WARN_EMPTY_BODY = YES; 371 | CLANG_WARN_ENUM_CONVERSION = YES; 372 | CLANG_WARN_INFINITE_RECURSION = YES; 373 | CLANG_WARN_INT_CONVERSION = YES; 374 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 375 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 376 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 378 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 379 | CLANG_WARN_STRICT_PROTOTYPES = YES; 380 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 381 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 382 | CLANG_WARN_UNREACHABLE_CODE = YES; 383 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 384 | COPY_PHASE_STRIP = NO; 385 | DEBUG_INFORMATION_FORMAT = dwarf; 386 | ENABLE_STRICT_OBJC_MSGSEND = YES; 387 | ENABLE_TESTABILITY = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu11; 389 | GCC_DYNAMIC_NO_PIC = NO; 390 | GCC_NO_COMMON_BLOCKS = YES; 391 | GCC_OPTIMIZATION_LEVEL = 0; 392 | GCC_PREPROCESSOR_DEFINITIONS = ( 393 | "DEBUG=1", 394 | "$(inherited)", 395 | ); 396 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 397 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 398 | GCC_WARN_UNDECLARED_SELECTOR = YES; 399 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 400 | GCC_WARN_UNUSED_FUNCTION = YES; 401 | GCC_WARN_UNUSED_VARIABLE = YES; 402 | MACOSX_DEPLOYMENT_TARGET = 10.14; 403 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 404 | MTL_FAST_MATH = YES; 405 | ONLY_ACTIVE_ARCH = YES; 406 | SDKROOT = macosx; 407 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 408 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 409 | }; 410 | name = Debug; 411 | }; 412 | D803E01C23BF671000AAF2D0 /* Release */ = { 413 | isa = XCBuildConfiguration; 414 | buildSettings = { 415 | ALWAYS_SEARCH_USER_PATHS = NO; 416 | CLANG_ANALYZER_NONNULL = YES; 417 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 418 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 419 | CLANG_CXX_LIBRARY = "libc++"; 420 | CLANG_ENABLE_MODULES = YES; 421 | CLANG_ENABLE_OBJC_ARC = YES; 422 | CLANG_ENABLE_OBJC_WEAK = YES; 423 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 424 | CLANG_WARN_BOOL_CONVERSION = YES; 425 | CLANG_WARN_COMMA = YES; 426 | CLANG_WARN_CONSTANT_CONVERSION = YES; 427 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 429 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 430 | CLANG_WARN_EMPTY_BODY = YES; 431 | CLANG_WARN_ENUM_CONVERSION = YES; 432 | CLANG_WARN_INFINITE_RECURSION = YES; 433 | CLANG_WARN_INT_CONVERSION = YES; 434 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 435 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 436 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 437 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 438 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 439 | CLANG_WARN_STRICT_PROTOTYPES = YES; 440 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 441 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 442 | CLANG_WARN_UNREACHABLE_CODE = YES; 443 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 444 | COPY_PHASE_STRIP = NO; 445 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 446 | ENABLE_NS_ASSERTIONS = NO; 447 | ENABLE_STRICT_OBJC_MSGSEND = YES; 448 | GCC_C_LANGUAGE_STANDARD = gnu11; 449 | GCC_NO_COMMON_BLOCKS = YES; 450 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 451 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 452 | GCC_WARN_UNDECLARED_SELECTOR = YES; 453 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 454 | GCC_WARN_UNUSED_FUNCTION = YES; 455 | GCC_WARN_UNUSED_VARIABLE = YES; 456 | MACOSX_DEPLOYMENT_TARGET = 10.14; 457 | MTL_ENABLE_DEBUG_INFO = NO; 458 | MTL_FAST_MATH = YES; 459 | SDKROOT = macosx; 460 | SWIFT_COMPILATION_MODE = wholemodule; 461 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 462 | }; 463 | name = Release; 464 | }; 465 | D803E01E23BF671000AAF2D0 /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | CODE_SIGN_STYLE = Automatic; 469 | DEVELOPMENT_TEAM = ""; 470 | ENABLE_HARDENED_RUNTIME = YES; 471 | LD_RUNPATH_SEARCH_PATHS = "@executable_path"; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES; 474 | SWIFT_FORCE_STATIC_LINK_STDLIB = NO; 475 | SWIFT_VERSION = 5.0; 476 | }; 477 | name = Debug; 478 | }; 479 | D803E01F23BF671000AAF2D0 /* Release */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | CODE_SIGN_STYLE = Automatic; 483 | DEVELOPMENT_TEAM = ""; 484 | ENABLE_HARDENED_RUNTIME = YES; 485 | LD_RUNPATH_SEARCH_PATHS = "@executable_path"; 486 | PRODUCT_NAME = "$(TARGET_NAME)"; 487 | SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES; 488 | SWIFT_FORCE_STATIC_LINK_STDLIB = NO; 489 | SWIFT_VERSION = 5.0; 490 | }; 491 | name = Release; 492 | }; 493 | D834952B23CE0E5E0056A42F /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | CODE_SIGN_STYLE = Automatic; 497 | DEVELOPMENT_TEAM = 3GVV3V5D67; 498 | EXECUTABLE_PREFIX = lib; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | SKIP_INSTALL = YES; 501 | SWIFT_VERSION = 5.0; 502 | }; 503 | name = Debug; 504 | }; 505 | D834952C23CE0E5E0056A42F /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | buildSettings = { 508 | CODE_SIGN_STYLE = Automatic; 509 | DEVELOPMENT_TEAM = 3GVV3V5D67; 510 | EXECUTABLE_PREFIX = lib; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | SKIP_INSTALL = YES; 513 | SWIFT_VERSION = 5.0; 514 | }; 515 | name = Release; 516 | }; 517 | D834954123CE102F0056A42F /* Debug */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | CODE_SIGN_STYLE = Automatic; 521 | COMBINE_HIDPI_IMAGES = YES; 522 | DEVELOPMENT_TEAM = ""; 523 | INFOPLIST_FILE = cococoLibraryTests/Info.plist; 524 | LD_RUNPATH_SEARCH_PATHS = ( 525 | "$(inherited)", 526 | "@executable_path/../Frameworks", 527 | "@loader_path/../Frameworks", 528 | ); 529 | PRODUCT_BUNDLE_IDENTIFIER = com.mysugr.cococoLibraryTests; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | SWIFT_VERSION = 5.0; 532 | }; 533 | name = Debug; 534 | }; 535 | D834954223CE102F0056A42F /* Release */ = { 536 | isa = XCBuildConfiguration; 537 | buildSettings = { 538 | CODE_SIGN_STYLE = Automatic; 539 | COMBINE_HIDPI_IMAGES = YES; 540 | DEVELOPMENT_TEAM = ""; 541 | INFOPLIST_FILE = cococoLibraryTests/Info.plist; 542 | LD_RUNPATH_SEARCH_PATHS = ( 543 | "$(inherited)", 544 | "@executable_path/../Frameworks", 545 | "@loader_path/../Frameworks", 546 | ); 547 | PRODUCT_BUNDLE_IDENTIFIER = com.mysugr.cococoLibraryTests; 548 | PRODUCT_NAME = "$(TARGET_NAME)"; 549 | SWIFT_VERSION = 5.0; 550 | }; 551 | name = Release; 552 | }; 553 | /* End XCBuildConfiguration section */ 554 | 555 | /* Begin XCConfigurationList section */ 556 | D803E01123BF671000AAF2D0 /* Build configuration list for PBXProject "cococo" */ = { 557 | isa = XCConfigurationList; 558 | buildConfigurations = ( 559 | D803E01B23BF671000AAF2D0 /* Debug */, 560 | D803E01C23BF671000AAF2D0 /* Release */, 561 | ); 562 | defaultConfigurationIsVisible = 0; 563 | defaultConfigurationName = Release; 564 | }; 565 | D803E01D23BF671000AAF2D0 /* Build configuration list for PBXNativeTarget "cococo" */ = { 566 | isa = XCConfigurationList; 567 | buildConfigurations = ( 568 | D803E01E23BF671000AAF2D0 /* Debug */, 569 | D803E01F23BF671000AAF2D0 /* Release */, 570 | ); 571 | defaultConfigurationIsVisible = 0; 572 | defaultConfigurationName = Release; 573 | }; 574 | D834952A23CE0E5E0056A42F /* Build configuration list for PBXNativeTarget "cococoLibrary" */ = { 575 | isa = XCConfigurationList; 576 | buildConfigurations = ( 577 | D834952B23CE0E5E0056A42F /* Debug */, 578 | D834952C23CE0E5E0056A42F /* Release */, 579 | ); 580 | defaultConfigurationIsVisible = 0; 581 | defaultConfigurationName = Release; 582 | }; 583 | D834954023CE102F0056A42F /* Build configuration list for PBXNativeTarget "cococoLibraryTests" */ = { 584 | isa = XCConfigurationList; 585 | buildConfigurations = ( 586 | D834954123CE102F0056A42F /* Debug */, 587 | D834954223CE102F0056A42F /* Release */, 588 | ); 589 | defaultConfigurationIsVisible = 0; 590 | defaultConfigurationName = Release; 591 | }; 592 | /* End XCConfigurationList section */ 593 | 594 | /* Begin XCRemoteSwiftPackageReference section */ 595 | D83494B823CCC7B70056A42F /* XCRemoteSwiftPackageReference "swift-package-manager" */ = { 596 | isa = XCRemoteSwiftPackageReference; 597 | repositoryURL = "https://github.com/apple/swift-package-manager.git"; 598 | requirement = { 599 | kind = upToNextMajorVersion; 600 | minimumVersion = 0.5.0; 601 | }; 602 | }; 603 | /* End XCRemoteSwiftPackageReference section */ 604 | 605 | /* Begin XCSwiftPackageProductDependency section */ 606 | D83494B923CCC7B70056A42F /* SPMUtility */ = { 607 | isa = XCSwiftPackageProductDependency; 608 | package = D83494B823CCC7B70056A42F /* XCRemoteSwiftPackageReference "swift-package-manager" */; 609 | productName = SPMUtility; 610 | }; 611 | /* End XCSwiftPackageProductDependency section */ 612 | }; 613 | rootObject = D803E00E23BF671000AAF2D0 /* Project object */; 614 | } 615 | -------------------------------------------------------------------------------- /cococo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cococo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cococo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "llbuild", 6 | "repositoryURL": "https://github.com/apple/swift-llbuild.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "f73b84bc1525998e5e267f9d830c1411487ac65e", 10 | "version": "0.2.0" 11 | } 12 | }, 13 | { 14 | "package": "SwiftPM", 15 | "repositoryURL": "https://github.com/apple/swift-package-manager.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "9abcc2260438177cecd7cf5185b144d13e74122b", 19 | "version": "0.5.0" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /cococo.xcodeproj/xcshareddata/xcschemes/cococo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 39 | 40 | 41 | 42 | 44 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 78 | 79 | 80 | 81 | 87 | 89 | 95 | 96 | 97 | 98 | 100 | 101 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /cococo.xcodeproj/xcshareddata/xcschemes/cococoLibrary.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /cococo/Cli.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cli.swift 3 | // cococo 4 | // 5 | // Created by Michael Heinzl on 10.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SPMUtility 11 | import cococoLibrary 12 | 13 | class Cli { 14 | 15 | let io = IO() 16 | 17 | func main() { 18 | do { 19 | let parser = ArgumentParser( 20 | usage: " [-e ...]", 21 | overview: "Converts Xcode's xcresult archive into SonarCloud's XML code coverage format" 22 | ) 23 | let archive = parser.add( 24 | positional: "xcresult", 25 | kind: [String].self, 26 | optional: false, 27 | strategy: .upToNextOption, 28 | usage: "Multiple paths to xcresult archives", 29 | completion: .filename 30 | ) 31 | let excluded = parser.add( 32 | option: "--excluded", 33 | shortName: "-e", 34 | kind: [String].self, 35 | strategy: .upToNextOption, 36 | usage: "Multiple file extensions which are excluded from processing", 37 | completion: ShellCompletion.none 38 | ) 39 | 40 | let argsv = Array(CommandLine.arguments.dropFirst()) 41 | let parsedArguments = try parser.parse(argsv) 42 | 43 | let archivePaths = parsedArguments.get(archive) ?? [] 44 | let excludedFileExtensions = parsedArguments.get(excluded) 45 | 46 | let xml = try Converter().convert(archivePaths, excludedFileExtensions: excludedFileExtensions) 47 | io.print(xml) 48 | 49 | } catch ArgumentParserError.expectedValue(let value) { 50 | io.print("Missing value for argument \(value).", to: .error) 51 | } catch ArgumentParserError.expectedArguments(_, let stringArray) { 52 | io.print("Missing arguments: \(stringArray.joined()).", to: .error) 53 | } catch { 54 | io.print(error.localizedDescription, to: .error) 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /cococo/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // cococo 4 | // 5 | // Created by Michael Heinzl on 03.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | Cli().main() 12 | -------------------------------------------------------------------------------- /cococoLibrary/Bash.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Bash.swift 3 | // cococo 4 | // 5 | // Created by Michael Heinzl on 08.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Executes commands on /bin/bash 12 | public class Bash { 13 | 14 | public enum Error: Swift.Error, Equatable { 15 | case failed(terminationStatus: Int) 16 | } 17 | 18 | /// Executes a command including its parameters 19 | /// 20 | /// - Parameters: 21 | /// - commandName: The command to execute e.g. "ls" 22 | /// - arguments: The command arguments e.g. ["-l", "-a"] 23 | /// - Returns: The output of the command 24 | public func execute(commandName: String, arguments: [String] = []) throws -> String { 25 | let bashCommand = try launchProcess( 26 | command: "/bin/bash", 27 | arguments: ["-l", "-c", "which \(commandName)"] 28 | ) 29 | return try launchProcess( 30 | command: bashCommand.trimmingCharacters(in: .whitespacesAndNewlines), 31 | arguments: arguments 32 | ) 33 | } 34 | 35 | private func launchProcess(command: String, arguments: [String]) throws -> String { 36 | let process = Process() 37 | process.launchPath = command 38 | process.arguments = arguments 39 | 40 | let pipe = Pipe() 41 | process.standardOutput = pipe 42 | process.launch() 43 | 44 | let outputData = pipe.fileHandleForReading.readDataToEndOfFile() 45 | let output = String(data: outputData, encoding: .utf8) ?? "" 46 | 47 | process.waitUntilExit() 48 | pipe.fileHandleForReading.closeFile() 49 | let status = process.terminationStatus 50 | if status == 0 { 51 | return output 52 | } else { 53 | throw Error.failed(terminationStatus: Int(status)) 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /cococoLibrary/Converter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Converter.swift 3 | // cococo 4 | // 5 | // Created by Michael Heinzl on 10.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Converts a xcresult archive to SonarQube's generic code coverage format 12 | public class Converter { 13 | 14 | private let io = IO() 15 | private let arrayWriteQueue = DispatchQueue(label: "write-queue", attributes: .concurrent) 16 | private let xmlEscaper = XMLEscaper() 17 | 18 | public init() {} 19 | 20 | /// Converts an array of xcresult archives to SonarQube's generic code coverage format 21 | /// 22 | /// - Parameters: 23 | /// - archivePaths: Paths to the xcresult archives to be processed 24 | /// - Returns: The converted XML string 25 | public func convert(_ archivePaths: [String], excludedFileExtensions: [String]?) throws -> String { 26 | var finalOutput = [String?]() 27 | try archivePaths.forEach { 28 | try finalOutput += convert($0, excludedFileExtensions: excludedFileExtensions) 29 | } 30 | finalOutput.insert("", at: 0) 31 | finalOutput.append("\n") 32 | 33 | return finalOutput 34 | .lazy 35 | .compactMap { $0 } 36 | .joined(separator: "\n") 37 | } 38 | 39 | /// Converts an xcresult archive to SonarQube's generic code coverage format 40 | /// 41 | /// - Parameters: 42 | /// - archivePath: Path to the xcresult archive 43 | /// - Returns: An array containing converted XML nodes for the archive at the given path 44 | internal func convert(_ archivePath: String, excludedFileExtensions: [String]?) throws -> [String?] { 45 | let bash = Bash() 46 | let listOutput = try bash.execute( 47 | commandName: "xcrun", 48 | arguments: ["xccov", "view", "--archive", "--file-list", archivePath] 49 | ) 50 | 51 | var fileList = listOutput 52 | .components(separatedBy: .newlines) 53 | .filter({ !$0.isEmpty }) 54 | 55 | if let excludedFileExtensions = excludedFileExtensions { 56 | fileList = filterFilePaths(fileList, excludedFileExtensions: excludedFileExtensions) 57 | } 58 | 59 | var finalOutput = Array(repeating: nil, count: fileList.count) 60 | DispatchQueue.concurrentPerform(iterations: fileList.count) { (i) in 61 | let filePath = String(fileList[i]) 62 | io.print("\(i)/\(fileList.count) \(filePath)", to: .error) 63 | do { 64 | let output = try convertFile(filePath, archivePath: archivePath) 65 | arrayWriteQueue.async(flags: .barrier) { 66 | finalOutput[i] = output 67 | } 68 | } catch { 69 | io.print("Conversion failed for: \(filePath)", to: .error) 70 | } 71 | } 72 | return finalOutput 73 | } 74 | 75 | /// Converts a single code coverage file to SonarQube's generic code coverage format 76 | /// 77 | /// - Parameters: 78 | /// - filePath: Path to the code coverage file 79 | /// - archivePath: Path to the xcresult archive 80 | /// - Returns: The resulting XML string for the given file 81 | internal func convertFile(_ filePath: String, archivePath: String) throws -> String { 82 | let bash = Bash() 83 | let viewOutput = try bash.execute(commandName: "xcrun", arguments: ["xccov", "view", "--archive", "--file", filePath, archivePath]) 84 | let lines = viewOutput.split(separator: "\n") 85 | 86 | var output = [String]() 87 | let escapedPath = xmlEscaper.escape(filePath) 88 | output.append(" ") 89 | 90 | for line in lines { 91 | if line.hasSuffix("*") { 92 | continue 93 | } 94 | let components = line.components(separatedBy: ": ") 95 | guard components.count == 2 else { 96 | continue 97 | } 98 | let lineNumber = components[0].trimmingCharacters(in: .whitespaces) 99 | let isTested = components[1].hasPrefix("0") ? "false" : "true" 100 | output.append(" ") 101 | } 102 | output.append(" ") 103 | return output.joined(separator: "\n") 104 | } 105 | 106 | internal func filterFilePaths(_ paths: [String], excludedFileExtensions: [String]) -> [String] { 107 | return paths.filter({ (filePath) -> Bool in 108 | let containsExcludedFileExtensions = excludedFileExtensions.contains { (fileExtensions) -> Bool in 109 | filePath.hasSuffix(fileExtensions) 110 | } 111 | return !containsExcludedFileExtensions 112 | }) 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /cococoLibrary/IO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IO.swift 3 | // cococo 4 | // 5 | // Created by Michael Heinzl on 10.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class IO { 12 | 13 | public init() {} 14 | 15 | public enum OutputType { 16 | case error 17 | case standard 18 | } 19 | 20 | public func print(_ message: String, to: OutputType = .standard) { 21 | switch to { 22 | case .standard: 23 | Swift.print("\(message)") 24 | case .error: 25 | fputs("\(message)\n", stderr) 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /cococoLibrary/XMLEscaper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XMLEscaper.swift 3 | // cococoKit 4 | // 5 | // Created by Michael Heinzl on 14.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Escapes text for XML 12 | internal class XMLEscaper { 13 | 14 | internal init() {} 15 | 16 | /// Escapes string by replacing illegal characters 17 | func escape(_ string: String) -> String { 18 | var result = string 19 | result = result.replacingOccurrences(of:"&", with: "&") 20 | result = result.replacingOccurrences(of:"'", with: "'") 21 | result = result.replacingOccurrences(of:"\"", with: """) 22 | result = result.replacingOccurrences(of:"<", with: "<") 23 | result = result.replacingOccurrences(of:">", with: ">") 24 | return result 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~-_8T-OEcNdhNpew23wZ1ZB7LgoiZPincZVDUFRQy387NyUQwImjY_xrgx8FMFiN2ySYVHX3aYyZ3C4EdTcQphA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~-_8T-OEcNdhNpew23wZ1ZB7LgoiZPincZVDUFRQy387NyUQwImjY_xrgx8FMFiN2ySYVHX3aYyZ3C4EdTcQphA== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~-qtwNp_f2fZo_-ax58Um1nBOqq_LawMVrHsxkHl3sadhvHaKZnODnZCWKpoquAH6Vf0PkeJwUW9m4yq0Wiguyg==: -------------------------------------------------------------------------------- 1 | [{"name":"3A31CEFC-E540-4AF2-90CA-3B41FBA83999","type":2}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~24sw3mMVu0yiZqYlmUscqy9CMHTOJT9PXCqC1XYlhqeOtmN-b-LVlSyTWQQZWphu_s6HSqSAe1jV10p_3rM-vw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~24sw3mMVu0yiZqYlmUscqy9CMHTOJT9PXCqC1XYlhqeOtmN-b-LVlSyTWQQZWphu_s6HSqSAe1jV10p_3rM-vw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~50zlzOBEe6Cggikt3hzMlOoqNy0Meu30qJuV2Atupzh-yUUNGc6t3DnmQGDsepvnUItUjQEcQrH3omfmHAlddg==: -------------------------------------------------------------------------------- 1 | [{"name":"testmanagerd.log","type":1}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~6NUkuq5en2H9TIGnPhxm_XI1mTyGbp0mk2xmlGFS_fE1w83m-s0eaAgzT8jLavDVsomSV_fj3gyEeNz8-l-0AQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~6NUkuq5en2H9TIGnPhxm_XI1mTyGbp0mk2xmlGFS_fE1w83m-s0eaAgzT8jLavDVsomSV_fj3gyEeNz8-l-0AQ== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~7f9IXX-kICx4FpA_jCXfMN3T08MzcfpJPwzSE-n0RbJq0p4hxnOwjikwCbtaAhHizMMskKlJlSABi-XFz0jKcg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~7f9IXX-kICx4FpA_jCXfMN3T08MzcfpJPwzSE-n0RbJq0p4hxnOwjikwCbtaAhHizMMskKlJlSABi-XFz0jKcg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~94NzaW5woF3BNyOqqO5h7zYhCpT07MiSMMoxX6UKCSHls-vMuhwbQYXqafiT24bg3H0z1Yo3ipuEbGDScBzgMw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~94NzaW5woF3BNyOqqO5h7zYhCpT07MiSMMoxX6UKCSHls-vMuhwbQYXqafiT24bg3H0z1Yo3ipuEbGDScBzgMw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~Fj0rfCSRA48VhQeVbAmTtZ604Np3pmc3onOZo6caSAtdAZuHhRYHwV8OW6W_jfZeZvYUJYiM4I1rfgm2leBryw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~Fj0rfCSRA48VhQeVbAmTtZ604Np3pmc3onOZo6caSAtdAZuHhRYHwV8OW6W_jfZeZvYUJYiM4I1rfgm2leBryw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~G68qXmZVzZXiHq_T2TlEzOiM8RWBNp319rR966JqSeWnlS5tvNi1ZnsHs0X6MM1Nqt8lT2PGce0VBQEZGEPWDw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~G68qXmZVzZXiHq_T2TlEzOiM8RWBNp319rR966JqSeWnlS5tvNi1ZnsHs0X6MM1Nqt8lT2PGce0VBQEZGEPWDw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~SLeLt8lKVQCChtgVef_SA3X4FpyKn2Oogk9YHpVbChFyzoOO3kTi3lsAHg5HUTdtO-52Kom1sv1YFBuYe83X9A==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~SLeLt8lKVQCChtgVef_SA3X4FpyKn2Oogk9YHpVbChFyzoOO3kTi3lsAHg5HUTdtO-52Kom1sv1YFBuYe83X9A== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~U-MMVGlo6VNjyI9x3g9-HsSrRB4iLjo-Ss1ma8FuydvBPbrRuTeOsnl678_GHdBv7qKb40vbODYiXixRHaL4cg==: -------------------------------------------------------------------------------- 1 | [{"name":"cococoKitTests-3A31CEFC-E540-4AF2-90CA-3B41FBA83999.xctestconfiguration","type":1}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~UqU2a4503F4gImKaTQC3-NvC-hvKwXLLKn2jvU777iA5u2wnpWfRvhQcXfk7BNfemW2tB-vHEzEmsv2yxTvbSw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~UqU2a4503F4gImKaTQC3-NvC-hvKwXLLKn2jvU777iA5u2wnpWfRvhQcXfk7BNfemW2tB-vHEzEmsv2yxTvbSw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~V5N20g2tbfNtC6P_FOmeIJzg9OaMCjCPtB1sE1SsOq9GEEOnP3yh_eCLeqJy7teeZYU3Uq8jWbqqnJ3zpJWVqQ==: -------------------------------------------------------------------------------- 1 | [{"name":"remote-container","type":2}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~XFNRKtSxJZ8r0lwLSEqTziyzqR8_7d5BblTSp4ItyJFPvDRGVaUec4oekqfCXJEVO9a6ujXmBsjlCrwHWNuIgA==: -------------------------------------------------------------------------------- 1 | [{"name":"cococoKitTests-7688EF9A-4563-4AFD-8FB9-5EF360680FA4.xctestconfiguration","type":1}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~Y0VetVEvhnBc2qz8RJCUYcL842qfqvSevY8OB-wcQvAP_H4On3JScWWWn6uPGt-810JiN5qqaNQg4oRO0-jpDw==: -------------------------------------------------------------------------------- 1 | [{"name":"remote-container","type":2}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~YrizJ0L-df_j4QZQ4ML2mZIil7N8h1aB8MleOBoyrf_r1l8CwpYwivatCeSvqbBf05A_-UQlAV1xT2qMeC-VVg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~YrizJ0L-df_j4QZQ4ML2mZIil7N8h1aB8MleOBoyrf_r1l8CwpYwivatCeSvqbBf05A_-UQlAV1xT2qMeC-VVg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~aQuuYLb-TKyYZtcAWj6Fx63Y1DomF-ssVZor3npByulK0GATZfYViD8JboHNjz6BwV0xbcVp7R0yt6OYVrTFMQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~aQuuYLb-TKyYZtcAWj6Fx63Y1DomF-ssVZor3npByulK0GATZfYViD8JboHNjz6BwV0xbcVp7R0yt6OYVrTFMQ== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~cPmsKVMixUukUBjUrD2QkE7mOethVpIPNH_RUshp-3qj1X7zIPv6PzNpo_evtT1HGn1vyZ5Nc9n2wliy4HBfzQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~cPmsKVMixUukUBjUrD2QkE7mOethVpIPNH_RUshp-3qj1X7zIPv6PzNpo_evtT1HGn1vyZ5Nc9n2wliy4HBfzQ== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~cm12k-Ps7aJ4GrJt7wyuRj8XNsiWydV7wx4SMBnv0HCA8tsaQSL0gtrryRqtR-1t5Zvk3SzNhSG5DSvj84X75Q==: -------------------------------------------------------------------------------- 1 | [{"name":"7688EF9A-4563-4AFD-8FB9-5EF360680FA4","type":2}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~fnScc6uwLeUOtP1wtZlnqtFmvEGAllShITIhX3BeZgyOFeOB2gl5_o449t_l-eg3Qi421YTdEshk3I9x0ZOCGg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~fnScc6uwLeUOtP1wtZlnqtFmvEGAllShITIhX3BeZgyOFeOB2gl5_o449t_l-eg3Qi421YTdEshk3I9x0ZOCGg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~gsDKNmFTosKDqM22lZ1qRkVmAfnfo0oULz3_43S_9WPMFZIycyK38DKyUVr5CqpYYHsR7ACb4ptkTgpAwmqOBg==: -------------------------------------------------------------------------------- 1 | [{"name":"tmp","type":2}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~juhI1raJ5S700ABcImgZVK-YOVPZ8e4gO3uZCVa0C1l34a18auJLksa8Hj6d8yZwSpB-05wwBB0vDxNP-JCZZA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~juhI1raJ5S700ABcImgZVK-YOVPZ8e4gO3uZCVa0C1l34a18auJLksa8Hj6d8yZwSpB-05wwBB0vDxNP-JCZZA== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~oKjVlRvWisdmloxst_ebPvfm1egBj903jOxknh_ZmlJJiktpEA3NkCUU1-ovPZQPFbpIKHXAnvBzTFfPB6ZzhQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~oKjVlRvWisdmloxst_ebPvfm1egBj903jOxknh_ZmlJJiktpEA3NkCUU1-ovPZQPFbpIKHXAnvBzTFfPB6ZzhQ== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~p6GGgLAcpnkTXmB_i0bgIdxUy1UY07e5xHTA1r_zNkzMe_CK5w9WUbIq9lm9MtSPEaQT8LAoflr6rpKsu5_PnA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~p6GGgLAcpnkTXmB_i0bgIdxUy1UY07e5xHTA1r_zNkzMe_CK5w9WUbIq9lm9MtSPEaQT8LAoflr6rpKsu5_PnA== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~qd9e6ooeKrMz43BCHtdlFtGqUm29HTUedZV34c6zJC_2Yo3KjW8IR398N7y6SmofRF93y4GvY9QW5YuFdo8wZg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~qd9e6ooeKrMz43BCHtdlFtGqUm29HTUedZV34c6zJC_2Yo3KjW8IR398N7y6SmofRF93y4GvY9QW5YuFdo8wZg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~rlyQM6UGPphiQJf3tw_DH-YdR9H1fREkapmc4-sI_JwVXqKPOXUgcgyM1SqgFvw1ItJb8k3VdNKCFwpsNFY10g==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~rlyQM6UGPphiQJf3tw_DH-YdR9H1fREkapmc4-sI_JwVXqKPOXUgcgyM1SqgFvw1ItJb8k3VdNKCFwpsNFY10g== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~tFDRQK08gMZAKbFKrDwZPg17dEe4Fcef4Wfh0Ui7F653X9zGL1xbAGp7w3Uzb4hb73cy-PzWFJzgVxZiRiXO8w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~tFDRQK08gMZAKbFKrDwZPg17dEe4Fcef4Wfh0Ui7F653X9zGL1xbAGp7w3Uzb4hb73cy-PzWFJzgVxZiRiXO8w== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~tta5TbL6EQkBtFy54Qdw7uKPBlHi7NMWXXwtEsYlPz5AQCtEwWUVd1xkCOJA60KgRr5N4gimH2yp54_QiE0Jfg==: -------------------------------------------------------------------------------- 1 | [{"name":"tmp","type":2}] -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/data.0~wwEG-hauljIcgt3ZtMdcQfbmdDVGUzs2boUcNrlJ4kEWkqgFzw4FRJLQbfGZV_x8NUOqaPD54BkdPBdIivQprQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/data.0~wwEG-hauljIcgt3ZtMdcQfbmdDVGUzs2boUcNrlJ4kEWkqgFzw4FRJLQbfGZV_x8NUOqaPD54BkdPBdIivQprQ== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~-_8T-OEcNdhNpew23wZ1ZB7LgoiZPincZVDUFRQy387NyUQwImjY_xrgx8FMFiN2ySYVHX3aYyZ3C4EdTcQphA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~-_8T-OEcNdhNpew23wZ1ZB7LgoiZPincZVDUFRQy387NyUQwImjY_xrgx8FMFiN2ySYVHX3aYyZ3C4EdTcQphA== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~-qtwNp_f2fZo_-ax58Um1nBOqq_LawMVrHsxkHl3sadhvHaKZnODnZCWKpoquAH6Vf0PkeJwUW9m4yq0Wiguyg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~-qtwNp_f2fZo_-ax58Um1nBOqq_LawMVrHsxkHl3sadhvHaKZnODnZCWKpoquAH6Vf0PkeJwUW9m4yq0Wiguyg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~24sw3mMVu0yiZqYlmUscqy9CMHTOJT9PXCqC1XYlhqeOtmN-b-LVlSyTWQQZWphu_s6HSqSAe1jV10p_3rM-vw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~50zlzOBEe6Cggikt3hzMlOoqNy0Meu30qJuV2Atupzh-yUUNGc6t3DnmQGDsepvnUItUjQEcQrH3omfmHAlddg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~50zlzOBEe6Cggikt3hzMlOoqNy0Meu30qJuV2Atupzh-yUUNGc6t3DnmQGDsepvnUItUjQEcQrH3omfmHAlddg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~6NUkuq5en2H9TIGnPhxm_XI1mTyGbp0mk2xmlGFS_fE1w83m-s0eaAgzT8jLavDVsomSV_fj3gyEeNz8-l-0AQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~7f9IXX-kICx4FpA_jCXfMN3T08MzcfpJPwzSE-n0RbJq0p4hxnOwjikwCbtaAhHizMMskKlJlSABi-XFz0jKcg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~7f9IXX-kICx4FpA_jCXfMN3T08MzcfpJPwzSE-n0RbJq0p4hxnOwjikwCbtaAhHizMMskKlJlSABi-XFz0jKcg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~94NzaW5woF3BNyOqqO5h7zYhCpT07MiSMMoxX6UKCSHls-vMuhwbQYXqafiT24bg3H0z1Yo3ipuEbGDScBzgMw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~Fj0rfCSRA48VhQeVbAmTtZ604Np3pmc3onOZo6caSAtdAZuHhRYHwV8OW6W_jfZeZvYUJYiM4I1rfgm2leBryw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~G68qXmZVzZXiHq_T2TlEzOiM8RWBNp319rR966JqSeWnlS5tvNi1ZnsHs0X6MM1Nqt8lT2PGce0VBQEZGEPWDw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~G68qXmZVzZXiHq_T2TlEzOiM8RWBNp319rR966JqSeWnlS5tvNi1ZnsHs0X6MM1Nqt8lT2PGce0VBQEZGEPWDw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~SLeLt8lKVQCChtgVef_SA3X4FpyKn2Oogk9YHpVbChFyzoOO3kTi3lsAHg5HUTdtO-52Kom1sv1YFBuYe83X9A==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~SLeLt8lKVQCChtgVef_SA3X4FpyKn2Oogk9YHpVbChFyzoOO3kTi3lsAHg5HUTdtO-52Kom1sv1YFBuYe83X9A== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~U-MMVGlo6VNjyI9x3g9-HsSrRB4iLjo-Ss1ma8FuydvBPbrRuTeOsnl678_GHdBv7qKb40vbODYiXixRHaL4cg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~U-MMVGlo6VNjyI9x3g9-HsSrRB4iLjo-Ss1ma8FuydvBPbrRuTeOsnl678_GHdBv7qKb40vbODYiXixRHaL4cg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~UqU2a4503F4gImKaTQC3-NvC-hvKwXLLKn2jvU777iA5u2wnpWfRvhQcXfk7BNfemW2tB-vHEzEmsv2yxTvbSw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~V5N20g2tbfNtC6P_FOmeIJzg9OaMCjCPtB1sE1SsOq9GEEOnP3yh_eCLeqJy7teeZYU3Uq8jWbqqnJ3zpJWVqQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~V5N20g2tbfNtC6P_FOmeIJzg9OaMCjCPtB1sE1SsOq9GEEOnP3yh_eCLeqJy7teeZYU3Uq8jWbqqnJ3zpJWVqQ== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~XFNRKtSxJZ8r0lwLSEqTziyzqR8_7d5BblTSp4ItyJFPvDRGVaUec4oekqfCXJEVO9a6ujXmBsjlCrwHWNuIgA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~XFNRKtSxJZ8r0lwLSEqTziyzqR8_7d5BblTSp4ItyJFPvDRGVaUec4oekqfCXJEVO9a6ujXmBsjlCrwHWNuIgA== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~Y0VetVEvhnBc2qz8RJCUYcL842qfqvSevY8OB-wcQvAP_H4On3JScWWWn6uPGt-810JiN5qqaNQg4oRO0-jpDw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~Y0VetVEvhnBc2qz8RJCUYcL842qfqvSevY8OB-wcQvAP_H4On3JScWWWn6uPGt-810JiN5qqaNQg4oRO0-jpDw== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~YrizJ0L-df_j4QZQ4ML2mZIil7N8h1aB8MleOBoyrf_r1l8CwpYwivatCeSvqbBf05A_-UQlAV1xT2qMeC-VVg==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~aQuuYLb-TKyYZtcAWj6Fx63Y1DomF-ssVZor3npByulK0GATZfYViD8JboHNjz6BwV0xbcVp7R0yt6OYVrTFMQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~cPmsKVMixUukUBjUrD2QkE7mOethVpIPNH_RUshp-3qj1X7zIPv6PzNpo_evtT1HGn1vyZ5Nc9n2wliy4HBfzQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~cm12k-Ps7aJ4GrJt7wyuRj8XNsiWydV7wx4SMBnv0HCA8tsaQSL0gtrryRqtR-1t5Zvk3SzNhSG5DSvj84X75Q==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~cm12k-Ps7aJ4GrJt7wyuRj8XNsiWydV7wx4SMBnv0HCA8tsaQSL0gtrryRqtR-1t5Zvk3SzNhSG5DSvj84X75Q== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~fnScc6uwLeUOtP1wtZlnqtFmvEGAllShITIhX3BeZgyOFeOB2gl5_o449t_l-eg3Qi421YTdEshk3I9x0ZOCGg==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~gsDKNmFTosKDqM22lZ1qRkVmAfnfo0oULz3_43S_9WPMFZIycyK38DKyUVr5CqpYYHsR7ACb4ptkTgpAwmqOBg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~gsDKNmFTosKDqM22lZ1qRkVmAfnfo0oULz3_43S_9WPMFZIycyK38DKyUVr5CqpYYHsR7ACb4ptkTgpAwmqOBg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~juhI1raJ5S700ABcImgZVK-YOVPZ8e4gO3uZCVa0C1l34a18auJLksa8Hj6d8yZwSpB-05wwBB0vDxNP-JCZZA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~oKjVlRvWisdmloxst_ebPvfm1egBj903jOxknh_ZmlJJiktpEA3NkCUU1-ovPZQPFbpIKHXAnvBzTFfPB6ZzhQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~p6GGgLAcpnkTXmB_i0bgIdxUy1UY07e5xHTA1r_zNkzMe_CK5w9WUbIq9lm9MtSPEaQT8LAoflr6rpKsu5_PnA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~qd9e6ooeKrMz43BCHtdlFtGqUm29HTUedZV34c6zJC_2Yo3KjW8IR398N7y6SmofRF93y4GvY9QW5YuFdo8wZg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~qd9e6ooeKrMz43BCHtdlFtGqUm29HTUedZV34c6zJC_2Yo3KjW8IR398N7y6SmofRF93y4GvY9QW5YuFdo8wZg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~rlyQM6UGPphiQJf3tw_DH-YdR9H1fREkapmc4-sI_JwVXqKPOXUgcgyM1SqgFvw1ItJb8k3VdNKCFwpsNFY10g==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~tFDRQK08gMZAKbFKrDwZPg17dEe4Fcef4Wfh0Ui7F653X9zGL1xbAGp7w3Uzb4hb73cy-PzWFJzgVxZiRiXO8w==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~tta5TbL6EQkBtFy54Qdw7uKPBlHi7NMWXXwtEsYlPz5AQCtEwWUVd1xkCOJA60KgRr5N4gimH2yp54_QiE0Jfg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysugr/cococo/91ffaac46651879d648009db79e86c25ddf88998/cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~tta5TbL6EQkBtFy54Qdw7uKPBlHi7NMWXXwtEsYlPz5AQCtEwWUVd1xkCOJA60KgRr5N4gimH2yp54_QiE0Jfg== -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Data/refs.0~wwEG-hauljIcgt3ZtMdcQfbmdDVGUzs2boUcNrlJ4kEWkqgFzw4FRJLQbfGZV_x8NUOqaPD54BkdPBdIivQprQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/Example.xcresult/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | dateCreated 6 | 2020-01-14T13:44:04Z 7 | externalLocations 8 | 9 | rootId 10 | 11 | hash 12 | 0~4ksLvO0iTqbUzy0bkQinxNdAfUvXv-kCvLd54YrUszvaQFoRjAT2Q2wuOpGqTmxOm-AqwYwASPtVV0dqrYzo6g== 13 | 14 | storage 15 | 16 | backend 17 | fileBacked2 18 | compression 19 | standard 20 | 21 | version 22 | 23 | major 24 | 3 25 | minor 26 | 21 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /cococoLibraryTests/Assets/ExampleResult.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /cococoLibraryTests/BashTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BashTests.swift 3 | // cococoLibraryTests 4 | // 5 | // Created by Michael Heinzl on 14.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import cococoLibrary 11 | 12 | class BashTests: XCTestCase { 13 | 14 | var sut: Bash! 15 | 16 | override func setUp() { 17 | super.setUp() 18 | 19 | sut = Bash() 20 | } 21 | 22 | func testSimpleCommand() throws { 23 | let output = try sut.execute(commandName: "echo", arguments: ["asdf"]) 24 | XCTAssertEqual(output.trimmingCharacters(in: .whitespacesAndNewlines), "asdf") 25 | } 26 | 27 | func testUnkownCommand() { 28 | XCTAssertThrowsError(try sut.execute(commandName: "fooBarUnkownCommand")) { (error) in 29 | XCTAssertEqual(error as! Bash.Error, Bash.Error.failed(terminationStatus: 1)) 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /cococoLibraryTests/ConverterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConverterTests.swift 3 | // cococoKitTests 4 | // 5 | // Created by Michael Heinzl on 14.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import cococoLibrary 11 | 12 | class ConverterTests: XCTestCase { 13 | 14 | var sut: Converter! 15 | 16 | override func setUp() { 17 | super.setUp() 18 | 19 | sut = Converter() 20 | } 21 | 22 | func testExample() throws { 23 | let result = try sut.convert([XCResultExamples.example], excludedFileExtensions: nil) 24 | let expectedResult = try String(contentsOf: XCResultExamples.exampleResult) 25 | XCTAssertEqual(result, expectedResult) 26 | } 27 | 28 | func testExcludeSingleFilePaths() { 29 | let filePaths = [ 30 | "foo/bar/file1.swift", 31 | "asdf/foo.h", 32 | "asdf/foo.m", 33 | "asdf/bar.m", 34 | "file2.swift" 35 | ] 36 | let excludedFileExtensions = [".swift"] 37 | let expectedPaths = [ 38 | "asdf/foo.h", 39 | "asdf/foo.m", 40 | "asdf/bar.m" 41 | ] 42 | let resultingPaths = sut.filterFilePaths(filePaths, excludedFileExtensions: excludedFileExtensions) 43 | XCTAssertEqual(resultingPaths, expectedPaths) 44 | } 45 | 46 | func testExcludeMultipleFilePaths() { 47 | let filePaths = [ 48 | "foo/bar/file1.swift", 49 | "asdf/foo.h", 50 | "asdf/foo.m", 51 | "asdf/bar.m", 52 | "file2.swift" 53 | ] 54 | let excludedFileExtensions = [".m", ".h"] 55 | let expectedPaths = [ 56 | "foo/bar/file1.swift", 57 | "file2.swift", 58 | ] 59 | let resultingPaths = sut.filterFilePaths(filePaths, excludedFileExtensions: excludedFileExtensions) 60 | XCTAssertEqual(resultingPaths, expectedPaths) 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /cococoLibraryTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /cococoLibraryTests/XCResultExamples.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCResultExamples.swift 3 | // cococoKitTests 4 | // 5 | // Created by Michael Heinzl on 14.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | private class Token {} 12 | let testBundle = Bundle(for: Token.self) 13 | 14 | struct XCResultExamples { 15 | 16 | static let example = testBundle.path(forResource: "Example", ofType: "xcresult")! 17 | static let exampleResult = URL(fileURLWithPath: testBundle.path(forResource: "ExampleResult", ofType: "xml")!) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cococoLibraryTests/XMLEscaperExamples.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XMLEscaperExamples.swift 3 | // cococoKitTests 4 | // 5 | // Created by Michael Heinzl on 14.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct XMLEscaperExamples { 12 | 13 | static let longExample = """ 14 | 15 | 16 | 1 17 | http://1.bp.foobar.com/-zvS_6Q1IzR8/T5l6qvnRmcI/AAAAAAAABcc/HXO7HDEJKo0/ 18 | 19 | 20 | 2 21 | John 22 | Doe 23 | http://4.bp.foobar.com/_xR71w9-qx9E/SrAz--pu0MI/AAAAAAAAC38/2ZP28rVEFKc/s200/ 24 | 25 | 26 | 3 27 | http://asdf.com/files/234234.jpg 28 | 29 | 30 | """ 31 | 32 | static let longEscapedExample = """ 33 | <employees> 34 | <employee> 35 | <id>1</id> 36 | <photo>http://1.bp.foobar.com/-zvS_6Q1IzR8/T5l6qvnRmcI/AAAAAAAABcc/HXO7HDEJKo0/</photo> 37 | </employee> 38 | <employee> 39 | <id>2</id> 40 | <firstName>John</firstName> 41 | <lastName>Doe</lastName> 42 | <photo>http://4.bp.foobar.com/_xR71w9-qx9E/SrAz--pu0MI/AAAAAAAAC38/2ZP28rVEFKc/s200/</photo> 43 | </employee> 44 | <employee> 45 | <id>3</id> 46 | <photo>http://asdf.com/files/234234.jpg</photo> 47 | </employee> 48 | </employees> 49 | """ 50 | 51 | } 52 | -------------------------------------------------------------------------------- /cococoLibraryTests/XMLEscaperTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XMLEscaperTests.swift 3 | // cococoKitTests 4 | // 5 | // Created by Michael Heinzl on 14.01.20. 6 | // Copyright © 2020 mySugr GmbH. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import cococoLibrary 11 | 12 | class XMLEscaperTests: XCTestCase { 13 | 14 | var sut: XMLEscaper! 15 | 16 | override func setUp() { 17 | super.setUp() 18 | 19 | sut = XMLEscaper() 20 | } 21 | 22 | func testSingleReplacments() { 23 | XCTAssertEqual(sut.escape("&"), "&") 24 | XCTAssertEqual(sut.escape("'"), "'") 25 | XCTAssertEqual(sut.escape("\""), """) 26 | XCTAssertEqual(sut.escape("<"), "<") 27 | XCTAssertEqual(sut.escape(">"), ">") 28 | } 29 | 30 | func testLongExampleText() { 31 | XCTAssertEqual(sut.escape(XMLEscaperExamples.longExample), XMLEscaperExamples.longEscapedExample) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | # app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app 2 | # apple_id("[[APPLE_ID]]") # Your Apple email address 3 | 4 | 5 | # For more information about the Appfile, see: 6 | # https://docs.fastlane.tools/advanced/#appfile 7 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:mac) 17 | 18 | platform :mac do 19 | 20 | before_all do 21 | setup_circle_ci 22 | end 23 | 24 | lane :test do 25 | scan( 26 | scheme: "cococo", 27 | derived_data_path: "derived_data", 28 | destination: "platform=OS X,arch=x86_64", 29 | clean: true, 30 | code_coverage: true, 31 | include_simulator_logs: false, 32 | disable_slide_to_type: false 33 | ) 34 | end 35 | 36 | lane :build do 37 | gym( 38 | scheme: "cococo", 39 | derived_data_path: "derived_data", 40 | destination: "platform=OS X,arch=x86_64", 41 | output_directory: "output" 42 | ) 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew cask install fastlane` 16 | 17 | # Available Actions 18 | ## Mac 19 | ### mac test 20 | ``` 21 | fastlane mac test 22 | ``` 23 | 24 | ### mac build 25 | ``` 26 | fastlane mac build 27 | ``` 28 | 29 | 30 | ---- 31 | 32 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 33 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 34 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 35 | --------------------------------------------------------------------------------