├── .github ├── CONTRIBUTING.md └── PULL_REQUEST_TEMPLATE.md ├── .travis.yml ├── LICENSE ├── README.md ├── backup └── extract-libdispatch-binaries.sh ├── ci └── execute_script.sh ├── swift-development ├── swift-ubuntu-trusty │ ├── .vim │ │ ├── CMakeLists.txt │ │ ├── autoload │ │ │ └── plug.vim │ │ ├── ftdetect │ │ │ ├── sil.vim │ │ │ ├── swift.vim │ │ │ └── swiftgyb.vim │ │ ├── ftplugin │ │ │ ├── swift.vim │ │ │ └── swiftgyb.vim │ │ └── syntax │ │ │ ├── sil.vim │ │ │ ├── swift.vim │ │ │ └── swiftgyb.vim │ ├── .vimrc │ └── Dockerfile └── swift-ubuntu-xenial-multiarch │ ├── .DS_Store │ ├── amd64 │ ├── .vim │ │ ├── CMakeLists.txt │ │ ├── autoload │ │ │ └── plug.vim │ │ ├── ftdetect │ │ │ ├── sil.vim │ │ │ ├── swift.vim │ │ │ └── swiftgyb.vim │ │ ├── ftplugin │ │ │ ├── swift.vim │ │ │ └── swiftgyb.vim │ │ └── syntax │ │ │ ├── sil.vim │ │ │ ├── swift.vim │ │ │ └── swiftgyb.vim │ ├── .vimrc │ └── Dockerfile │ ├── manifest.yml │ └── s390x │ └── Dockerfile ├── swift-runtime ├── swift-ubuntu-trusty │ └── Dockerfile └── swift-ubuntu-xenial-multiarch │ ├── .DS_Store │ ├── amd64 │ └── Dockerfile │ ├── manifest.yml │ └── s390x │ └── Dockerfile ├── ubuntu-14.04 └── Dockerfile ├── ubuntu-16.04 └── Dockerfile └── utils ├── common-utils.sh ├── run-utils.sh └── tools-utils.sh /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome contributions, and request you follow these guidelines. 4 | 5 | - [Raising issues](#raising-issues) 6 | - [Contributor License Agreement](#contributor-license-agreement) 7 | - [Guidelines](#guidelines) 8 | 9 | ## Raising issues 10 | 11 | Please raise any bug reports on the issue tracker. Be sure to 12 | search the list to see if your issue has already been raised. 13 | 14 | A good bug report is one that make it easy for us to understand what you were 15 | trying to do and what went wrong. Provide as much context as possible so we can try to recreate the issue. 16 | 17 | ### Contributor License Agreement 18 | 19 | In order for us to accept pull-requests, the contributor must first complete 20 | a Contributor License Agreement (CLA). Please see our [CLA repo](http://github.com/IBM-Swift/CLA) for more information. 21 | 22 | This clarifies the intellectual property license granted with any contribution. It is for your protection as a 23 | Contributor as well as the protection of IBM and its customers; it does not 24 | change your rights to use your own Contributions for any other purpose. 25 | 26 | ### Guidelines 27 | 28 | Please ensure you follow these guidelines: 29 | 30 | - All files must have the Apache license in the header. 31 | - All PRs must have passing builds. -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Motivation and Context 7 | 8 | 9 | 10 | ## How Has This Been Tested? 11 | 12 | 13 | 14 | 15 | ## Checklist: 16 | 17 | 18 | - [ ] I have submitted a [CLA form](https://github.com/IBM-Swift/CLA) 19 | - [ ] If applicable, I have updated the documentation accordingly. 20 | - [ ] If applicable, I have added tests to cover my changes. 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Travis CI build file for swift-ubuntu image. 2 | # See the following URLs for further details on Travis CI 3 | # https://docs.travis-ci.com/user/customizing-the-build/ 4 | # https://docs.travis-ci.com/user/docker/ 5 | # https://docs.travis-ci.com/user/multi-os/ 6 | 7 | language: generic 8 | 9 | # whitelist (branches that should be built) 10 | branches: 11 | only: 12 | - master 13 | - develop 14 | - /^issue.*$/ 15 | 16 | notifications: 17 | slack: 18 | secure: "VFUQIBCL8Kiubw7ojN3oJOs2TgobYaAZTCQePDATOMSRKRo/rDgsloGDc3kqGkLb0lAwky1lwKQjnRUsG1mEES6+W2K3QWsmzpTR1owPzZprrHrL/h1vkWdysx7ed0dBnbs8uhtD4iPe46vWZqLc1ZyfV8QxefTD9mrS4VeH7rd4qOwMgkjphaoVc0/cOkt0u8p54961HLVt4euSZf0766hfYH+1EwvoShaiK/2aKTF/hmFavB2iASHRXJnOm9S4iDWyFW2D7XEwoo9o9jOAqtYbVefGglCjUymmuNCmj1bE3NSWXJB/5KC8xFNYs7b5jZ19diu5PQK2K1HCtJvLhW2wv7cBfBFrluvz52zeHB8izYIiSV+sr6mJgnPuwaoYUObJWkLlKpTo3oPgAU/62l0KMgdn1EoBrCSDVCz5IBjLmty25nFl1oDGZITQjNIkIMUjh4dojjr+JSRDumHxje39bu8nvxsA5pxDulnWQNorvaHeWf8t2ZAqYW/ojpAlmvBr7E+U9P6DHw40FDStcI8bJGfWv8yybjMocYtTTl6FaQdfqNm3Afp5wlUxNAkAG2neRGnuitHTQ4CBHquA9NG4c7tlyafUf9UMuce3ikQiUeecNnrW2tLkKEnkO6KXwgvOCAyQrFMHncPWXfQVY/+c/2ejelCOUW8BL2pBLBY=" 19 | 20 | sudo: required 21 | services: docker 22 | 23 | # after_success failure doesn't fail build: https://github.com/travis-ci/travis-ci/issues/758 24 | script: 25 | - source ./ci/execute_script.sh 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status - Master](https://travis-ci.org/IBM-Swift/swift-ubuntu-docker.svg?branch=master)](https://travis-ci.org/IBM-Swift/swift-ubuntu-docker) 2 | 3 | # Swift 5 - Ubuntu Docker 4 | 5 | This repo contains the code for generating two Docker images for Swift: 6 | 7 | - The `ibmcom/swift-ubuntu` image contains the Swift 5.0.2 RELEASE toolchain as well as the dependencies for running Kitura-based applications. Our development team uses this image for development and testing of Swift 5 applications on the Linux Ubuntu (v14.04) operating system. 8 | - The `ibmcom/swift-ubuntu-runtime` image contains only those libraries (`.so` files) provided by the Swift 5.0.2 RELEASE toolchain that are required to run Swift applications. Note that this image does not contain SwiftPM or any of the build tools used when compiling and linking Swift applications. Hence, the size for the `ibmcom/swift-ubuntu-runtime` image (~300 MB) is much smaller than that of the `ibmcom/swift-ubuntu` image. The `ibmcom/swift-ubuntu-runtime` image is ideal for provisioning your Swift application as an [IBM Container](https://www.ibm.com/cloud-computing/bluemix/containers) on the IBM Cloud. 9 | 10 | - The `ibmcom/swift-ubuntu-xenial` and `ibmcom/swift-ubuntu-xenial-runtime` images follow a similar convention, but for Linux Ubuntu 16.04. These images are multi-arch so will pull down the appropriate image for your architecture. We currently offer support for `amd64` and `s390x` architectures. 11 | 12 | # Recent updates 13 | 1. Upgraded to the Swift 5.0.2 RELEASE binaries. 14 | 2. Changed location of Swift binaries and libraries so they are available system wide (not just for the `root` user). 15 | 3. Reduced number of layers in images. 16 | 4. Removed system packages no longer needed. 17 | 5. Aligned version of Ubuntu with version found in Cloud Foundry environments (v14.04). 18 | 6. Reduced size of the Docker image. 19 | 7. Updated Dockerfiles per guidelines in [Best practices for writing Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/). 20 | 8. Added Support for amd64 and s390x architectures of Xenial Linux Ubuntu 16.04. 21 | 22 | 23 | 24 | # Quick Start 25 | 26 | The easiest way to get started is by using the Kitura command line tools to generate the docker files needed, and copy them over to your project. If you just want to explore our supported base images, see the next sections. 27 | 28 | To get started with `kitura init`: 29 | 30 | 1. Create a new directory, change into it and run [`kitura init`](https://www.kitura.io/docs/getting-started/create-server-cli.html#). This will generate a project which will include two files named `Dockerfile` and `Dockerfile-tools`. 31 | 2. Copy the `Dockerfile` and `Dockerfile-tools` files into your project's root directory (this is the directory that contains your `Package.swift` file and the Sources and Tests folders). 32 | 3. Edit the `Dockerfile` in a text editor and replace references to your `kitura init` folder with the name of your project. `Dockerfile-Tools` has preconfigured behavior to download and compile Swift binaries and copy the executable into your application. It doesn't need editing. 33 | 4. Run the following commands, replacing YOUR_PROJECT with the name of your project. **Note:** Use all lower case letters for your projects name and replace spaces with dashes. 34 | 1. `docker build -t YOUR_PROJECT-build -f Dockerfile-tools .` 35 | 2. `docker run -v $PWD:/root/project -w /root/project YOUR_PROJECT-build /swift-utils/tools-utils.sh build release` 36 | 3. `docker run -it -p 8090:8080 -v $PWD:/root/project -w /root/project YOUR_PROJECT-run sh -c ".build-ubuntu/release/YOUR_PROJECT"` 37 | 38 | `Dockerfile-tools` is responsible for downloading the Swift binaries and builds the exectuables. 39 | 40 | The `Dockerfile` then copies the applications source code, and then compiled executable into the runtime image of the application. This means the large Swift binary file isn't copied into your application, and reduces the overall size of your app, meaning faster uploads and a smaller storage quota impact. 41 | 42 | The final command runs your Docker image locally. 43 | 44 | This was the quickest way to get started, but if you just want see explore our base images then see the following sections for detailed instructions. 45 | 46 | 47 | # ibmcom/swift-ubuntu 48 | ## Pulling ibmcom/swift-ubuntu from Docker Hub 49 | Run the following command to download the latest version of the `ibmcom/swift-ubuntu` image from Docker Hub: 50 | 51 | ``` 52 | docker pull ibmcom/swift-ubuntu:latest 53 | ``` 54 | 55 | ### Use a specific version of ibmcom/swift-ubuntu 56 | Docker images are tagged with Swift version number. To use the Swift 5.0.2 image from Docker Hub, issue the following command: 57 | 58 | ``` 59 | docker pull ibmcom/swift-ubuntu:5.0.2 60 | ``` 61 | 62 | ## Using ibmcom/swift-ubuntu for development 63 | Mount a folder on your host to your Docker container using the following command: 64 | 65 | ``` 66 | docker run -i -t -v :/ ibmcom/swift-ubuntu:5.0.2 67 | ``` 68 | 69 | After executing the above command, you will have terminal access to the Docker container (the default command for the image is `/bin/bash`). This will allow you to build, test, and run your Swift application in a Linux environment (Ubuntu v14.04). 70 | 71 | ## Privileged mode 72 | If you attempt to run the Swift REPL and you get the error `failed to launch REPL process: process launch failed: 'A' packet returned an error: 8`, then you should run your Docker container in privileged mode: 73 | 74 | ``` 75 | docker run --privileged -i -t ibmcom/swift-ubuntu:5.0.2 76 | ``` 77 | 78 | This issue is described at https://bugs.swift.org/browse/SR-54. 79 | 80 | # ibmcom/swift-ubuntu-xenial 81 | ## Pulling ibmcom/swift-ubuntu-xenial from Docker Hub 82 | Run the following command to download the latest version of the `ibmcom/swift-ubuntu-xenial` image from Docker Hub: 83 | 84 | ``` 85 | docker pull ibmcom/swift-ubuntu-xenial:latest 86 | ``` 87 | This image supports both amd64 and s390x architectures and will pull down the correct image based on the architecture you are using i.e. `ibmcom/swift-ubuntu-xenial-amd64` or `ibmcom/swift-ubuntu-xenial-s390x`. 88 | 89 | ## Using ibmcom/swift-ubuntu-xenial for development 90 | Mount a folder on your host to your Docker container using the following command: 91 | 92 | ``` 93 | docker run -i -t -v :/ ibmcom/swift-ubuntu-xenial:latest 94 | ``` 95 | 96 | After executing the above command, you will have terminal access to the Docker container (the default command for the image is `/bin/bash`). This will allow you to build, test, and run your Swift application in a Linux environment (Ubuntu v16.04, amd64 or s390x), depending on your architecture. 97 | 98 | ## Privileged mode 99 | If you attempt to run the Swift REPL and you get the error `failed to launch REPL process: process launch failed: 'A' packet returned an error: 8`, then you should run your Docker container in privileged mode: 100 | 101 | ``` 102 | docker run --privileged -i -t ibmcom/swift-ubuntu-xenial:latest 103 | ``` 104 | 105 | This issue is described at https://bugs.swift.org/browse/SR-54. 106 | 107 | # ibmcom/swift-ubuntu-runtime 108 | ## Pulling ibmcom/swift-ubuntu-runtime from Docker Hub 109 | Run the following command to download the latest version of the `ibmcom/swift-ubuntu-runtime` image from Docker Hub: 110 | 111 | ``` 112 | docker pull ibmcom/swift-ubuntu-runtime:latest 113 | ``` 114 | 115 | ### Use a specific version of ibmcom/swift-ubuntu-runtime 116 | Docker images are now tagged with Swift version number. To use the Swift 5.0.2 image from Docker Hub, issue the following command: 117 | 118 | ``` 119 | docker pull ibmcom/swift-ubuntu-runtime:5.0.2 120 | ``` 121 | 122 | ## Using ibmcom/swift-ubuntu-runtime 123 | You can extend the `ibmcom/swift-ubuntu-runtime` image in your own Dockerfile to add your Swift application binaries (and any other dependencies you may need). For instance, the next sample Dockerfile simply adds the binaries for the [Kitura-Starter](https://github.com/IBM-Bluemix/Kitura-Starter) application and specifies the command to start the server (total image size after adding the Kitura-Starter binaries is ~300MB): 124 | 125 | ``` 126 | # Builds a Docker image for running the Kitura-Starter sample application. 127 | 128 | ... 129 | 130 | FROM ibmcom/swift-ubuntu-runtime:5.0.2 131 | LABEL Description="Docker image for running the Kitura-Starter sample application." 132 | 133 | USER root 134 | 135 | # Expose default port for Kitura 136 | EXPOSE 8080 137 | 138 | # Binaries should have been compiled against the correct platform (i.e. Ubuntu 14.04). 139 | RUN mkdir /Kitura-Starter 140 | ADD .build/debug/Kitura-Starter /Kitura-Starter 141 | ADD .build/debug/*.so /Kitura-Starter 142 | ADD .build/debug/*.so.* /Kitura-Starter 143 | CMD [ "sh", "-c", "/Kitura-Starter/Kitura-Starter" ] 144 | ``` 145 | 146 | For details on how to create an IBM Container to execute a Swift application, please see [10 Steps To Running a Swift App in an IBM Container](https://developer.ibm.com/swift/2016/02/22/10-steps-to-running-a-swift-app-in-an-ibm-container) and [Running Kitura in an IBM Container](https://developer.ibm.com/swift/2016/03/04/running-kitura-in-an-ibm-container/). 147 | 148 | # Exposing ports in your Docker container 149 | Exposing your server's port running in a Docker container to the host system (e.g. macOS) is quite easy using the latest version of Docker: 150 | 151 | ``` 152 | docker run -p : [additional options] 153 | ``` 154 | 155 | For example, if your Swift server is running on port `8080`, and you want to make it accessible via port `9080` on the host system, run the following command: 156 | 157 | ``` 158 | docker run -p 9080:8080 [additional options] 159 | ``` 160 | 161 | Port `8080` in the container will then be mapped to port `9080` on the host system. For further details on the `-p` option, see the official Docker [documentation](https://docs.docker.com/engine/reference/run/#/expose-incoming-ports). 162 | 163 | # Contributing 164 | 165 | Improvements are very welcome! You can find more info on contributing in our [contributing guidelines](.github/CONTRIBUTING.md). 166 | -------------------------------------------------------------------------------- /backup/extract-libdispatch-binaries.sh: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2016 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | # Utility script used for extracting libdispatch binaries from the Docker container. 18 | 19 | for i in "$@" 20 | do 21 | case $i in 22 | --container=*) 23 | container="${i#*=}" 24 | shift # past argument=value 25 | ;; 26 | --swiftVersion=*) 27 | swiftVersion="${i#*=}" 28 | shift # past argument=value 29 | ;; 30 | --linuxVersion=*) 31 | linuxVersion="${i#*=}" 32 | shift # past argument=value 33 | ;; 34 | --outputFolder=*) 35 | outputFolder="${i#*=}" 36 | shift # past argument=value 37 | ;; 38 | *) 39 | # unknown option 40 | ;; 41 | esac 42 | done 43 | 44 | # Variables 45 | #container=fb5e2fd45218 46 | #swiftVersion=swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a 47 | #linuxVersion=ubuntu14.04 48 | #outputFolder=/Users/olivieri/tmp/libdispatch 49 | sourceFolder=$swiftVersion-$linuxVersion 50 | 51 | echo 52 | echo "Starting execution for extracting libdispatch binaries..." 53 | echo "Docker container: $container" 54 | echo "Swift version: $swiftVersion" 55 | echo "Linux version: $linuxVersion" 56 | echo "Source folder on docker container: $sourceFolder" 57 | echo "Output folder: $outputFolder" 58 | echo 59 | echo "Deleting '$outputFolder'..." 60 | rm -rf $outputFolder 61 | echo "Creating folder '$outputFolder'..." 62 | mkdir -p $outputFolder 63 | 64 | (IFS=' 65 | ' 66 | for line in `docker diff $container`; do 67 | line=${line#"C "} 68 | line=${line#"A "} 69 | path=$line 70 | basename="$(basename $line)" 71 | dir="$(dirname $line)" 72 | if [[ "$dir" == *"$sourceFolder"* ]]; then 73 | target="${path##*${sourceFolder}}" 74 | if [[ "$basename" == *"."* ]]; then 75 | #File 76 | echo "Copying file: $target" 77 | docker cp $container:$path $outputFolder$target 78 | else 79 | #Folder 80 | echo "Creating folder: $target" 81 | mkdir -p $outputFolder$target 82 | fi 83 | fi 84 | done) 85 | 86 | echo "Finished extracting libdispatch binaries." 87 | echo 88 | 89 | tarFileName=$swiftVersion-libdispatch.tar.gz 90 | echo "Creating $tarFileName file..." 91 | cd $outputFolder && tar -cvzf $tarFileName * 92 | echo "Finished creating '$tarFileName' in $outputFolder." 93 | # Untarring file 94 | # tar -xvf $tarFileName 95 | -------------------------------------------------------------------------------- /ci/execute_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | # Copyright IBM Corporation 2017, 2019 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ## 17 | 18 | set -ev 19 | 20 | # Swift version to use in Development Dockerfiles. 21 | DEVELOPMENT_VERSION="5.0.2" 22 | # Swift version to use in Runtime Dockerfiles. 23 | RUNTIME_VERSION="5.0.2" 24 | 25 | # Manifest-tool used for pushing multi-arch docker images 26 | git clone https://github.com/estesp/manifest-tool.git --branch v0.9.0 27 | make build --directory=manifest-tool 28 | 29 | docker build --pull -t ibmcom/ubuntu:14.04 ./ubuntu-14.04 30 | docker build --build-arg VERSION=${DEVELOPMENT_VERSION} -t ibmcom/swift-ubuntu:latest ./swift-development/swift-ubuntu-trusty 31 | docker build --build-arg VERSION=${RUNTIME_VERSION} -t ibmcom/swift-ubuntu-runtime:latest ./swift-runtime/swift-ubuntu-trusty 32 | docker tag ibmcom/swift-ubuntu:latest ibmcom/swift-ubuntu:$DEVELOPMENT_VERSION 33 | docker tag ibmcom/swift-ubuntu-runtime:latest ibmcom/swift-ubuntu-runtime:$RUNTIME_VERSION 34 | 35 | docker build --pull -t ibmcom/ubuntu:16.04 ./ubuntu-16.04 36 | docker build --build-arg VERSION=${DEVELOPMENT_VERSION} -t ibmcom/swift-ubuntu-xenial-amd64:latest ./swift-development/swift-ubuntu-xenial-multiarch/amd64 37 | docker build --build-arg VERSION=${RUNTIME_VERSION} -t ibmcom/swift-ubuntu-xenial-runtime-amd64:latest ./swift-runtime/swift-ubuntu-xenial-multiarch/amd64 38 | docker tag ibmcom/swift-ubuntu-xenial-amd64:latest ibmcom/swift-ubuntu-xenial-amd64:$DEVELOPMENT_VERSION 39 | docker tag ibmcom/swift-ubuntu-xenial-runtime-amd64:latest ibmcom/swift-ubuntu-xenial-runtime-amd64:$RUNTIME_VERSION 40 | 41 | if [ "$TRAVIS_BRANCH" == "master" ]; then 42 | docker login -u="$DOCKERHUB_USERNAME" -p="$DOCKERHUB_PASSWORD"; 43 | docker push ibmcom/ubuntu:14.04; 44 | docker push ibmcom/swift-ubuntu:latest; 45 | docker push ibmcom/swift-ubuntu-runtime:latest; 46 | docker push ibmcom/swift-ubuntu:$DEVELOPMENT_VERSION; 47 | docker push ibmcom/swift-ubuntu-runtime:$RUNTIME_VERSION; 48 | 49 | docker push ibmcom/ubuntu:16.04; 50 | docker push ibmcom/swift-ubuntu-xenial-amd64:latest; 51 | docker push ibmcom/swift-ubuntu-xenial-amd64:$DEVELOPMENT_VERSION; 52 | ./manifest-tool/manifest-tool push from-spec ./swift-development/swift-ubuntu-xenial-multiarch/manifest.yml; 53 | docker push ibmcom/swift-ubuntu-xenial-runtime-amd64:latest 54 | docker push ibmcom/swift-ubuntu-xenial-runtime-amd64:$DEVELOPMENT_VERSION 55 | ./manifest-tool/manifest-tool push from-spec ./swift-runtime/swift-ubuntu-xenial-multiarch/manifest.yml; 56 | fi 57 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-trusty/.vim/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | swift_install_in_component(editor-integration 2 | DIRECTORY 3 | ftdetect 4 | syntax 5 | DESTINATION "share/vim/vim73" 6 | PATTERN ".*" EXCLUDE) 7 | 8 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-trusty/.vim/autoload/plug.vim: -------------------------------------------------------------------------------- 1 | " vim-plug: Vim plugin manager 2 | " ============================ 3 | " 4 | " Download plug.vim and put it in ~/.vim/autoload 5 | " 6 | " curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ 7 | " https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim 8 | " 9 | " Edit your .vimrc 10 | " 11 | " call plug#begin('~/.vim/plugged') 12 | " 13 | " " Make sure you use single quotes 14 | " 15 | " " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align 16 | " Plug 'junegunn/vim-easy-align' 17 | " 18 | " " Any valid git URL is allowed 19 | " Plug 'https://github.com/junegunn/vim-github-dashboard.git' 20 | " 21 | " " Group dependencies, vim-snippets depends on ultisnips 22 | " Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' 23 | " 24 | " " On-demand loading 25 | " Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } 26 | " Plug 'tpope/vim-fireplace', { 'for': 'clojure' } 27 | " 28 | " " Using a non-master branch 29 | " Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } 30 | " 31 | " " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) 32 | " Plug 'fatih/vim-go', { 'tag': '*' } 33 | " 34 | " " Plugin options 35 | " Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } 36 | " 37 | " " Plugin outside ~/.vim/plugged with post-update hook 38 | " Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } 39 | " 40 | " " Unmanaged plugin (manually installed and updated) 41 | " Plug '~/my-prototype-plugin' 42 | " 43 | " " Add plugins to &runtimepath 44 | " call plug#end() 45 | " 46 | " Then reload .vimrc and :PlugInstall to install plugins. 47 | " 48 | " Plug options: 49 | " 50 | "| Option | Description | 51 | "| ----------------------- | ------------------------------------------------ | 52 | "| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | 53 | "| `rtp` | Subdirectory that contains Vim plugin | 54 | "| `dir` | Custom directory for the plugin | 55 | "| `as` | Use different name for the plugin | 56 | "| `do` | Post-update hook (string or funcref) | 57 | "| `on` | On-demand loading: Commands or ``-mappings | 58 | "| `for` | On-demand loading: File types | 59 | "| `frozen` | Do not update unless explicitly specified | 60 | " 61 | " More information: https://github.com/junegunn/vim-plug 62 | " 63 | " 64 | " Copyright (c) 2016 Junegunn Choi 65 | " 66 | " MIT License 67 | " 68 | " Permission is hereby granted, free of charge, to any person obtaining 69 | " a copy of this software and associated documentation files (the 70 | " "Software"), to deal in the Software without restriction, including 71 | " without limitation the rights to use, copy, modify, merge, publish, 72 | " distribute, sublicense, and/or sell copies of the Software, and to 73 | " permit persons to whom the Software is furnished to do so, subject to 74 | " the following conditions: 75 | " 76 | " The above copyright notice and this permission notice shall be 77 | " included in all copies or substantial portions of the Software. 78 | " 79 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 80 | " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 81 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 82 | " NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 83 | " LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 84 | " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 85 | " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 86 | 87 | if exists('g:loaded_plug') 88 | finish 89 | endif 90 | let g:loaded_plug = 1 91 | 92 | let s:cpo_save = &cpo 93 | set cpo&vim 94 | 95 | let s:plug_src = 'https://github.com/junegunn/vim-plug.git' 96 | let s:plug_tab = get(s:, 'plug_tab', -1) 97 | let s:plug_buf = get(s:, 'plug_buf', -1) 98 | let s:mac_gui = has('gui_macvim') && has('gui_running') 99 | let s:is_win = has('win32') || has('win64') 100 | let s:nvim = has('nvim') && exists('*jobwait') && !s:is_win 101 | let s:me = resolve(expand(':p')) 102 | let s:base_spec = { 'branch': 'master', 'frozen': 0 } 103 | let s:TYPE = { 104 | \ 'string': type(''), 105 | \ 'list': type([]), 106 | \ 'dict': type({}), 107 | \ 'funcref': type(function('call')) 108 | \ } 109 | let s:loaded = get(s:, 'loaded', {}) 110 | let s:triggers = get(s:, 'triggers', {}) 111 | 112 | function! plug#begin(...) 113 | if a:0 > 0 114 | let s:plug_home_org = a:1 115 | let home = s:path(fnamemodify(expand(a:1), ':p')) 116 | elseif exists('g:plug_home') 117 | let home = s:path(g:plug_home) 118 | elseif !empty(&rtp) 119 | let home = s:path(split(&rtp, ',')[0]) . '/plugged' 120 | else 121 | return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') 122 | endif 123 | 124 | let g:plug_home = home 125 | let g:plugs = {} 126 | let g:plugs_order = [] 127 | let s:triggers = {} 128 | 129 | call s:define_commands() 130 | return 1 131 | endfunction 132 | 133 | function! s:define_commands() 134 | command! -nargs=+ -bar Plug call plug#() 135 | if !executable('git') 136 | return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') 137 | endif 138 | command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) 139 | command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) 140 | command! -nargs=0 -bar -bang PlugClean call s:clean(0) 141 | command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif 142 | command! -nargs=0 -bar PlugStatus call s:status() 143 | command! -nargs=0 -bar PlugDiff call s:diff() 144 | command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) 145 | endfunction 146 | 147 | function! s:to_a(v) 148 | return type(a:v) == s:TYPE.list ? a:v : [a:v] 149 | endfunction 150 | 151 | function! s:to_s(v) 152 | return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" 153 | endfunction 154 | 155 | function! s:glob(from, pattern) 156 | return s:lines(globpath(a:from, a:pattern)) 157 | endfunction 158 | 159 | function! s:source(from, ...) 160 | let found = 0 161 | for pattern in a:000 162 | for vim in s:glob(a:from, pattern) 163 | execute 'source' s:esc(vim) 164 | let found = 1 165 | endfor 166 | endfor 167 | return found 168 | endfunction 169 | 170 | function! s:assoc(dict, key, val) 171 | let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) 172 | endfunction 173 | 174 | function! s:ask(message) 175 | call inputsave() 176 | echohl WarningMsg 177 | let proceed = input(a:message.' (y/N) ') =~? '^y' 178 | echohl None 179 | call inputrestore() 180 | echo "\r" 181 | return proceed 182 | endfunction 183 | 184 | function! plug#end() 185 | if !exists('g:plugs') 186 | return s:err('Call plug#begin() first') 187 | endif 188 | 189 | if exists('#PlugLOD') 190 | augroup PlugLOD 191 | autocmd! 192 | augroup END 193 | augroup! PlugLOD 194 | endif 195 | let lod = { 'ft': {}, 'map': {}, 'cmd': {} } 196 | 197 | filetype off 198 | for name in g:plugs_order 199 | let plug = g:plugs[name] 200 | if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for') 201 | let s:loaded[name] = 1 202 | continue 203 | endif 204 | 205 | if has_key(plug, 'on') 206 | let s:triggers[name] = { 'map': [], 'cmd': [] } 207 | for cmd in s:to_a(plug.on) 208 | if cmd =~? '^.\+' 209 | if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) 210 | call s:assoc(lod.map, cmd, name) 211 | endif 212 | call add(s:triggers[name].map, cmd) 213 | elseif cmd =~# '^[A-Z]' 214 | if exists(':'.cmd) != 2 215 | call s:assoc(lod.cmd, cmd, name) 216 | endif 217 | call add(s:triggers[name].cmd, cmd) 218 | else 219 | call s:err('Invalid `on` option: '.cmd. 220 | \ '. Should start with an uppercase letter or ``.') 221 | endif 222 | endfor 223 | endif 224 | 225 | if has_key(plug, 'for') 226 | let types = s:to_a(plug.for) 227 | if !empty(types) 228 | augroup filetypedetect 229 | call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') 230 | augroup END 231 | endif 232 | for type in types 233 | call s:assoc(lod.ft, type, name) 234 | endfor 235 | endif 236 | endfor 237 | 238 | for [cmd, names] in items(lod.cmd) 239 | execute printf( 240 | \ 'command! -nargs=* -range -bang %s call s:lod_cmd(%s, "", , , , %s)', 241 | \ cmd, string(cmd), string(names)) 242 | endfor 243 | 244 | for [map, names] in items(lod.map) 245 | for [mode, map_prefix, key_prefix] in 246 | \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] 247 | execute printf( 248 | \ '%snoremap %s %s:call lod_map(%s, %s, "%s")', 249 | \ mode, map, map_prefix, string(map), string(names), key_prefix) 250 | endfor 251 | endfor 252 | 253 | for [ft, names] in items(lod.ft) 254 | augroup PlugLOD 255 | execute printf('autocmd FileType %s call lod_ft(%s, %s)', 256 | \ ft, string(ft), string(names)) 257 | augroup END 258 | endfor 259 | 260 | call s:reorg_rtp() 261 | filetype plugin indent on 262 | if has('vim_starting') 263 | if has('syntax') && !exists('g:syntax_on') 264 | syntax enable 265 | end 266 | else 267 | call s:reload() 268 | endif 269 | endfunction 270 | 271 | function! s:loaded_names() 272 | return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') 273 | endfunction 274 | 275 | function! s:reload() 276 | for name in s:loaded_names() 277 | call s:source(s:rtp(g:plugs[name]), 'plugin/**/*.vim', 'after/plugin/**/*.vim') 278 | endfor 279 | endfunction 280 | 281 | function! s:trim(str) 282 | return substitute(a:str, '[\/]\+$', '', '') 283 | endfunction 284 | 285 | function! s:version_requirement(val, min) 286 | for idx in range(0, len(a:min) - 1) 287 | let v = get(a:val, idx, 0) 288 | if v < a:min[idx] | return 0 289 | elseif v > a:min[idx] | return 1 290 | endif 291 | endfor 292 | return 1 293 | endfunction 294 | 295 | function! s:git_version_requirement(...) 296 | if !exists('s:git_version') 297 | let s:git_version = map(split(split(s:system('git --version'))[-1], '\.'), 'str2nr(v:val)') 298 | endif 299 | return s:version_requirement(s:git_version, a:000) 300 | endfunction 301 | 302 | function! s:progress_opt(base) 303 | return a:base && !s:is_win && 304 | \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' 305 | endfunction 306 | 307 | if s:is_win 308 | function! s:rtp(spec) 309 | return s:path(a:spec.dir . get(a:spec, 'rtp', '')) 310 | endfunction 311 | 312 | function! s:path(path) 313 | return s:trim(substitute(a:path, '/', '\', 'g')) 314 | endfunction 315 | 316 | function! s:dirpath(path) 317 | return s:path(a:path) . '\' 318 | endfunction 319 | 320 | function! s:is_local_plug(repo) 321 | return a:repo =~? '^[a-z]:\|^[%~]' 322 | endfunction 323 | else 324 | function! s:rtp(spec) 325 | return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) 326 | endfunction 327 | 328 | function! s:path(path) 329 | return s:trim(a:path) 330 | endfunction 331 | 332 | function! s:dirpath(path) 333 | return substitute(a:path, '[/\\]*$', '/', '') 334 | endfunction 335 | 336 | function! s:is_local_plug(repo) 337 | return a:repo[0] =~ '[/$~]' 338 | endfunction 339 | endif 340 | 341 | function! s:err(msg) 342 | echohl ErrorMsg 343 | echom '[vim-plug] '.a:msg 344 | echohl None 345 | endfunction 346 | 347 | function! s:warn(cmd, msg) 348 | echohl WarningMsg 349 | execute a:cmd 'a:msg' 350 | echohl None 351 | endfunction 352 | 353 | function! s:esc(path) 354 | return escape(a:path, ' ') 355 | endfunction 356 | 357 | function! s:escrtp(path) 358 | return escape(a:path, ' ,') 359 | endfunction 360 | 361 | function! s:remove_rtp() 362 | for name in s:loaded_names() 363 | let rtp = s:rtp(g:plugs[name]) 364 | execute 'set rtp-='.s:escrtp(rtp) 365 | let after = globpath(rtp, 'after') 366 | if isdirectory(after) 367 | execute 'set rtp-='.s:escrtp(after) 368 | endif 369 | endfor 370 | endfunction 371 | 372 | function! s:reorg_rtp() 373 | if !empty(s:first_rtp) 374 | execute 'set rtp-='.s:first_rtp 375 | execute 'set rtp-='.s:last_rtp 376 | endif 377 | 378 | " &rtp is modified from outside 379 | if exists('s:prtp') && s:prtp !=# &rtp 380 | call s:remove_rtp() 381 | unlet! s:middle 382 | endif 383 | 384 | let s:middle = get(s:, 'middle', &rtp) 385 | let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') 386 | let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), 'isdirectory(v:val)') 387 | let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') 388 | \ . ','.s:middle.',' 389 | \ . join(map(afters, 'escape(v:val, ",")'), ',') 390 | let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') 391 | let s:prtp = &rtp 392 | 393 | if !empty(s:first_rtp) 394 | execute 'set rtp^='.s:first_rtp 395 | execute 'set rtp+='.s:last_rtp 396 | endif 397 | endfunction 398 | 399 | function! s:doautocmd(...) 400 | if exists('#'.join(a:000, '#')) 401 | execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) 402 | endif 403 | endfunction 404 | 405 | function! s:dobufread(names) 406 | for name in a:names 407 | let path = s:rtp(g:plugs[name]).'/**' 408 | for dir in ['ftdetect', 'ftplugin'] 409 | if len(finddir(dir, path)) 410 | return s:doautocmd('BufRead') 411 | endif 412 | endfor 413 | endfor 414 | endfunction 415 | 416 | function! plug#load(...) 417 | if a:0 == 0 418 | return s:err('Argument missing: plugin name(s) required') 419 | endif 420 | if !exists('g:plugs') 421 | return s:err('plug#begin was not called') 422 | endif 423 | let unknowns = filter(copy(a:000), '!has_key(g:plugs, v:val)') 424 | if !empty(unknowns) 425 | let s = len(unknowns) > 1 ? 's' : '' 426 | return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) 427 | end 428 | for name in a:000 429 | call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) 430 | endfor 431 | call s:dobufread(a:000) 432 | return 1 433 | endfunction 434 | 435 | function! s:remove_triggers(name) 436 | if !has_key(s:triggers, a:name) 437 | return 438 | endif 439 | for cmd in s:triggers[a:name].cmd 440 | execute 'silent! delc' cmd 441 | endfor 442 | for map in s:triggers[a:name].map 443 | execute 'silent! unmap' map 444 | execute 'silent! iunmap' map 445 | endfor 446 | call remove(s:triggers, a:name) 447 | endfunction 448 | 449 | function! s:lod(names, types, ...) 450 | for name in a:names 451 | call s:remove_triggers(name) 452 | let s:loaded[name] = 1 453 | endfor 454 | call s:reorg_rtp() 455 | 456 | for name in a:names 457 | let rtp = s:rtp(g:plugs[name]) 458 | for dir in a:types 459 | call s:source(rtp, dir.'/**/*.vim') 460 | endfor 461 | if a:0 462 | if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) 463 | execute 'runtime' a:1 464 | endif 465 | call s:source(rtp, a:2) 466 | endif 467 | call s:doautocmd('User', name) 468 | endfor 469 | endfunction 470 | 471 | function! s:lod_ft(pat, names) 472 | let syn = 'syntax/'.a:pat.'.vim' 473 | call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) 474 | execute 'autocmd! PlugLOD FileType' a:pat 475 | call s:doautocmd('filetypeplugin', 'FileType') 476 | call s:doautocmd('filetypeindent', 'FileType') 477 | endfunction 478 | 479 | function! s:lod_cmd(cmd, bang, l1, l2, args, names) 480 | call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) 481 | call s:dobufread(a:names) 482 | execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) 483 | endfunction 484 | 485 | function! s:lod_map(map, names, prefix) 486 | call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) 487 | call s:dobufread(a:names) 488 | let extra = '' 489 | while 1 490 | let c = getchar(0) 491 | if c == 0 492 | break 493 | endif 494 | let extra .= nr2char(c) 495 | endwhile 496 | if v:count 497 | call feedkeys(v:count, 'n') 498 | endif 499 | call feedkeys('"'.v:register, 'n') 500 | if mode(1) == 'no' 501 | call feedkeys(v:operator) 502 | endif 503 | call feedkeys(a:prefix . substitute(a:map, '^', "\", '') . extra) 504 | endfunction 505 | 506 | function! plug#(repo, ...) 507 | if a:0 > 1 508 | return s:err('Invalid number of arguments (1..2)') 509 | endif 510 | 511 | try 512 | let repo = s:trim(a:repo) 513 | let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec 514 | let name = get(opts, 'as', fnamemodify(repo, ':t:s?\.git$??')) 515 | let spec = extend(s:infer_properties(name, repo), opts) 516 | if !has_key(g:plugs, name) 517 | call add(g:plugs_order, name) 518 | endif 519 | let g:plugs[name] = spec 520 | let s:loaded[name] = get(s:loaded, name, 0) 521 | catch 522 | return s:err(v:exception) 523 | endtry 524 | endfunction 525 | 526 | function! s:parse_options(arg) 527 | let opts = copy(s:base_spec) 528 | let type = type(a:arg) 529 | if type == s:TYPE.string 530 | let opts.tag = a:arg 531 | elseif type == s:TYPE.dict 532 | call extend(opts, a:arg) 533 | if has_key(opts, 'dir') 534 | let opts.dir = s:dirpath(expand(opts.dir)) 535 | endif 536 | else 537 | throw 'Invalid argument type (expected: string or dictionary)' 538 | endif 539 | return opts 540 | endfunction 541 | 542 | function! s:infer_properties(name, repo) 543 | let repo = a:repo 544 | if s:is_local_plug(repo) 545 | return { 'dir': s:dirpath(expand(repo)) } 546 | else 547 | if repo =~ ':' 548 | let uri = repo 549 | else 550 | if repo !~ '/' 551 | let repo = 'vim-scripts/'. repo 552 | endif 553 | let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') 554 | let uri = printf(fmt, repo) 555 | endif 556 | let dir = s:dirpath( fnamemodify(join([g:plug_home, a:name], '/'), ':p') ) 557 | return { 'dir': dir, 'uri': uri } 558 | endif 559 | endfunction 560 | 561 | function! s:install(force, names) 562 | call s:update_impl(0, a:force, a:names) 563 | endfunction 564 | 565 | function! s:update(force, names) 566 | call s:update_impl(1, a:force, a:names) 567 | endfunction 568 | 569 | function! plug#helptags() 570 | if !exists('g:plugs') 571 | return s:err('plug#begin was not called') 572 | endif 573 | for spec in values(g:plugs) 574 | let docd = join([spec.dir, 'doc'], '/') 575 | if isdirectory(docd) 576 | silent! execute 'helptags' s:esc(docd) 577 | endif 578 | endfor 579 | return 1 580 | endfunction 581 | 582 | function! s:syntax() 583 | syntax clear 584 | syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber 585 | syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX 586 | syn match plugNumber /[0-9]\+[0-9.]*/ contained 587 | syn match plugBracket /[[\]]/ contained 588 | syn match plugX /x/ contained 589 | syn match plugDash /^-/ 590 | syn match plugPlus /^+/ 591 | syn match plugStar /^*/ 592 | syn match plugMessage /\(^- \)\@<=.*/ 593 | syn match plugName /\(^- \)\@<=[^ ]*:/ 594 | syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ 595 | syn match plugTag /(tag: [^)]\+)/ 596 | syn match plugInstall /\(^+ \)\@<=[^:]*/ 597 | syn match plugUpdate /\(^* \)\@<=[^:]*/ 598 | syn match plugCommit /^ \X*[0-9a-f]\{7} .*/ contains=plugRelDate,plugEdge,plugTag 599 | syn match plugEdge /^ \X\+$/ 600 | syn match plugEdge /^ \X*/ contained nextgroup=plugSha 601 | syn match plugSha /[0-9a-f]\{7}/ contained 602 | syn match plugRelDate /([^)]*)$/ contained 603 | syn match plugNotLoaded /(not loaded)$/ 604 | syn match plugError /^x.*/ 605 | syn match plugH2 /^.*:\n-\+$/ 606 | syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean 607 | hi def link plug1 Title 608 | hi def link plug2 Repeat 609 | hi def link plugH2 Type 610 | hi def link plugX Exception 611 | hi def link plugBracket Structure 612 | hi def link plugNumber Number 613 | 614 | hi def link plugDash Special 615 | hi def link plugPlus Constant 616 | hi def link plugStar Boolean 617 | 618 | hi def link plugMessage Function 619 | hi def link plugName Label 620 | hi def link plugInstall Function 621 | hi def link plugUpdate Type 622 | 623 | hi def link plugError Error 624 | hi def link plugRelDate Comment 625 | hi def link plugEdge PreProc 626 | hi def link plugSha Identifier 627 | hi def link plugTag Constant 628 | 629 | hi def link plugNotLoaded Comment 630 | endfunction 631 | 632 | function! s:lpad(str, len) 633 | return a:str . repeat(' ', a:len - len(a:str)) 634 | endfunction 635 | 636 | function! s:lines(msg) 637 | return split(a:msg, "[\r\n]") 638 | endfunction 639 | 640 | function! s:lastline(msg) 641 | return get(s:lines(a:msg), -1, '') 642 | endfunction 643 | 644 | function! s:new_window() 645 | execute get(g:, 'plug_window', 'vertical topleft new') 646 | endfunction 647 | 648 | function! s:plug_window_exists() 649 | let buflist = tabpagebuflist(s:plug_tab) 650 | return !empty(buflist) && index(buflist, s:plug_buf) >= 0 651 | endfunction 652 | 653 | function! s:switch_in() 654 | if !s:plug_window_exists() 655 | return 0 656 | endif 657 | 658 | if winbufnr(0) != s:plug_buf 659 | let s:pos = [tabpagenr(), winnr(), winsaveview()] 660 | execute 'normal!' s:plug_tab.'gt' 661 | let winnr = bufwinnr(s:plug_buf) 662 | execute winnr.'wincmd w' 663 | call add(s:pos, winsaveview()) 664 | else 665 | let s:pos = [winsaveview()] 666 | endif 667 | 668 | setlocal modifiable 669 | return 1 670 | endfunction 671 | 672 | function! s:switch_out(...) 673 | call winrestview(s:pos[-1]) 674 | setlocal nomodifiable 675 | if a:0 > 0 676 | execute a:1 677 | endif 678 | 679 | if len(s:pos) > 1 680 | execute 'normal!' s:pos[0].'gt' 681 | execute s:pos[1] 'wincmd w' 682 | call winrestview(s:pos[2]) 683 | endif 684 | endfunction 685 | 686 | function! s:finish_bindings() 687 | nnoremap R :call retry() 688 | nnoremap D :PlugDiff 689 | nnoremap S :PlugStatus 690 | nnoremap U :call status_update() 691 | xnoremap U :call status_update() 692 | nnoremap ]] :silent! call section('') 693 | nnoremap [[ :silent! call section('b') 694 | endfunction 695 | 696 | function! s:prepare(...) 697 | if empty(getcwd()) 698 | throw 'Invalid current working directory. Cannot proceed.' 699 | endif 700 | 701 | call s:job_abort() 702 | if s:switch_in() 703 | normal q 704 | endif 705 | 706 | call s:new_window() 707 | nnoremap q :if b:plug_preview==1pcendifbd 708 | if a:0 == 0 709 | call s:finish_bindings() 710 | endif 711 | let b:plug_preview = -1 712 | let s:plug_tab = tabpagenr() 713 | let s:plug_buf = winbufnr(0) 714 | call s:assign_name() 715 | 716 | silent! unmap 717 | silent! unmap L 718 | silent! unmap o 719 | silent! unmap X 720 | setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable 721 | setf vim-plug 722 | if exists('g:syntax_on') 723 | call s:syntax() 724 | endif 725 | endfunction 726 | 727 | function! s:assign_name() 728 | " Assign buffer name 729 | let prefix = '[Plugins]' 730 | let name = prefix 731 | let idx = 2 732 | while bufexists(name) 733 | let name = printf('%s (%s)', prefix, idx) 734 | let idx = idx + 1 735 | endwhile 736 | silent! execute 'f' fnameescape(name) 737 | endfunction 738 | 739 | function! s:chsh(swap) 740 | let prev = [&shell, &shellredir] 741 | if !s:is_win && a:swap 742 | set shell=sh shellredir=>%s\ 2>&1 743 | endif 744 | return prev 745 | endfunction 746 | 747 | function! s:bang(cmd, ...) 748 | try 749 | let [sh, shrd] = s:chsh(a:0) 750 | " FIXME: Escaping is incomplete. We could use shellescape with eval, 751 | " but it won't work on Windows. 752 | let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd 753 | let g:_plug_bang = '!'.escape(cmd, '#!%') 754 | execute "normal! :execute g:_plug_bang\\" 755 | finally 756 | unlet g:_plug_bang 757 | let [&shell, &shellredir] = [sh, shrd] 758 | endtry 759 | return v:shell_error ? 'Exit status: ' . v:shell_error : '' 760 | endfunction 761 | 762 | function! s:regress_bar() 763 | let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') 764 | call s:progress_bar(2, bar, len(bar)) 765 | endfunction 766 | 767 | function! s:is_updated(dir) 768 | return !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', a:dir)) 769 | endfunction 770 | 771 | function! s:do(pull, force, todo) 772 | for [name, spec] in items(a:todo) 773 | if !isdirectory(spec.dir) 774 | continue 775 | endif 776 | let installed = has_key(s:update.new, name) 777 | let updated = installed ? 0 : 778 | \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) 779 | if a:force || installed || updated 780 | execute 'cd' s:esc(spec.dir) 781 | call append(3, '- Post-update hook for '. name .' ... ') 782 | let error = '' 783 | let type = type(spec.do) 784 | if type == s:TYPE.string 785 | let error = s:bang(spec.do) 786 | elseif type == s:TYPE.funcref 787 | try 788 | let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') 789 | call spec.do({ 'name': name, 'status': status, 'force': a:force }) 790 | catch 791 | let error = v:exception 792 | endtry 793 | else 794 | let error = 'Invalid hook type' 795 | endif 796 | call setline(4, empty(error) ? (getline(4) . 'OK') 797 | \ : ('x' . getline(4)[1:] . error)) 798 | if !empty(error) 799 | call add(s:update.errors, name) 800 | call s:regress_bar() 801 | endif 802 | cd - 803 | endif 804 | endfor 805 | endfunction 806 | 807 | function! s:hash_match(a, b) 808 | return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 809 | endfunction 810 | 811 | function! s:checkout(spec) 812 | let sha = a:spec.commit 813 | let output = s:system('git rev-parse HEAD', a:spec.dir) 814 | if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) 815 | let output = s:system( 816 | \ 'git fetch --depth 999999 && git checkout '.s:esc(sha), a:spec.dir) 817 | endif 818 | return output 819 | endfunction 820 | 821 | function! s:finish(pull) 822 | let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) 823 | if new_frozen 824 | let s = new_frozen > 1 ? 's' : '' 825 | call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) 826 | endif 827 | call append(3, '- Finishing ... ') | 4 828 | redraw 829 | call plug#helptags() 830 | call plug#end() 831 | call setline(4, getline(4) . 'Done!') 832 | redraw 833 | let msgs = [] 834 | if !empty(s:update.errors) 835 | call add(msgs, "Press 'R' to retry.") 836 | endif 837 | if a:pull && len(s:update.new) < len(filter(getline(5, '$'), 838 | \ "v:val =~ '^- ' && stridx(v:val, 'Already up-to-date') < 0")) 839 | call add(msgs, "Press 'D' to see the updated changes.") 840 | endif 841 | echo join(msgs, ' ') 842 | call s:finish_bindings() 843 | endfunction 844 | 845 | function! s:retry() 846 | if empty(s:update.errors) 847 | return 848 | endif 849 | echo 850 | call s:update_impl(s:update.pull, s:update.force, 851 | \ extend(copy(s:update.errors), [s:update.threads])) 852 | endfunction 853 | 854 | function! s:is_managed(name) 855 | return has_key(g:plugs[a:name], 'uri') 856 | endfunction 857 | 858 | function! s:names(...) 859 | return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) 860 | endfunction 861 | 862 | function! s:check_ruby() 863 | silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") 864 | if !exists('g:plug_ruby') 865 | redraw! 866 | return s:warn('echom', 'Warning: Ruby interface is broken') 867 | endif 868 | let ruby_version = split(g:plug_ruby, '\.') 869 | unlet g:plug_ruby 870 | return s:version_requirement(ruby_version, [1, 8, 7]) 871 | endfunction 872 | 873 | function! s:update_impl(pull, force, args) abort 874 | let args = copy(a:args) 875 | let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? 876 | \ remove(args, -1) : get(g:, 'plug_threads', 16) 877 | 878 | let managed = filter(copy(g:plugs), 's:is_managed(v:key)') 879 | let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : 880 | \ filter(managed, 'index(args, v:key) >= 0') 881 | 882 | if empty(todo) 883 | return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) 884 | endif 885 | 886 | if !s:is_win && s:git_version_requirement(2, 3) 887 | let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' 888 | let $GIT_TERMINAL_PROMPT = 0 889 | for plug in values(todo) 890 | let plug.uri = substitute(plug.uri, 891 | \ '^https://git::@github\.com', 'https://github.com', '') 892 | endfor 893 | endif 894 | 895 | if !isdirectory(g:plug_home) 896 | try 897 | call mkdir(g:plug_home, 'p') 898 | catch 899 | return s:err(printf('Invalid plug directory: %s. '. 900 | \ 'Try to call plug#begin with a valid directory', g:plug_home)) 901 | endtry 902 | endif 903 | 904 | if has('nvim') && !exists('*jobwait') && threads > 1 905 | call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') 906 | endif 907 | 908 | let python = (has('python') || has('python3')) && (!s:nvim || has('vim_starting')) 909 | let ruby = has('ruby') && !s:nvim && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && s:check_ruby() 910 | 911 | let s:update = { 912 | \ 'start': reltime(), 913 | \ 'all': todo, 914 | \ 'todo': copy(todo), 915 | \ 'errors': [], 916 | \ 'pull': a:pull, 917 | \ 'force': a:force, 918 | \ 'new': {}, 919 | \ 'threads': (python || ruby || s:nvim) ? min([len(todo), threads]) : 1, 920 | \ 'bar': '', 921 | \ 'fin': 0 922 | \ } 923 | 924 | call s:prepare(1) 925 | call append(0, ['', '']) 926 | normal! 2G 927 | silent! redraw 928 | 929 | let s:clone_opt = get(g:, 'plug_shallow', 1) ? 930 | \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' 931 | 932 | " Python version requirement (>= 2.7) 933 | if python && !has('python3') && !ruby && !s:nvim && s:update.threads > 1 934 | redir => pyv 935 | silent python import platform; print platform.python_version() 936 | redir END 937 | let python = s:version_requirement( 938 | \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) 939 | endif 940 | 941 | if (python || ruby) && s:update.threads > 1 942 | try 943 | let imd = &imd 944 | if s:mac_gui 945 | set noimd 946 | endif 947 | if ruby 948 | call s:update_ruby() 949 | else 950 | call s:update_python() 951 | endif 952 | catch 953 | let lines = getline(4, '$') 954 | let printed = {} 955 | silent! 4,$d _ 956 | for line in lines 957 | let name = s:extract_name(line, '.', '') 958 | if empty(name) || !has_key(printed, name) 959 | call append('$', line) 960 | if !empty(name) 961 | let printed[name] = 1 962 | if line[0] == 'x' && index(s:update.errors, name) < 0 963 | call add(s:update.errors, name) 964 | end 965 | endif 966 | endif 967 | endfor 968 | finally 969 | let &imd = imd 970 | call s:update_finish() 971 | endtry 972 | else 973 | call s:update_vim() 974 | endif 975 | endfunction 976 | 977 | function! s:log4(name, msg) 978 | call setline(4, printf('- %s (%s)', a:msg, a:name)) 979 | redraw 980 | endfunction 981 | 982 | function! s:update_finish() 983 | if exists('s:git_terminal_prompt') 984 | let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt 985 | endif 986 | if s:switch_in() 987 | call append(3, '- Updating ...') | 4 988 | for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) 989 | let pos = s:logpos(name) 990 | if !pos 991 | continue 992 | endif 993 | if has_key(spec, 'commit') 994 | call s:log4(name, 'Checking out '.spec.commit) 995 | let out = s:checkout(spec) 996 | elseif has_key(spec, 'tag') 997 | let tag = spec.tag 998 | if tag =~ '\*' 999 | let tags = s:lines(s:system('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir)) 1000 | if !v:shell_error && !empty(tags) 1001 | let tag = tags[0] 1002 | call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) 1003 | call append(3, '') 1004 | endif 1005 | endif 1006 | call s:log4(name, 'Checking out '.tag) 1007 | let out = s:system('git checkout -q '.s:esc(tag).' 2>&1', spec.dir) 1008 | else 1009 | let branch = s:esc(get(spec, 'branch', 'master')) 1010 | call s:log4(name, 'Merging origin/'.branch) 1011 | let out = s:system('git checkout -q '.branch.' 2>&1' 1012 | \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir) 1013 | endif 1014 | if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && 1015 | \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) 1016 | call s:log4(name, 'Updating submodules. This may take a while.') 1017 | let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir) 1018 | endif 1019 | let msg = printf('%s %s: %s', v:shell_error ? 'x': '-', name, s:lastline(out)) 1020 | if v:shell_error 1021 | call add(s:update.errors, name) 1022 | call s:regress_bar() 1023 | execute pos 'd _' 1024 | call append(4, msg) | 4 1025 | elseif !empty(out) 1026 | call setline(pos, msg) 1027 | endif 1028 | redraw 1029 | endfor 1030 | 4 d _ 1031 | call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) 1032 | call s:finish(s:update.pull) 1033 | call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') 1034 | call s:switch_out('normal! gg') 1035 | endif 1036 | endfunction 1037 | 1038 | function! s:job_abort() 1039 | if !s:nvim || !exists('s:jobs') 1040 | return 1041 | endif 1042 | 1043 | for [name, j] in items(s:jobs) 1044 | silent! call jobstop(j.jobid) 1045 | if j.new 1046 | call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) 1047 | endif 1048 | endfor 1049 | let s:jobs = {} 1050 | endfunction 1051 | 1052 | " When a:event == 'stdout', data = list of strings 1053 | " When a:event == 'exit', data = returncode 1054 | function! s:job_handler(job_id, data, event) abort 1055 | if !s:plug_window_exists() " plug window closed 1056 | return s:job_abort() 1057 | endif 1058 | 1059 | if a:event == 'stdout' 1060 | let complete = empty(a:data[-1]) 1061 | let lines = map(filter(a:data, 'len(v:val) > 0'), 'split(v:val, "[\r\n]")[-1]') 1062 | call extend(self.lines, lines) 1063 | let self.result = join(self.lines, "\n") 1064 | if !complete 1065 | call remove(self.lines, -1) 1066 | endif 1067 | " To reduce the number of buffer updates 1068 | let self.tick = get(self, 'tick', -1) + 1 1069 | if self.tick % len(s:jobs) == 0 1070 | call s:log(self.new ? '+' : '*', self.name, self.result) 1071 | endif 1072 | elseif a:event == 'exit' 1073 | let self.running = 0 1074 | if a:data != 0 1075 | let self.error = 1 1076 | endif 1077 | call s:reap(self.name) 1078 | call s:tick() 1079 | endif 1080 | endfunction 1081 | 1082 | function! s:spawn(name, cmd, opts) 1083 | let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [], 'result': '', 1084 | \ 'new': get(a:opts, 'new', 0), 1085 | \ 'on_stdout': function('s:job_handler'), 1086 | \ 'on_exit' : function('s:job_handler'), 1087 | \ } 1088 | let s:jobs[a:name] = job 1089 | 1090 | if s:nvim 1091 | let argv = [ 'sh', '-c', 1092 | \ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) ] 1093 | let jid = jobstart(argv, job) 1094 | if jid > 0 1095 | let job.jobid = jid 1096 | else 1097 | let job.running = 0 1098 | let job.error = 1 1099 | let job.result = jid < 0 ? 'sh is not executable' : 1100 | \ 'Invalid arguments (or job table is full)' 1101 | endif 1102 | else 1103 | let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd] 1104 | let job.result = call('s:system', params) 1105 | let job.error = v:shell_error != 0 1106 | let job.running = 0 1107 | endif 1108 | endfunction 1109 | 1110 | function! s:reap(name) 1111 | let job = s:jobs[a:name] 1112 | if job.error 1113 | call add(s:update.errors, a:name) 1114 | elseif get(job, 'new', 0) 1115 | let s:update.new[a:name] = 1 1116 | endif 1117 | let s:update.bar .= job.error ? 'x' : '=' 1118 | 1119 | call s:log(job.error ? 'x' : '-', a:name, empty(job.result) ? 'OK' : job.result) 1120 | call s:bar() 1121 | 1122 | call remove(s:jobs, a:name) 1123 | endfunction 1124 | 1125 | function! s:bar() 1126 | if s:switch_in() 1127 | let total = len(s:update.all) 1128 | call setline(1, (s:update.pull ? 'Updating' : 'Installing'). 1129 | \ ' plugins ('.len(s:update.bar).'/'.total.')') 1130 | call s:progress_bar(2, s:update.bar, total) 1131 | call s:switch_out() 1132 | endif 1133 | endfunction 1134 | 1135 | function! s:logpos(name) 1136 | for i in range(4, line('$')) 1137 | if getline(i) =~# '^[-+x*] '.a:name.':' 1138 | return i 1139 | endif 1140 | endfor 1141 | endfunction 1142 | 1143 | function! s:log(bullet, name, lines) 1144 | if s:switch_in() 1145 | let pos = s:logpos(a:name) 1146 | if pos > 0 1147 | execute pos 'd _' 1148 | if pos > winheight('.') 1149 | let pos = 4 1150 | endif 1151 | else 1152 | let pos = 4 1153 | endif 1154 | call append(pos - 1, s:format_message(a:bullet, a:name, a:lines)) 1155 | call s:switch_out() 1156 | endif 1157 | endfunction 1158 | 1159 | function! s:update_vim() 1160 | let s:jobs = {} 1161 | 1162 | call s:bar() 1163 | call s:tick() 1164 | endfunction 1165 | 1166 | function! s:tick() 1167 | let pull = s:update.pull 1168 | let prog = s:progress_opt(s:nvim) 1169 | while 1 " Without TCO, Vim stack is bound to explode 1170 | if empty(s:update.todo) 1171 | if empty(s:jobs) && !s:update.fin 1172 | let s:update.fin = 1 1173 | call s:update_finish() 1174 | endif 1175 | return 1176 | endif 1177 | 1178 | let name = keys(s:update.todo)[0] 1179 | let spec = remove(s:update.todo, name) 1180 | let new = !isdirectory(spec.dir) 1181 | 1182 | call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') 1183 | redraw 1184 | 1185 | let has_tag = has_key(spec, 'tag') 1186 | if !new 1187 | let [error, _] = s:git_validate(spec, 0) 1188 | if empty(error) 1189 | if pull 1190 | let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' 1191 | call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir }) 1192 | else 1193 | let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 } 1194 | endif 1195 | else 1196 | let s:jobs[name] = { 'running': 0, 'result': error, 'error': 1 } 1197 | endif 1198 | else 1199 | call s:spawn(name, 1200 | \ printf('git clone %s %s %s %s 2>&1', 1201 | \ has_tag ? '' : s:clone_opt, 1202 | \ prog, 1203 | \ s:shellesc(spec.uri), 1204 | \ s:shellesc(s:trim(spec.dir))), { 'new': 1 }) 1205 | endif 1206 | 1207 | if !s:jobs[name].running 1208 | call s:reap(name) 1209 | endif 1210 | if len(s:jobs) >= s:update.threads 1211 | break 1212 | endif 1213 | endwhile 1214 | endfunction 1215 | 1216 | function! s:update_python() 1217 | let py_exe = has('python') ? 'python' : 'python3' 1218 | execute py_exe "<< EOF" 1219 | import datetime 1220 | import functools 1221 | import os 1222 | try: 1223 | import queue 1224 | except ImportError: 1225 | import Queue as queue 1226 | import random 1227 | import re 1228 | import shutil 1229 | import signal 1230 | import subprocess 1231 | import tempfile 1232 | import threading as thr 1233 | import time 1234 | import traceback 1235 | import vim 1236 | 1237 | G_NVIM = vim.eval("has('nvim')") == '1' 1238 | G_PULL = vim.eval('s:update.pull') == '1' 1239 | G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 1240 | G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) 1241 | G_CLONE_OPT = vim.eval('s:clone_opt') 1242 | G_PROGRESS = vim.eval('s:progress_opt(1)') 1243 | G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) 1244 | G_STOP = thr.Event() 1245 | G_IS_WIN = vim.eval('s:is_win') == '1' 1246 | 1247 | class PlugError(Exception): 1248 | def __init__(self, msg): 1249 | self.msg = msg 1250 | class CmdTimedOut(PlugError): 1251 | pass 1252 | class CmdFailed(PlugError): 1253 | pass 1254 | class InvalidURI(PlugError): 1255 | pass 1256 | class Action(object): 1257 | INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] 1258 | 1259 | class Buffer(object): 1260 | def __init__(self, lock, num_plugs, is_pull): 1261 | self.bar = '' 1262 | self.event = 'Updating' if is_pull else 'Installing' 1263 | self.lock = lock 1264 | self.maxy = int(vim.eval('winheight(".")')) 1265 | self.num_plugs = num_plugs 1266 | 1267 | def __where(self, name): 1268 | """ Find first line with name in current buffer. Return line num. """ 1269 | found, lnum = False, 0 1270 | matcher = re.compile('^[-+x*] {0}:'.format(name)) 1271 | for line in vim.current.buffer: 1272 | if matcher.search(line) is not None: 1273 | found = True 1274 | break 1275 | lnum += 1 1276 | 1277 | if not found: 1278 | lnum = -1 1279 | return lnum 1280 | 1281 | def header(self): 1282 | curbuf = vim.current.buffer 1283 | curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) 1284 | 1285 | num_spaces = self.num_plugs - len(self.bar) 1286 | curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') 1287 | 1288 | with self.lock: 1289 | vim.command('normal! 2G') 1290 | vim.command('redraw') 1291 | 1292 | def write(self, action, name, lines): 1293 | first, rest = lines[0], lines[1:] 1294 | msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] 1295 | msg.extend([' ' + line for line in rest]) 1296 | 1297 | try: 1298 | if action == Action.ERROR: 1299 | self.bar += 'x' 1300 | vim.command("call add(s:update.errors, '{0}')".format(name)) 1301 | elif action == Action.DONE: 1302 | self.bar += '=' 1303 | 1304 | curbuf = vim.current.buffer 1305 | lnum = self.__where(name) 1306 | if lnum != -1: # Found matching line num 1307 | del curbuf[lnum] 1308 | if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): 1309 | lnum = 3 1310 | else: 1311 | lnum = 3 1312 | curbuf.append(msg, lnum) 1313 | 1314 | self.header() 1315 | except vim.error: 1316 | pass 1317 | 1318 | class Command(object): 1319 | CD = 'cd /d' if G_IS_WIN else 'cd' 1320 | 1321 | def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): 1322 | self.cmd = cmd 1323 | if cmd_dir: 1324 | self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) 1325 | self.timeout = timeout 1326 | self.callback = cb if cb else (lambda msg: None) 1327 | self.clean = clean if clean else (lambda: None) 1328 | self.proc = None 1329 | 1330 | @property 1331 | def alive(self): 1332 | """ Returns true only if command still running. """ 1333 | return self.proc and self.proc.poll() is None 1334 | 1335 | def execute(self, ntries=3): 1336 | """ Execute the command with ntries if CmdTimedOut. 1337 | Returns the output of the command if no Exception. 1338 | """ 1339 | attempt, finished, limit = 0, False, self.timeout 1340 | 1341 | while not finished: 1342 | try: 1343 | attempt += 1 1344 | result = self.try_command() 1345 | finished = True 1346 | return result 1347 | except CmdTimedOut: 1348 | if attempt != ntries: 1349 | self.notify_retry() 1350 | self.timeout += limit 1351 | else: 1352 | raise 1353 | 1354 | def notify_retry(self): 1355 | """ Retry required for command, notify user. """ 1356 | for count in range(3, 0, -1): 1357 | if G_STOP.is_set(): 1358 | raise KeyboardInterrupt 1359 | msg = 'Timeout. Will retry in {0} second{1} ...'.format( 1360 | count, 's' if count != 1 else '') 1361 | self.callback([msg]) 1362 | time.sleep(1) 1363 | self.callback(['Retrying ...']) 1364 | 1365 | def try_command(self): 1366 | """ Execute a cmd & poll for callback. Returns list of output. 1367 | Raises CmdFailed -> return code for Popen isn't 0 1368 | Raises CmdTimedOut -> command exceeded timeout without new output 1369 | """ 1370 | first_line = True 1371 | 1372 | try: 1373 | tfile = tempfile.NamedTemporaryFile(mode='w+b') 1374 | preexec_fn = not G_IS_WIN and os.setsid or None 1375 | self.proc = subprocess.Popen(self.cmd, stdout=tfile, 1376 | stderr=subprocess.STDOUT, 1377 | stdin=subprocess.PIPE, shell=True, 1378 | preexec_fn=preexec_fn) 1379 | thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) 1380 | thrd.start() 1381 | 1382 | thread_not_started = True 1383 | while thread_not_started: 1384 | try: 1385 | thrd.join(0.1) 1386 | thread_not_started = False 1387 | except RuntimeError: 1388 | pass 1389 | 1390 | while self.alive: 1391 | if G_STOP.is_set(): 1392 | raise KeyboardInterrupt 1393 | 1394 | if first_line or random.random() < G_LOG_PROB: 1395 | first_line = False 1396 | line = '' if G_IS_WIN else nonblock_read(tfile.name) 1397 | if line: 1398 | self.callback([line]) 1399 | 1400 | time_diff = time.time() - os.path.getmtime(tfile.name) 1401 | if time_diff > self.timeout: 1402 | raise CmdTimedOut(['Timeout!']) 1403 | 1404 | thrd.join(0.5) 1405 | 1406 | tfile.seek(0) 1407 | result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] 1408 | 1409 | if self.proc.returncode != 0: 1410 | raise CmdFailed([''] + result) 1411 | 1412 | return result 1413 | except: 1414 | self.terminate() 1415 | raise 1416 | 1417 | def terminate(self): 1418 | """ Terminate process and cleanup. """ 1419 | if self.alive: 1420 | if G_IS_WIN: 1421 | os.kill(self.proc.pid, signal.SIGINT) 1422 | else: 1423 | os.killpg(self.proc.pid, signal.SIGTERM) 1424 | self.clean() 1425 | 1426 | class Plugin(object): 1427 | def __init__(self, name, args, buf_q, lock): 1428 | self.name = name 1429 | self.args = args 1430 | self.buf_q = buf_q 1431 | self.lock = lock 1432 | self.tag = args.get('tag', 0) 1433 | 1434 | def manage(self): 1435 | try: 1436 | if os.path.exists(self.args['dir']): 1437 | self.update() 1438 | else: 1439 | self.install() 1440 | with self.lock: 1441 | thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) 1442 | except PlugError as exc: 1443 | self.write(Action.ERROR, self.name, exc.msg) 1444 | except KeyboardInterrupt: 1445 | G_STOP.set() 1446 | self.write(Action.ERROR, self.name, ['Interrupted!']) 1447 | except: 1448 | # Any exception except those above print stack trace 1449 | msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) 1450 | self.write(Action.ERROR, self.name, msg.split('\n')) 1451 | raise 1452 | 1453 | def install(self): 1454 | target = self.args['dir'] 1455 | if target[-1] == '\\': 1456 | target = target[0:-1] 1457 | 1458 | def clean(target): 1459 | def _clean(): 1460 | try: 1461 | shutil.rmtree(target) 1462 | except OSError: 1463 | pass 1464 | return _clean 1465 | 1466 | self.write(Action.INSTALL, self.name, ['Installing ...']) 1467 | callback = functools.partial(self.write, Action.INSTALL, self.name) 1468 | cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( 1469 | '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], 1470 | esc(target)) 1471 | com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) 1472 | result = com.execute(G_RETRIES) 1473 | self.write(Action.DONE, self.name, result[-1:]) 1474 | 1475 | def repo_uri(self): 1476 | cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' 1477 | command = Command(cmd, self.args['dir'], G_TIMEOUT,) 1478 | result = command.execute(G_RETRIES) 1479 | return result[-1] 1480 | 1481 | def update(self): 1482 | match = re.compile(r'git::?@') 1483 | actual_uri = re.sub(match, '', self.repo_uri()) 1484 | expect_uri = re.sub(match, '', self.args['uri']) 1485 | if actual_uri != expect_uri: 1486 | msg = ['', 1487 | 'Invalid URI: {0}'.format(actual_uri), 1488 | 'Expected {0}'.format(expect_uri), 1489 | 'PlugClean required.'] 1490 | raise InvalidURI(msg) 1491 | 1492 | if G_PULL: 1493 | self.write(Action.UPDATE, self.name, ['Updating ...']) 1494 | callback = functools.partial(self.write, Action.UPDATE, self.name) 1495 | fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' 1496 | cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) 1497 | com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) 1498 | result = com.execute(G_RETRIES) 1499 | self.write(Action.DONE, self.name, result[-1:]) 1500 | else: 1501 | self.write(Action.DONE, self.name, ['Already installed']) 1502 | 1503 | def write(self, action, name, msg): 1504 | self.buf_q.put((action, name, msg)) 1505 | 1506 | class PlugThread(thr.Thread): 1507 | def __init__(self, tname, args): 1508 | super(PlugThread, self).__init__() 1509 | self.tname = tname 1510 | self.args = args 1511 | 1512 | def run(self): 1513 | thr.current_thread().name = self.tname 1514 | buf_q, work_q, lock = self.args 1515 | 1516 | try: 1517 | while not G_STOP.is_set(): 1518 | name, args = work_q.get_nowait() 1519 | plug = Plugin(name, args, buf_q, lock) 1520 | plug.manage() 1521 | work_q.task_done() 1522 | except queue.Empty: 1523 | pass 1524 | 1525 | class RefreshThread(thr.Thread): 1526 | def __init__(self, lock): 1527 | super(RefreshThread, self).__init__() 1528 | self.lock = lock 1529 | self.running = True 1530 | 1531 | def run(self): 1532 | while self.running: 1533 | with self.lock: 1534 | thread_vim_command('noautocmd normal! a') 1535 | time.sleep(0.33) 1536 | 1537 | def stop(self): 1538 | self.running = False 1539 | 1540 | if G_NVIM: 1541 | def thread_vim_command(cmd): 1542 | vim.session.threadsafe_call(lambda: vim.command(cmd)) 1543 | else: 1544 | def thread_vim_command(cmd): 1545 | vim.command(cmd) 1546 | 1547 | def esc(name): 1548 | return '"' + name.replace('"', '\"') + '"' 1549 | 1550 | def nonblock_read(fname): 1551 | """ Read a file with nonblock flag. Return the last line. """ 1552 | fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) 1553 | buf = os.read(fread, 100000).decode('utf-8', 'replace') 1554 | os.close(fread) 1555 | 1556 | line = buf.rstrip('\r\n') 1557 | left = max(line.rfind('\r'), line.rfind('\n')) 1558 | if left != -1: 1559 | left += 1 1560 | line = line[left:] 1561 | 1562 | return line 1563 | 1564 | def main(): 1565 | thr.current_thread().name = 'main' 1566 | nthreads = int(vim.eval('s:update.threads')) 1567 | plugs = vim.eval('s:update.todo') 1568 | mac_gui = vim.eval('s:mac_gui') == '1' 1569 | 1570 | lock = thr.Lock() 1571 | buf = Buffer(lock, len(plugs), G_PULL) 1572 | buf_q, work_q = queue.Queue(), queue.Queue() 1573 | for work in plugs.items(): 1574 | work_q.put(work) 1575 | 1576 | start_cnt = thr.active_count() 1577 | for num in range(nthreads): 1578 | tname = 'PlugT-{0:02}'.format(num) 1579 | thread = PlugThread(tname, (buf_q, work_q, lock)) 1580 | thread.start() 1581 | if mac_gui: 1582 | rthread = RefreshThread(lock) 1583 | rthread.start() 1584 | 1585 | while not buf_q.empty() or thr.active_count() != start_cnt: 1586 | try: 1587 | action, name, msg = buf_q.get(True, 0.25) 1588 | buf.write(action, name, ['OK'] if not msg else msg) 1589 | buf_q.task_done() 1590 | except queue.Empty: 1591 | pass 1592 | except KeyboardInterrupt: 1593 | G_STOP.set() 1594 | 1595 | if mac_gui: 1596 | rthread.stop() 1597 | rthread.join() 1598 | 1599 | main() 1600 | EOF 1601 | endfunction 1602 | 1603 | function! s:update_ruby() 1604 | ruby << EOF 1605 | module PlugStream 1606 | SEP = ["\r", "\n", nil] 1607 | def get_line 1608 | buffer = '' 1609 | loop do 1610 | char = readchar rescue return 1611 | if SEP.include? char.chr 1612 | buffer << $/ 1613 | break 1614 | else 1615 | buffer << char 1616 | end 1617 | end 1618 | buffer 1619 | end 1620 | end unless defined?(PlugStream) 1621 | 1622 | def esc arg 1623 | %["#{arg.gsub('"', '\"')}"] 1624 | end 1625 | 1626 | def killall pid 1627 | pids = [pid] 1628 | if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM 1629 | pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } 1630 | else 1631 | unless `which pgrep 2> /dev/null`.empty? 1632 | children = pids 1633 | until children.empty? 1634 | children = children.map { |pid| 1635 | `pgrep -P #{pid}`.lines.map { |l| l.chomp } 1636 | }.flatten 1637 | pids += children 1638 | end 1639 | end 1640 | pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } 1641 | end 1642 | end 1643 | 1644 | require 'thread' 1645 | require 'fileutils' 1646 | require 'timeout' 1647 | running = true 1648 | iswin = VIM::evaluate('s:is_win').to_i == 1 1649 | pull = VIM::evaluate('s:update.pull').to_i == 1 1650 | base = VIM::evaluate('g:plug_home') 1651 | all = VIM::evaluate('s:update.todo') 1652 | limit = VIM::evaluate('get(g:, "plug_timeout", 60)') 1653 | tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 1654 | nthr = VIM::evaluate('s:update.threads').to_i 1655 | maxy = VIM::evaluate('winheight(".")').to_i 1656 | cd = iswin ? 'cd /d' : 'cd' 1657 | tot = VIM::evaluate('len(s:update.todo)') || 0 1658 | bar = '' 1659 | skip = 'Already installed' 1660 | mtx = Mutex.new 1661 | take1 = proc { mtx.synchronize { running && all.shift } } 1662 | logh = proc { 1663 | cnt = bar.length 1664 | $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" 1665 | $curbuf[2] = '[' + bar.ljust(tot) + ']' 1666 | VIM::command('normal! 2G') 1667 | VIM::command('redraw') 1668 | } 1669 | where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } 1670 | log = proc { |name, result, type| 1671 | mtx.synchronize do 1672 | ing = ![true, false].include?(type) 1673 | bar += type ? '=' : 'x' unless ing 1674 | b = case type 1675 | when :install then '+' when :update then '*' 1676 | when true, nil then '-' else 1677 | VIM::command("call add(s:update.errors, '#{name}')") 1678 | 'x' 1679 | end 1680 | result = 1681 | if type || type.nil? 1682 | ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] 1683 | elsif result =~ /^Interrupted|^Timeout/ 1684 | ["#{b} #{name}: #{result}"] 1685 | else 1686 | ["#{b} #{name}"] + result.lines.map { |l| " " << l } 1687 | end 1688 | if lnum = where.call(name) 1689 | $curbuf.delete lnum 1690 | lnum = 4 if ing && lnum > maxy 1691 | end 1692 | result.each_with_index do |line, offset| 1693 | $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) 1694 | end 1695 | logh.call 1696 | end 1697 | } 1698 | bt = proc { |cmd, name, type, cleanup| 1699 | tried = timeout = 0 1700 | begin 1701 | tried += 1 1702 | timeout += limit 1703 | fd = nil 1704 | data = '' 1705 | if iswin 1706 | Timeout::timeout(timeout) do 1707 | tmp = VIM::evaluate('tempname()') 1708 | system("(#{cmd}) > #{tmp}") 1709 | data = File.read(tmp).chomp 1710 | File.unlink tmp rescue nil 1711 | end 1712 | else 1713 | fd = IO.popen(cmd).extend(PlugStream) 1714 | first_line = true 1715 | log_prob = 1.0 / nthr 1716 | while line = Timeout::timeout(timeout) { fd.get_line } 1717 | data << line 1718 | log.call name, line.chomp, type if name && (first_line || rand < log_prob) 1719 | first_line = false 1720 | end 1721 | fd.close 1722 | end 1723 | [$? == 0, data.chomp] 1724 | rescue Timeout::Error, Interrupt => e 1725 | if fd && !fd.closed? 1726 | killall fd.pid 1727 | fd.close 1728 | end 1729 | cleanup.call if cleanup 1730 | if e.is_a?(Timeout::Error) && tried < tries 1731 | 3.downto(1) do |countdown| 1732 | s = countdown > 1 ? 's' : '' 1733 | log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type 1734 | sleep 1 1735 | end 1736 | log.call name, 'Retrying ...', type 1737 | retry 1738 | end 1739 | [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] 1740 | end 1741 | } 1742 | main = Thread.current 1743 | threads = [] 1744 | watcher = Thread.new { 1745 | while VIM::evaluate('getchar(1)') 1746 | sleep 0.1 1747 | end 1748 | mtx.synchronize do 1749 | running = false 1750 | threads.each { |t| t.raise Interrupt } 1751 | end 1752 | threads.each { |t| t.join rescue nil } 1753 | main.kill 1754 | } 1755 | refresh = Thread.new { 1756 | while true 1757 | mtx.synchronize do 1758 | break unless running 1759 | VIM::command('noautocmd normal! a') 1760 | end 1761 | sleep 0.2 1762 | end 1763 | } if VIM::evaluate('s:mac_gui') == 1 1764 | 1765 | clone_opt = VIM::evaluate('s:clone_opt') 1766 | progress = VIM::evaluate('s:progress_opt(1)') 1767 | nthr.times do 1768 | mtx.synchronize do 1769 | threads << Thread.new { 1770 | while pair = take1.call 1771 | name = pair.first 1772 | dir, uri, tag = pair.last.values_at *%w[dir uri tag] 1773 | exists = File.directory? dir 1774 | ok, result = 1775 | if exists 1776 | chdir = "#{cd} #{iswin ? dir : esc(dir)}" 1777 | ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil 1778 | current_uri = data.lines.to_a.last 1779 | if !ret 1780 | if data =~ /^Interrupted|^Timeout/ 1781 | [false, data] 1782 | else 1783 | [false, [data.chomp, "PlugClean required."].join($/)] 1784 | end 1785 | elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '') 1786 | [false, ["Invalid URI: #{current_uri}", 1787 | "Expected: #{uri}", 1788 | "PlugClean required."].join($/)] 1789 | else 1790 | if pull 1791 | log.call name, 'Updating ...', :update 1792 | fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' 1793 | bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil 1794 | else 1795 | [true, skip] 1796 | end 1797 | end 1798 | else 1799 | d = esc dir.sub(%r{[\\/]+$}, '') 1800 | log.call name, 'Installing ...', :install 1801 | bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { 1802 | FileUtils.rm_rf dir 1803 | } 1804 | end 1805 | mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok 1806 | log.call name, result, ok 1807 | end 1808 | } if running 1809 | end 1810 | end 1811 | threads.each { |t| t.join rescue nil } 1812 | logh.call 1813 | refresh.kill if refresh 1814 | watcher.kill 1815 | EOF 1816 | endfunction 1817 | 1818 | function! s:shellesc(arg) 1819 | return '"'.escape(a:arg, '"').'"' 1820 | endfunction 1821 | 1822 | function! s:glob_dir(path) 1823 | return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') 1824 | endfunction 1825 | 1826 | function! s:progress_bar(line, bar, total) 1827 | call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') 1828 | endfunction 1829 | 1830 | function! s:compare_git_uri(a, b) 1831 | let a = substitute(a:a, 'git:\{1,2}@', '', '') 1832 | let b = substitute(a:b, 'git:\{1,2}@', '', '') 1833 | return a ==# b 1834 | endfunction 1835 | 1836 | function! s:format_message(bullet, name, message) 1837 | if a:bullet != 'x' 1838 | return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] 1839 | else 1840 | let lines = map(s:lines(a:message), '" ".v:val') 1841 | return extend([printf('x %s:', a:name)], lines) 1842 | endif 1843 | endfunction 1844 | 1845 | function! s:with_cd(cmd, dir) 1846 | return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) 1847 | endfunction 1848 | 1849 | function! s:system(cmd, ...) 1850 | try 1851 | let [sh, shrd] = s:chsh(1) 1852 | let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd 1853 | return system(s:is_win ? '('.cmd.')' : cmd) 1854 | finally 1855 | let [&shell, &shellredir] = [sh, shrd] 1856 | endtry 1857 | endfunction 1858 | 1859 | function! s:system_chomp(...) 1860 | let ret = call('s:system', a:000) 1861 | return v:shell_error ? '' : substitute(ret, '\n$', '', '') 1862 | endfunction 1863 | 1864 | function! s:git_validate(spec, check_branch) 1865 | let err = '' 1866 | if isdirectory(a:spec.dir) 1867 | let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) 1868 | let remote = result[-1] 1869 | if v:shell_error 1870 | let err = join([remote, 'PlugClean required.'], "\n") 1871 | elseif !s:compare_git_uri(remote, a:spec.uri) 1872 | let err = join(['Invalid URI: '.remote, 1873 | \ 'Expected: '.a:spec.uri, 1874 | \ 'PlugClean required.'], "\n") 1875 | elseif a:check_branch && has_key(a:spec, 'commit') 1876 | let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) 1877 | let sha = result[-1] 1878 | if v:shell_error 1879 | let err = join(add(result, 'PlugClean required.'), "\n") 1880 | elseif !s:hash_match(sha, a:spec.commit) 1881 | let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', 1882 | \ a:spec.commit[:6], sha[:6]), 1883 | \ 'PlugUpdate required.'], "\n") 1884 | endif 1885 | elseif a:check_branch 1886 | let branch = result[0] 1887 | " Check tag 1888 | if has_key(a:spec, 'tag') 1889 | let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) 1890 | if a:spec.tag !=# tag 1891 | let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', 1892 | \ (empty(tag) ? 'N/A' : tag), a:spec.tag) 1893 | endif 1894 | " Check branch 1895 | elseif a:spec.branch !=# branch 1896 | let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', 1897 | \ branch, a:spec.branch) 1898 | endif 1899 | if empty(err) 1900 | let commits = len(s:lines(s:system(printf('git rev-list origin/%s..HEAD', a:spec.branch), a:spec.dir))) 1901 | if !v:shell_error && commits 1902 | let err = join([printf('Diverged from origin/%s by %d commit(s).', a:spec.branch, commits), 1903 | \ 'Reinstall after PlugClean.'], "\n") 1904 | endif 1905 | endif 1906 | endif 1907 | else 1908 | let err = 'Not found' 1909 | endif 1910 | return [err, err =~# 'PlugClean'] 1911 | endfunction 1912 | 1913 | function! s:rm_rf(dir) 1914 | if isdirectory(a:dir) 1915 | call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(a:dir)) 1916 | endif 1917 | endfunction 1918 | 1919 | function! s:clean(force) 1920 | call s:prepare() 1921 | call append(0, 'Searching for invalid plugins in '.g:plug_home) 1922 | call append(1, '') 1923 | 1924 | " List of valid directories 1925 | let dirs = [] 1926 | let errs = {} 1927 | let [cnt, total] = [0, len(g:plugs)] 1928 | for [name, spec] in items(g:plugs) 1929 | if !s:is_managed(name) 1930 | call add(dirs, spec.dir) 1931 | else 1932 | let [err, clean] = s:git_validate(spec, 1) 1933 | if clean 1934 | let errs[spec.dir] = s:lines(err)[0] 1935 | else 1936 | call add(dirs, spec.dir) 1937 | endif 1938 | endif 1939 | let cnt += 1 1940 | call s:progress_bar(2, repeat('=', cnt), total) 1941 | normal! 2G 1942 | redraw 1943 | endfor 1944 | 1945 | let allowed = {} 1946 | for dir in dirs 1947 | let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 1948 | let allowed[dir] = 1 1949 | for child in s:glob_dir(dir) 1950 | let allowed[child] = 1 1951 | endfor 1952 | endfor 1953 | 1954 | let todo = [] 1955 | let found = sort(s:glob_dir(g:plug_home)) 1956 | while !empty(found) 1957 | let f = remove(found, 0) 1958 | if !has_key(allowed, f) && isdirectory(f) 1959 | call add(todo, f) 1960 | call append(line('$'), '- ' . f) 1961 | if has_key(errs, f) 1962 | call append(line('$'), ' ' . errs[f]) 1963 | endif 1964 | let found = filter(found, 'stridx(v:val, f) != 0') 1965 | end 1966 | endwhile 1967 | 1968 | 4 1969 | redraw 1970 | if empty(todo) 1971 | call append(line('$'), 'Already clean.') 1972 | else 1973 | if a:force || s:ask('Proceed?') 1974 | for dir in todo 1975 | call s:rm_rf(dir) 1976 | endfor 1977 | call append(3, ['Removed.', '']) 1978 | else 1979 | call append(3, ['Cancelled.', '']) 1980 | endif 1981 | endif 1982 | 4 1983 | endfunction 1984 | 1985 | function! s:upgrade() 1986 | echo 'Downloading the latest version of vim-plug' 1987 | redraw 1988 | let tmp = tempname() 1989 | let new = tmp . '/plug.vim' 1990 | 1991 | try 1992 | let out = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp)) 1993 | if v:shell_error 1994 | return s:err('Error upgrading vim-plug: '. out) 1995 | endif 1996 | 1997 | if readfile(s:me) ==# readfile(new) 1998 | echo 'vim-plug is already up-to-date' 1999 | return 0 2000 | else 2001 | call rename(s:me, s:me . '.old') 2002 | call rename(new, s:me) 2003 | unlet g:loaded_plug 2004 | echo 'vim-plug has been upgraded' 2005 | return 1 2006 | endif 2007 | finally 2008 | silent! call s:rm_rf(tmp) 2009 | endtry 2010 | endfunction 2011 | 2012 | function! s:upgrade_specs() 2013 | for spec in values(g:plugs) 2014 | let spec.frozen = get(spec, 'frozen', 0) 2015 | endfor 2016 | endfunction 2017 | 2018 | function! s:status() 2019 | call s:prepare() 2020 | call append(0, 'Checking plugins') 2021 | call append(1, '') 2022 | 2023 | let ecnt = 0 2024 | let unloaded = 0 2025 | let [cnt, total] = [0, len(g:plugs)] 2026 | for [name, spec] in items(g:plugs) 2027 | if has_key(spec, 'uri') 2028 | if isdirectory(spec.dir) 2029 | let [err, _] = s:git_validate(spec, 1) 2030 | let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] 2031 | else 2032 | let [valid, msg] = [0, 'Not found. Try PlugInstall.'] 2033 | endif 2034 | else 2035 | if isdirectory(spec.dir) 2036 | let [valid, msg] = [1, 'OK'] 2037 | else 2038 | let [valid, msg] = [0, 'Not found.'] 2039 | endif 2040 | endif 2041 | let cnt += 1 2042 | let ecnt += !valid 2043 | " `s:loaded` entry can be missing if PlugUpgraded 2044 | if valid && get(s:loaded, name, -1) == 0 2045 | let unloaded = 1 2046 | let msg .= ' (not loaded)' 2047 | endif 2048 | call s:progress_bar(2, repeat('=', cnt), total) 2049 | call append(3, s:format_message(valid ? '-' : 'x', name, msg)) 2050 | normal! 2G 2051 | redraw 2052 | endfor 2053 | call setline(1, 'Finished. '.ecnt.' error(s).') 2054 | normal! gg 2055 | setlocal nomodifiable 2056 | if unloaded 2057 | echo "Press 'L' on each line to load plugin, or 'U' to update" 2058 | nnoremap L :call status_load(line('.')) 2059 | xnoremap L :call status_load(line('.')) 2060 | end 2061 | endfunction 2062 | 2063 | function! s:extract_name(str, prefix, suffix) 2064 | return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') 2065 | endfunction 2066 | 2067 | function! s:status_load(lnum) 2068 | let line = getline(a:lnum) 2069 | let name = s:extract_name(line, '-', '(not loaded)') 2070 | if !empty(name) 2071 | call plug#load(name) 2072 | setlocal modifiable 2073 | call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) 2074 | setlocal nomodifiable 2075 | endif 2076 | endfunction 2077 | 2078 | function! s:status_update() range 2079 | let lines = getline(a:firstline, a:lastline) 2080 | let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') 2081 | if !empty(names) 2082 | echo 2083 | execute 'PlugUpdate' join(names) 2084 | endif 2085 | endfunction 2086 | 2087 | function! s:is_preview_window_open() 2088 | silent! wincmd P 2089 | if &previewwindow 2090 | wincmd p 2091 | return 1 2092 | endif 2093 | endfunction 2094 | 2095 | function! s:find_name(lnum) 2096 | for lnum in reverse(range(1, a:lnum)) 2097 | let line = getline(lnum) 2098 | if empty(line) 2099 | return '' 2100 | endif 2101 | let name = s:extract_name(line, '-', '') 2102 | if !empty(name) 2103 | return name 2104 | endif 2105 | endfor 2106 | return '' 2107 | endfunction 2108 | 2109 | function! s:preview_commit() 2110 | if b:plug_preview < 0 2111 | let b:plug_preview = !s:is_preview_window_open() 2112 | endif 2113 | 2114 | let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7}') 2115 | if empty(sha) 2116 | return 2117 | endif 2118 | 2119 | let name = s:find_name(line('.')) 2120 | if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) 2121 | return 2122 | endif 2123 | 2124 | execute 'pedit' sha 2125 | wincmd P 2126 | setlocal filetype=git buftype=nofile nobuflisted modifiable 2127 | execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha 2128 | normal! gg"_dd 2129 | setlocal nomodifiable 2130 | nnoremap q :q 2131 | wincmd p 2132 | endfunction 2133 | 2134 | function! s:section(flags) 2135 | call search('\(^[x-] \)\@<=[^:]\+:', a:flags) 2136 | endfunction 2137 | 2138 | function! s:format_git_log(line) 2139 | let indent = ' ' 2140 | let tokens = split(a:line, nr2char(1)) 2141 | if len(tokens) != 5 2142 | return indent.substitute(a:line, '\s*$', '', '') 2143 | endif 2144 | let [graph, sha, refs, subject, date] = tokens 2145 | let tag = matchstr(refs, 'tag: [^,)]\+') 2146 | let tag = empty(tag) ? ' ' : ' ('.tag.') ' 2147 | return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) 2148 | endfunction 2149 | 2150 | function! s:append_ul(lnum, text) 2151 | call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) 2152 | endfunction 2153 | 2154 | function! s:diff() 2155 | call s:prepare() 2156 | call append(0, ['Collecting changes ...', '']) 2157 | let cnts = [0, 0] 2158 | let bar = '' 2159 | let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') 2160 | call s:progress_bar(2, bar, len(total)) 2161 | for origin in [1, 0] 2162 | let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) 2163 | if empty(plugs) 2164 | continue 2165 | endif 2166 | call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') 2167 | for [k, v] in plugs 2168 | let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' 2169 | let diff = s:system_chomp('git log --graph --color=never --pretty=format:"%x01%h%x01%d%x01%s%x01%cr" '.s:shellesc(range), v.dir) 2170 | if !empty(diff) 2171 | let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' 2172 | call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) 2173 | let cnts[origin] += 1 2174 | endif 2175 | let bar .= '=' 2176 | call s:progress_bar(2, bar, len(total)) 2177 | normal! 2G 2178 | redraw 2179 | endfor 2180 | if !cnts[origin] 2181 | call append(5, ['', 'N/A']) 2182 | endif 2183 | endfor 2184 | call setline(1, printf('%d plugin(s) updated.', cnts[0]) 2185 | \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) 2186 | 2187 | if cnts[0] || cnts[1] 2188 | nnoremap :silent! call preview_commit() 2189 | nnoremap o :silent! call preview_commit() 2190 | endif 2191 | if cnts[0] 2192 | nnoremap X :call revert() 2193 | echo "Press 'X' on each block to revert the update" 2194 | endif 2195 | normal! gg 2196 | setlocal nomodifiable 2197 | endfunction 2198 | 2199 | function! s:revert() 2200 | if search('^Pending updates', 'bnW') 2201 | return 2202 | endif 2203 | 2204 | let name = s:find_name(line('.')) 2205 | if empty(name) || !has_key(g:plugs, name) || 2206 | \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' 2207 | return 2208 | endif 2209 | 2210 | call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch), g:plugs[name].dir) 2211 | setlocal modifiable 2212 | normal! "_dap 2213 | setlocal nomodifiable 2214 | echo 'Reverted.' 2215 | endfunction 2216 | 2217 | function! s:snapshot(force, ...) abort 2218 | call s:prepare() 2219 | setf vim 2220 | call append(0, ['" Generated by vim-plug', 2221 | \ '" '.strftime("%c"), 2222 | \ '" :source this file in vim to restore the snapshot', 2223 | \ '" or execute: vim -S snapshot.vim', 2224 | \ '', '', 'PlugUpdate!']) 2225 | 1 2226 | let anchor = line('$') - 3 2227 | let names = sort(keys(filter(copy(g:plugs), 2228 | \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) 2229 | for name in reverse(names) 2230 | let sha = s:system_chomp('git rev-parse --short HEAD', g:plugs[name].dir) 2231 | if !empty(sha) 2232 | call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) 2233 | redraw 2234 | endif 2235 | endfor 2236 | 2237 | if a:0 > 0 2238 | let fn = expand(a:1) 2239 | if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) 2240 | return 2241 | endif 2242 | call writefile(getline(1, '$'), fn) 2243 | echo 'Saved as '.a:1 2244 | silent execute 'e' s:esc(fn) 2245 | setf vim 2246 | endif 2247 | endfunction 2248 | 2249 | function! s:split_rtp() 2250 | return split(&rtp, '\\\@/ contained nextgroup=swiftImportComponent 10 | syn match swiftImportComponent /\.\<[A-Za-z_][A-Za-z_0-9]*\>/ contained nextgroup=swiftImportComponent 11 | 12 | syn region swiftComment start="/\*" end="\*/" contains=swiftComment,swiftLineComment,swiftTodo 13 | syn region swiftLineComment start="//" end="$" contains=swiftComment,swiftTodo 14 | 15 | syn match swiftLineComment /^#!.*/ 16 | syn match swiftTypeName /\<[A-Z][a-zA-Z_0-9]*\>/ 17 | syn match swiftDecimal /\<[-]\?[0-9]\+\>/ 18 | syn match swiftDecimal /\<[-+]\?[0-9]\+\>/ 19 | 20 | syn match swiftTypeName /\$\*\<\?[A-Z][a-zA-Z0-9_]*\>/ 21 | syn match swiftVarName /%\<[A-z[a-z_0-9]\+\(#[0-9]\+\)\?\>/ 22 | 23 | syn keyword swiftKeyword break case continue default do else for if in static switch repeat return where while skipwhite 24 | 25 | syn keyword swiftKeyword sil internal thunk skipwhite 26 | syn keyword swiftKeyword public hidden private shared public_external hidden_external skipwhite 27 | syn keyword swiftKeyword getter setter allocator initializer enumelt destroyer globalaccessor objc skipwhite 28 | syn keyword swiftKeyword alloc_global alloc_stack alloc_ref alloc_ref_dynamic alloc_box alloc_existential_box alloc_value_buffer dealloc_stack dealloc_box dealloc_existential_box dealloc_ref dealloc_partial_ref dealloc_value_buffer skipwhite 29 | syn keyword swiftKeyword debug_value debug_value_addr skipwhite 30 | syn keyword swiftKeyword load load_unowned store assign mark_uninitialized mark_function_escape copy_addr destroy_addr index_addr index_raw_pointer to skipwhite 31 | syn keyword swiftKeyword strong_retain strong_release strong_retain_unowned ref_to_unowned unowned_to_ref unowned_retain unowned_release load_weak store_unowned store_weak fix_lifetime autorelease_value set_deallocating is_unique is_unique_or_pinned strong_pin strong_unpin skipwhite 32 | syn keyword swiftKeyword function_ref integer_literal float_literal string_literal global_addr skipwhite 33 | syn keyword swiftKeyword class_method super_method witness_method dynamic_method skipwhite 34 | syn keyword swiftKeyword partial_apply builtin skipwhite 35 | syn keyword swiftApplyKeyword apply try_apply skipwhite 36 | syn keyword swiftKeyword metatype value_metatype existential_metatype skipwhite 37 | syn keyword swiftKeyword retain_value release_value tuple tuple_extract tuple_element_addr struct struct_extract struct_element_addr ref_element_addr skipwhite 38 | syn keyword swiftKeyword init_enum_data_addr unchecked_enum_data unchecked_take_enum_data_addr inject_enum_addr skipwhite 39 | syn keyword swiftKeyword init_existential_addr init_existential_metatype deinit_existential_addr open_existential_addr open_existential_box open_existential_metatype init_existential_ref open_existential_ref skipwhite 40 | syn keyword swiftKeyword upcast address_to_pointer pointer_to_address pointer_to_thin_function unchecked_addr_cast unchecked_ref_cast unchecked_ref_cast_addr ref_to_raw_pointer ref_to_bridge_object ref_to_unmanaged unmanaged_to_ref raw_pointer_to_ref skipwhite 41 | syn keyword swiftKeyword convert_function thick_to_objc_metatype thin_function_to_pointer objc_to_thick_metatype thin_to_thick_function is_nonnull unchecked_ref_bit_cast unchecked_trivial_bit_cast bridge_object_to_ref bridge_object_to_word unchecked_bitwise_cast skipwhite 42 | syn keyword swiftKeyword objc_existential_metatype_to_object objc_metatype_to_object objc_protocol skipwhite 43 | syn keyword swiftKeyword unconditional_checked_cast unconditional_checked_cast_addr skipwhite 44 | syn keyword swiftKeyword cond_fail skipwhite 45 | syn keyword swiftKeyword unreachable return throw br cond_br switch_value select_enum select_enum_addr select_value switch_enum switch_enum_addr dynamic_method_br checked_cast_br checked_cast_addr_br skipwhite 46 | syn keyword swiftKeyword project_box project_existential_box project_value_buffer project_block_storage init_block_storage_header copy_block mark_dependence skipwhite 47 | 48 | syn keyword swiftTypeDefinition class extension protocol struct typealias enum skipwhite nextgroup=swiftTypeName 49 | syn region swiftTypeAttributes start="\[" end="\]" skipwhite contained nextgroup=swiftTypeName 50 | syn match swiftTypeName /\<[A-Za-z_][A-Za-z_0-9\.]*\>/ contained nextgroup=swiftTypeParameters 51 | 52 | syn region swiftTypeParameters start="<" end=">" skipwhite contained 53 | 54 | syn keyword swiftFuncDefinition func skipwhite nextgroup=swiftFuncAttributes,swiftFuncName,swiftOperator 55 | syn region swiftFuncAttributes start="\[" end="\]" skipwhite contained nextgroup=swiftFuncName,swiftOperator 56 | syn match swiftFuncName /\<[A-Za-z_][A-Za-z_0-9]*\>/ skipwhite contained nextgroup=swiftTypeParameters 57 | syn keyword swiftFuncKeyword subscript init destructor nextgroup=swiftTypeParameters 58 | 59 | syn keyword swiftVarDefinition var skipwhite nextgroup=swiftVarName 60 | syn keyword swiftVarDefinition let skipwhite nextgroup=swiftVarName 61 | syn match swiftVarName /\<[A-Za-z_][A-Za-z_0-9]*\>/ skipwhite contained 62 | 63 | syn keyword swiftDefinitionModifier static 64 | 65 | syn match swiftImplicitVarName /\$\<[A-Za-z_0-9]\+\>/ 66 | 67 | hi def link swiftImport Include 68 | hi def link swiftImportModule Title 69 | hi def link swiftImportComponent Identifier 70 | hi def link swiftApplyKeyword ModeMsg 71 | hi def link swiftKeyword Statement 72 | hi def link swiftTypeDefinition Define 73 | hi def link swiftTypeName Type 74 | hi def link swiftTypeParameters Special 75 | hi def link swiftTypeAttributes PreProc 76 | hi def link swiftFuncDefinition Define 77 | hi def link swiftDefinitionModifier Define 78 | hi def link swiftFuncName Function 79 | hi def link swiftFuncAttributes PreProc 80 | hi def link swiftFuncKeyword Function 81 | hi def link swiftVarDefinition Define 82 | hi def link swiftVarName Identifier 83 | hi def link swiftImplicitVarName Identifier 84 | hi def link swiftIdentifierKeyword Identifier 85 | hi def link swiftTypeDeclaration Delimiter 86 | hi def link swiftBoolean Boolean 87 | hi def link swiftString String 88 | hi def link swiftInterpolation Special 89 | hi def link swiftComment Comment 90 | hi def link swiftLineComment Comment 91 | hi def link swiftDecimal Number 92 | hi def link swiftHex Number 93 | hi def link swiftOct Number 94 | hi def link swiftBin Number 95 | hi def link swiftOperator Function 96 | hi def link swiftChar Character 97 | hi def link swiftLabel Label 98 | hi def link swiftNew Operator 99 | 100 | let b:current_syntax = "sil" 101 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-trusty/.vim/syntax/swift.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: swift 3 | " Maintainer: Joe Groff 4 | " Last Change: 2013 Feb 2 5 | 6 | if exists("b:current_syntax") 7 | finish 8 | endif 9 | 10 | syn keyword swiftKeyword 11 | \ associatedtype 12 | \ break 13 | \ case 14 | \ catch 15 | \ continue 16 | \ default 17 | \ defer 18 | \ do 19 | \ else 20 | \ fallthrough 21 | \ for 22 | \ guard 23 | \ if 24 | \ in 25 | \ let 26 | \ repeat 27 | \ return 28 | \ switch 29 | \ throw 30 | \ try 31 | \ var 32 | \ where 33 | \ while 34 | syn match swiftMultiwordKeyword 35 | \ "indirect case" 36 | 37 | syn keyword swiftImport skipwhite nextgroup=swiftImportModule 38 | \ import 39 | 40 | syn keyword swiftDefinitionModifier 41 | \ convenience 42 | \ dynamic 43 | \ fileprivate 44 | \ final 45 | \ internal 46 | \ nonmutating 47 | \ override 48 | \ private 49 | \ public 50 | \ required 51 | \ rethrows 52 | \ static 53 | \ throws 54 | 55 | syn keyword swiftIdentifierKeyword 56 | \ Self 57 | \ metatype 58 | \ self 59 | \ super 60 | 61 | syn keyword swiftFuncKeywordGeneral skipwhite nextgroup=swiftTypeParameters 62 | \ init 63 | 64 | syn keyword swiftFuncKeyword 65 | \ deinit 66 | \ subscript 67 | 68 | syn keyword swiftScope 69 | \ autoreleasepool 70 | 71 | syn keyword swiftMutating skipwhite nextgroup=swiftFuncDefinition 72 | \ mutating 73 | syn keyword swiftFuncDefinition skipwhite nextgroup=swiftTypeName,swiftOperator 74 | \ func 75 | 76 | syn keyword swiftTypeDefinition skipwhite nextgroup=swiftTypeName 77 | \ class 78 | \ enum 79 | \ extension 80 | \ protocol 81 | \ struct 82 | \ typealias 83 | 84 | syn keyword swiftVarDefinition skipwhite nextgroup=swiftVarName 85 | \ let 86 | \ var 87 | 88 | syn keyword swiftLabel 89 | \ get 90 | \ set 91 | 92 | syn keyword swiftBoolean 93 | \ false 94 | \ true 95 | 96 | syn keyword swiftNil 97 | \ nil 98 | 99 | syn match swiftImportModule contained nextgroup=swiftImportComponent 100 | \ /\<[A-Za-z_][A-Za-z_0-9]*\>/ 101 | syn match swiftImportComponent contained nextgroup=swiftImportComponent 102 | \ /\.\<[A-Za-z_][A-Za-z_0-9]*\>/ 103 | 104 | syn match swiftTypeName contained nextgroup=swiftTypeParameters 105 | \ /\<[A-Za-z_][A-Za-z_0-9\.]*\>/ 106 | syn match swiftVarName contained skipwhite nextgroup=swiftTypeDeclaration 107 | \ /\<[A-Za-z_][A-Za-z_0-9]*\>/ 108 | syn match swiftImplicitVarName 109 | \ /\$\<[A-Za-z_0-9]\+\>/ 110 | 111 | " TypeName[Optionality]? 112 | syn match swiftType contained nextgroup=swiftTypeParameters 113 | \ /\<[A-Za-z_][A-Za-z_0-9\.]*\>[!?]\?/ 114 | " [Type:Type] (dictionary) or [Type] (array) 115 | syn region swiftType contained contains=swiftTypePair,swiftType 116 | \ matchgroup=Delimiter start=/\[/ end=/\]/ 117 | syn match swiftTypePair contained nextgroup=swiftTypeParameters,swiftTypeDeclaration 118 | \ /\<[A-Za-z_][A-Za-z_0-9\.]*\>[!?]\?/ 119 | " (Type[, Type]) (tuple) 120 | " FIXME: we should be able to use skip="," and drop swiftParamDelim 121 | syn region swiftType contained contains=swiftType,swiftParamDelim 122 | \ matchgroup=Delimiter start="[^@](" end=")" matchgroup=NONE skip="," 123 | syn match swiftParamDelim contained 124 | \ /,/ 125 | " (generics) 126 | syn region swiftTypeParameters contained contains=swiftVarName,swiftConstraint 127 | \ matchgroup=Delimiter start="<" end=">" matchgroup=NONE skip="," 128 | syn keyword swiftConstraint contained 129 | \ where 130 | 131 | syn match swiftTypeDeclaration skipwhite nextgroup=swiftType 132 | \ /:/ 133 | syn match swiftTypeDeclaration skipwhite nextgroup=swiftType 134 | \ /->/ 135 | 136 | syn region swiftString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=swiftInterpolation 137 | syn region swiftInterpolation start=/\\(/ end=/)/ contained 138 | syn region swiftComment start="/\*" end="\*/" contains=swiftComment,swiftLineComment,swiftTodo 139 | syn region swiftLineComment start="//" end="$" contains=swiftComment,swiftTodo 140 | 141 | syn match swiftDecimal /[+\-]\?\<\([0-9][0-9_]*\)\([.][0-9_]*\)\?\([eE][+\-]\?[0-9][0-9_]*\)\?\>/ 142 | syn match swiftHex /[+\-]\?\<0x[0-9A-Fa-f][0-9A-Fa-f_]*\(\([.][0-9A-Fa-f_]*\)\?[pP][+\-]\?[0-9][0-9_]*\)\?\>/ 143 | syn match swiftOct /[+\-]\?\<0o[0-7][0-7_]*\>/ 144 | syn match swiftBin /[+\-]\?\<0b[01][01_]*\>/ 145 | 146 | syn match swiftOperator +\.\@!&|^~]\@!&|^~]*\|*/\@![/=\-+*%<>!&|^~]*\|->\@![/=\-+*%<>!&|^~]*\|[=+%<>!&|^~][/=\-+*%<>!&|^~]*\)+ skipwhite nextgroup=swiftTypeParameters 147 | syn match swiftOperator "\.\.[<.]" skipwhite nextgroup=swiftTypeParameters 148 | 149 | syn match swiftChar /'\([^'\\]\|\\\(["'tnr0\\]\|x[0-9a-fA-F]\{2}\|u[0-9a-fA-F]\{4}\|U[0-9a-fA-F]\{8}\)\)'/ 150 | 151 | syn match swiftPreproc /#\(\\|\\)/ 152 | syn match swiftPreproc /^\s*#\(\\|\\|\\|\\)/ 153 | syn region swiftPreprocFalse start="^\s*#\\s\+\" end="^\s*#\(\\|\\|\\)" 154 | 155 | syn match swiftAttribute /@\<\w\+\>/ skipwhite nextgroup=swiftType 156 | 157 | syn keyword swiftTodo MARK TODO FIXME contained 158 | 159 | syn match swiftCastOp "\" skipwhite nextgroup=swiftType 160 | syn match swiftCastOp "\[!?]\?" skipwhite nextgroup=swiftType 161 | 162 | syn match swiftNilOps "??" 163 | 164 | syn region swiftReservedIdentifier oneline 165 | \ start=/`/ end=/`/ 166 | 167 | hi def link swiftImport Include 168 | hi def link swiftImportModule Title 169 | hi def link swiftImportComponent Identifier 170 | hi def link swiftKeyword Statement 171 | hi def link swiftMultiwordKeyword Statement 172 | hi def link swiftTypeDefinition Define 173 | hi def link swiftType Type 174 | hi def link swiftTypePair Type 175 | hi def link swiftTypeName Function 176 | hi def link swiftConstraint Special 177 | hi def link swiftFuncDefinition Define 178 | hi def link swiftDefinitionModifier Define 179 | hi def link swiftFuncKeyword Function 180 | hi def link swiftFuncKeywordGeneral Function 181 | hi def link swiftVarDefinition Define 182 | hi def link swiftVarName Identifier 183 | hi def link swiftImplicitVarName Identifier 184 | hi def link swiftIdentifierKeyword Identifier 185 | hi def link swiftTypeDeclaration Delimiter 186 | hi def link swiftTypeParameters Delimiter 187 | hi def link swiftBoolean Boolean 188 | hi def link swiftString String 189 | hi def link swiftInterpolation Special 190 | hi def link swiftComment Comment 191 | hi def link swiftLineComment Comment 192 | hi def link swiftDecimal Number 193 | hi def link swiftHex Number 194 | hi def link swiftOct Number 195 | hi def link swiftBin Number 196 | hi def link swiftOperator Function 197 | hi def link swiftChar Character 198 | hi def link swiftLabel Operator 199 | hi def link swiftMutating Statement 200 | hi def link swiftPreproc PreCondit 201 | hi def link swiftPreprocFalse Comment 202 | hi def link swiftAttribute Type 203 | hi def link swiftTodo Todo 204 | hi def link swiftNil Constant 205 | hi def link swiftCastOp Operator 206 | hi def link swiftNilOps Operator 207 | hi def link swiftScope PreProc 208 | 209 | let b:current_syntax = "swift" 210 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-trusty/.vim/syntax/swiftgyb.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: gyb on swift 3 | 4 | runtime! syntax/swift.vim 5 | unlet b:current_syntax 6 | 7 | syn include @Python syntax/python.vim 8 | syn region pythonCode matchgroup=gybPythonCode start=+^ *%+ end=+$+ contains=@Python keepend 9 | syn region pythonCode matchgroup=gybPythonCode start=+%{+ end=+}%+ contains=@Python keepend 10 | syn match gybPythonCode /\${[^}]*}/ 11 | hi def link gybPythonCode CursorLineNr 12 | 13 | let b:current_syntax = "swiftgyb" 14 | 15 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-trusty/.vimrc: -------------------------------------------------------------------------------- 1 | " Make command line two lines high 2 | set ch=2 3 | 4 | set showmatch 5 | set number 6 | set tabstop=4 7 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-trusty/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2016,2017 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | # Dockerfile to build a Docker image with the Swift tools and binaries and 18 | # its dependencies. 19 | 20 | FROM ibmcom/ubuntu:14.04 21 | MAINTAINER IBM Swift Engineering at IBM Cloud 22 | LABEL Description="Linux Ubuntu 14.04 image with the Swift binaries and tools." 23 | 24 | USER root 25 | 26 | # Set environment variables for image 27 | ARG VERSION=${VERSION} 28 | ENV SWIFT_SNAPSHOT swift-${VERSION}-RELEASE 29 | ENV SWIFT_SNAPSHOT_LOWERCASE swift-${VERSION}-release 30 | ENV UBUNTU_VERSION ubuntu14.04 31 | ENV UBUNTU_VERSION_NO_DOTS ubuntu1404 32 | ENV WORK_DIR / 33 | 34 | # Set WORKDIR 35 | WORKDIR ${WORK_DIR} 36 | 37 | # Linux OS utils and libraries and set clang 3.8 as default 38 | RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y \ 39 | build-essential \ 40 | clang-3.8 \ 41 | git \ 42 | libpython2.7 \ 43 | libicu-dev \ 44 | wget \ 45 | libcurl4-openssl-dev \ 46 | vim \ 47 | && apt-get clean \ 48 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ 49 | && update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.8 100 \ 50 | && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.8 100 \ 51 | && echo "set -o vi" >> /root/.bashrc 52 | 53 | # Install Swift compiler 54 | RUN wget --progress=dot:giga https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 55 | https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 56 | && gpg --keyserver hkp://pool.sks-keyservers.net \ 57 | --recv-keys \ 58 | '7463 A81A 4B2E EA1B 551F FBCF D441 C977 412B 37AD' \ 59 | '1BE1 E29A 084C B305 F397 D62A 9F59 7F4D 21A5 6D5F' \ 60 | 'A3BA FD35 56A5 9079 C068 94BD 63BC 1CFE 91D3 06C6' \ 61 | '5E4D F843 FB06 5D7F 7E24 FBA2 EF54 30F0 71E1 B235' \ 62 | '8513 444E 2DA3 6B7C 1659 AF4D 7638 F1FB 2B2B 08C4' \ 63 | 'A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561' \ 64 | && gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys \ 65 | && gpg --verify $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 66 | && tar xzvf $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz --strip-components=1 \ 67 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 68 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 69 | && chmod -R go+r /usr/lib/swift \ 70 | && swift --version 71 | 72 | # Add utilities 73 | COPY .vim /root/.vim 74 | COPY .vimrc /root/.vimrc 75 | 76 | CMD /bin/bash 77 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitura/swift-ubuntu-docker/0870d11e37668daad7e1ce25ab9cc6fd6c82594f/swift-development/swift-ubuntu-xenial-multiarch/.DS_Store -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | swift_install_in_component(editor-integration 2 | DIRECTORY 3 | ftdetect 4 | syntax 5 | DESTINATION "share/vim/vim73" 6 | PATTERN ".*" EXCLUDE) 7 | 8 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/ftdetect/sil.vim: -------------------------------------------------------------------------------- 1 | au BufNewFile,BufRead *.sil set ft=sil 2 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/ftdetect/swift.vim: -------------------------------------------------------------------------------- 1 | au BufNewFile,BufRead *.swift set ft=swift 2 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/ftdetect/swiftgyb.vim: -------------------------------------------------------------------------------- 1 | au BufNewFile,BufRead *.swift.gyb set ft=swiftgyb 2 | 3 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/ftplugin/swift.vim: -------------------------------------------------------------------------------- 1 | setlocal comments=s1:/*,mb:*,ex:*/,:///,:// 2 | setlocal expandtab 3 | setlocal ts=2 4 | setlocal sw=2 5 | setlocal smartindent 6 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/ftplugin/swiftgyb.vim: -------------------------------------------------------------------------------- 1 | runtime! ftplugin/swift.vim 2 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/syntax/sil.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: sil 3 | 4 | if exists("b:current_syntax") 5 | finish 6 | endif 7 | 8 | syn keyword swiftImport import skipwhite nextgroup=swiftImportModule 9 | syn match swiftImportModule /\<[A-Za-z_][A-Za-z_0-9]*\>/ contained nextgroup=swiftImportComponent 10 | syn match swiftImportComponent /\.\<[A-Za-z_][A-Za-z_0-9]*\>/ contained nextgroup=swiftImportComponent 11 | 12 | syn region swiftComment start="/\*" end="\*/" contains=swiftComment,swiftLineComment,swiftTodo 13 | syn region swiftLineComment start="//" end="$" contains=swiftComment,swiftTodo 14 | 15 | syn match swiftLineComment /^#!.*/ 16 | syn match swiftTypeName /\<[A-Z][a-zA-Z_0-9]*\>/ 17 | syn match swiftDecimal /\<[-]\?[0-9]\+\>/ 18 | syn match swiftDecimal /\<[-+]\?[0-9]\+\>/ 19 | 20 | syn match swiftTypeName /\$\*\<\?[A-Z][a-zA-Z0-9_]*\>/ 21 | syn match swiftVarName /%\<[A-z[a-z_0-9]\+\(#[0-9]\+\)\?\>/ 22 | 23 | syn keyword swiftKeyword break case continue default do else for if in static switch repeat return where while skipwhite 24 | 25 | syn keyword swiftKeyword sil internal thunk skipwhite 26 | syn keyword swiftKeyword public hidden private shared public_external hidden_external skipwhite 27 | syn keyword swiftKeyword getter setter allocator initializer enumelt destroyer globalaccessor objc skipwhite 28 | syn keyword swiftKeyword alloc_global alloc_stack alloc_ref alloc_ref_dynamic alloc_box alloc_existential_box alloc_value_buffer dealloc_stack dealloc_box dealloc_existential_box dealloc_ref dealloc_partial_ref dealloc_value_buffer skipwhite 29 | syn keyword swiftKeyword debug_value debug_value_addr skipwhite 30 | syn keyword swiftKeyword load load_unowned store assign mark_uninitialized mark_function_escape copy_addr destroy_addr index_addr index_raw_pointer to skipwhite 31 | syn keyword swiftKeyword strong_retain strong_release strong_retain_unowned ref_to_unowned unowned_to_ref unowned_retain unowned_release load_weak store_unowned store_weak fix_lifetime autorelease_value set_deallocating is_unique is_unique_or_pinned strong_pin strong_unpin skipwhite 32 | syn keyword swiftKeyword function_ref integer_literal float_literal string_literal global_addr skipwhite 33 | syn keyword swiftKeyword class_method super_method witness_method dynamic_method skipwhite 34 | syn keyword swiftKeyword partial_apply builtin skipwhite 35 | syn keyword swiftApplyKeyword apply try_apply skipwhite 36 | syn keyword swiftKeyword metatype value_metatype existential_metatype skipwhite 37 | syn keyword swiftKeyword retain_value release_value tuple tuple_extract tuple_element_addr struct struct_extract struct_element_addr ref_element_addr skipwhite 38 | syn keyword swiftKeyword init_enum_data_addr unchecked_enum_data unchecked_take_enum_data_addr inject_enum_addr skipwhite 39 | syn keyword swiftKeyword init_existential_addr init_existential_metatype deinit_existential_addr open_existential_addr open_existential_box open_existential_metatype init_existential_ref open_existential_ref skipwhite 40 | syn keyword swiftKeyword upcast address_to_pointer pointer_to_address pointer_to_thin_function unchecked_addr_cast unchecked_ref_cast unchecked_ref_cast_addr ref_to_raw_pointer ref_to_bridge_object ref_to_unmanaged unmanaged_to_ref raw_pointer_to_ref skipwhite 41 | syn keyword swiftKeyword convert_function thick_to_objc_metatype thin_function_to_pointer objc_to_thick_metatype thin_to_thick_function is_nonnull unchecked_ref_bit_cast unchecked_trivial_bit_cast bridge_object_to_ref bridge_object_to_word unchecked_bitwise_cast skipwhite 42 | syn keyword swiftKeyword objc_existential_metatype_to_object objc_metatype_to_object objc_protocol skipwhite 43 | syn keyword swiftKeyword unconditional_checked_cast unconditional_checked_cast_addr skipwhite 44 | syn keyword swiftKeyword cond_fail skipwhite 45 | syn keyword swiftKeyword unreachable return throw br cond_br switch_value select_enum select_enum_addr select_value switch_enum switch_enum_addr dynamic_method_br checked_cast_br checked_cast_addr_br skipwhite 46 | syn keyword swiftKeyword project_box project_existential_box project_value_buffer project_block_storage init_block_storage_header copy_block mark_dependence skipwhite 47 | 48 | syn keyword swiftTypeDefinition class extension protocol struct typealias enum skipwhite nextgroup=swiftTypeName 49 | syn region swiftTypeAttributes start="\[" end="\]" skipwhite contained nextgroup=swiftTypeName 50 | syn match swiftTypeName /\<[A-Za-z_][A-Za-z_0-9\.]*\>/ contained nextgroup=swiftTypeParameters 51 | 52 | syn region swiftTypeParameters start="<" end=">" skipwhite contained 53 | 54 | syn keyword swiftFuncDefinition func skipwhite nextgroup=swiftFuncAttributes,swiftFuncName,swiftOperator 55 | syn region swiftFuncAttributes start="\[" end="\]" skipwhite contained nextgroup=swiftFuncName,swiftOperator 56 | syn match swiftFuncName /\<[A-Za-z_][A-Za-z_0-9]*\>/ skipwhite contained nextgroup=swiftTypeParameters 57 | syn keyword swiftFuncKeyword subscript init destructor nextgroup=swiftTypeParameters 58 | 59 | syn keyword swiftVarDefinition var skipwhite nextgroup=swiftVarName 60 | syn keyword swiftVarDefinition let skipwhite nextgroup=swiftVarName 61 | syn match swiftVarName /\<[A-Za-z_][A-Za-z_0-9]*\>/ skipwhite contained 62 | 63 | syn keyword swiftDefinitionModifier static 64 | 65 | syn match swiftImplicitVarName /\$\<[A-Za-z_0-9]\+\>/ 66 | 67 | hi def link swiftImport Include 68 | hi def link swiftImportModule Title 69 | hi def link swiftImportComponent Identifier 70 | hi def link swiftApplyKeyword ModeMsg 71 | hi def link swiftKeyword Statement 72 | hi def link swiftTypeDefinition Define 73 | hi def link swiftTypeName Type 74 | hi def link swiftTypeParameters Special 75 | hi def link swiftTypeAttributes PreProc 76 | hi def link swiftFuncDefinition Define 77 | hi def link swiftDefinitionModifier Define 78 | hi def link swiftFuncName Function 79 | hi def link swiftFuncAttributes PreProc 80 | hi def link swiftFuncKeyword Function 81 | hi def link swiftVarDefinition Define 82 | hi def link swiftVarName Identifier 83 | hi def link swiftImplicitVarName Identifier 84 | hi def link swiftIdentifierKeyword Identifier 85 | hi def link swiftTypeDeclaration Delimiter 86 | hi def link swiftBoolean Boolean 87 | hi def link swiftString String 88 | hi def link swiftInterpolation Special 89 | hi def link swiftComment Comment 90 | hi def link swiftLineComment Comment 91 | hi def link swiftDecimal Number 92 | hi def link swiftHex Number 93 | hi def link swiftOct Number 94 | hi def link swiftBin Number 95 | hi def link swiftOperator Function 96 | hi def link swiftChar Character 97 | hi def link swiftLabel Label 98 | hi def link swiftNew Operator 99 | 100 | let b:current_syntax = "sil" 101 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/syntax/swift.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: swift 3 | " Maintainer: Joe Groff 4 | " Last Change: 2013 Feb 2 5 | 6 | if exists("b:current_syntax") 7 | finish 8 | endif 9 | 10 | syn keyword swiftKeyword 11 | \ associatedtype 12 | \ break 13 | \ case 14 | \ catch 15 | \ continue 16 | \ default 17 | \ defer 18 | \ do 19 | \ else 20 | \ fallthrough 21 | \ for 22 | \ guard 23 | \ if 24 | \ in 25 | \ let 26 | \ repeat 27 | \ return 28 | \ switch 29 | \ throw 30 | \ try 31 | \ var 32 | \ where 33 | \ while 34 | syn match swiftMultiwordKeyword 35 | \ "indirect case" 36 | 37 | syn keyword swiftImport skipwhite nextgroup=swiftImportModule 38 | \ import 39 | 40 | syn keyword swiftDefinitionModifier 41 | \ convenience 42 | \ dynamic 43 | \ fileprivate 44 | \ final 45 | \ internal 46 | \ nonmutating 47 | \ override 48 | \ private 49 | \ public 50 | \ required 51 | \ rethrows 52 | \ static 53 | \ throws 54 | 55 | syn keyword swiftIdentifierKeyword 56 | \ Self 57 | \ metatype 58 | \ self 59 | \ super 60 | 61 | syn keyword swiftFuncKeywordGeneral skipwhite nextgroup=swiftTypeParameters 62 | \ init 63 | 64 | syn keyword swiftFuncKeyword 65 | \ deinit 66 | \ subscript 67 | 68 | syn keyword swiftScope 69 | \ autoreleasepool 70 | 71 | syn keyword swiftMutating skipwhite nextgroup=swiftFuncDefinition 72 | \ mutating 73 | syn keyword swiftFuncDefinition skipwhite nextgroup=swiftTypeName,swiftOperator 74 | \ func 75 | 76 | syn keyword swiftTypeDefinition skipwhite nextgroup=swiftTypeName 77 | \ class 78 | \ enum 79 | \ extension 80 | \ protocol 81 | \ struct 82 | \ typealias 83 | 84 | syn keyword swiftVarDefinition skipwhite nextgroup=swiftVarName 85 | \ let 86 | \ var 87 | 88 | syn keyword swiftLabel 89 | \ get 90 | \ set 91 | 92 | syn keyword swiftBoolean 93 | \ false 94 | \ true 95 | 96 | syn keyword swiftNil 97 | \ nil 98 | 99 | syn match swiftImportModule contained nextgroup=swiftImportComponent 100 | \ /\<[A-Za-z_][A-Za-z_0-9]*\>/ 101 | syn match swiftImportComponent contained nextgroup=swiftImportComponent 102 | \ /\.\<[A-Za-z_][A-Za-z_0-9]*\>/ 103 | 104 | syn match swiftTypeName contained nextgroup=swiftTypeParameters 105 | \ /\<[A-Za-z_][A-Za-z_0-9\.]*\>/ 106 | syn match swiftVarName contained skipwhite nextgroup=swiftTypeDeclaration 107 | \ /\<[A-Za-z_][A-Za-z_0-9]*\>/ 108 | syn match swiftImplicitVarName 109 | \ /\$\<[A-Za-z_0-9]\+\>/ 110 | 111 | " TypeName[Optionality]? 112 | syn match swiftType contained nextgroup=swiftTypeParameters 113 | \ /\<[A-Za-z_][A-Za-z_0-9\.]*\>[!?]\?/ 114 | " [Type:Type] (dictionary) or [Type] (array) 115 | syn region swiftType contained contains=swiftTypePair,swiftType 116 | \ matchgroup=Delimiter start=/\[/ end=/\]/ 117 | syn match swiftTypePair contained nextgroup=swiftTypeParameters,swiftTypeDeclaration 118 | \ /\<[A-Za-z_][A-Za-z_0-9\.]*\>[!?]\?/ 119 | " (Type[, Type]) (tuple) 120 | " FIXME: we should be able to use skip="," and drop swiftParamDelim 121 | syn region swiftType contained contains=swiftType,swiftParamDelim 122 | \ matchgroup=Delimiter start="[^@](" end=")" matchgroup=NONE skip="," 123 | syn match swiftParamDelim contained 124 | \ /,/ 125 | " (generics) 126 | syn region swiftTypeParameters contained contains=swiftVarName,swiftConstraint 127 | \ matchgroup=Delimiter start="<" end=">" matchgroup=NONE skip="," 128 | syn keyword swiftConstraint contained 129 | \ where 130 | 131 | syn match swiftTypeDeclaration skipwhite nextgroup=swiftType 132 | \ /:/ 133 | syn match swiftTypeDeclaration skipwhite nextgroup=swiftType 134 | \ /->/ 135 | 136 | syn region swiftString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=swiftInterpolation 137 | syn region swiftInterpolation start=/\\(/ end=/)/ contained 138 | syn region swiftComment start="/\*" end="\*/" contains=swiftComment,swiftLineComment,swiftTodo 139 | syn region swiftLineComment start="//" end="$" contains=swiftComment,swiftTodo 140 | 141 | syn match swiftDecimal /[+\-]\?\<\([0-9][0-9_]*\)\([.][0-9_]*\)\?\([eE][+\-]\?[0-9][0-9_]*\)\?\>/ 142 | syn match swiftHex /[+\-]\?\<0x[0-9A-Fa-f][0-9A-Fa-f_]*\(\([.][0-9A-Fa-f_]*\)\?[pP][+\-]\?[0-9][0-9_]*\)\?\>/ 143 | syn match swiftOct /[+\-]\?\<0o[0-7][0-7_]*\>/ 144 | syn match swiftBin /[+\-]\?\<0b[01][01_]*\>/ 145 | 146 | syn match swiftOperator +\.\@!&|^~]\@!&|^~]*\|*/\@![/=\-+*%<>!&|^~]*\|->\@![/=\-+*%<>!&|^~]*\|[=+%<>!&|^~][/=\-+*%<>!&|^~]*\)+ skipwhite nextgroup=swiftTypeParameters 147 | syn match swiftOperator "\.\.[<.]" skipwhite nextgroup=swiftTypeParameters 148 | 149 | syn match swiftChar /'\([^'\\]\|\\\(["'tnr0\\]\|x[0-9a-fA-F]\{2}\|u[0-9a-fA-F]\{4}\|U[0-9a-fA-F]\{8}\)\)'/ 150 | 151 | syn match swiftPreproc /#\(\\|\\)/ 152 | syn match swiftPreproc /^\s*#\(\\|\\|\\|\\)/ 153 | syn region swiftPreprocFalse start="^\s*#\\s\+\" end="^\s*#\(\\|\\|\\)" 154 | 155 | syn match swiftAttribute /@\<\w\+\>/ skipwhite nextgroup=swiftType 156 | 157 | syn keyword swiftTodo MARK TODO FIXME contained 158 | 159 | syn match swiftCastOp "\" skipwhite nextgroup=swiftType 160 | syn match swiftCastOp "\[!?]\?" skipwhite nextgroup=swiftType 161 | 162 | syn match swiftNilOps "??" 163 | 164 | syn region swiftReservedIdentifier oneline 165 | \ start=/`/ end=/`/ 166 | 167 | hi def link swiftImport Include 168 | hi def link swiftImportModule Title 169 | hi def link swiftImportComponent Identifier 170 | hi def link swiftKeyword Statement 171 | hi def link swiftMultiwordKeyword Statement 172 | hi def link swiftTypeDefinition Define 173 | hi def link swiftType Type 174 | hi def link swiftTypePair Type 175 | hi def link swiftTypeName Function 176 | hi def link swiftConstraint Special 177 | hi def link swiftFuncDefinition Define 178 | hi def link swiftDefinitionModifier Define 179 | hi def link swiftFuncKeyword Function 180 | hi def link swiftFuncKeywordGeneral Function 181 | hi def link swiftVarDefinition Define 182 | hi def link swiftVarName Identifier 183 | hi def link swiftImplicitVarName Identifier 184 | hi def link swiftIdentifierKeyword Identifier 185 | hi def link swiftTypeDeclaration Delimiter 186 | hi def link swiftTypeParameters Delimiter 187 | hi def link swiftBoolean Boolean 188 | hi def link swiftString String 189 | hi def link swiftInterpolation Special 190 | hi def link swiftComment Comment 191 | hi def link swiftLineComment Comment 192 | hi def link swiftDecimal Number 193 | hi def link swiftHex Number 194 | hi def link swiftOct Number 195 | hi def link swiftBin Number 196 | hi def link swiftOperator Function 197 | hi def link swiftChar Character 198 | hi def link swiftLabel Operator 199 | hi def link swiftMutating Statement 200 | hi def link swiftPreproc PreCondit 201 | hi def link swiftPreprocFalse Comment 202 | hi def link swiftAttribute Type 203 | hi def link swiftTodo Todo 204 | hi def link swiftNil Constant 205 | hi def link swiftCastOp Operator 206 | hi def link swiftNilOps Operator 207 | hi def link swiftScope PreProc 208 | 209 | let b:current_syntax = "swift" 210 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vim/syntax/swiftgyb.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: gyb on swift 3 | 4 | runtime! syntax/swift.vim 5 | unlet b:current_syntax 6 | 7 | syn include @Python syntax/python.vim 8 | syn region pythonCode matchgroup=gybPythonCode start=+^ *%+ end=+$+ contains=@Python keepend 9 | syn region pythonCode matchgroup=gybPythonCode start=+%{+ end=+}%+ contains=@Python keepend 10 | syn match gybPythonCode /\${[^}]*}/ 11 | hi def link gybPythonCode CursorLineNr 12 | 13 | let b:current_syntax = "swiftgyb" 14 | 15 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/.vimrc: -------------------------------------------------------------------------------- 1 | " Make command line two lines high 2 | set ch=2 3 | 4 | set showmatch 5 | set number 6 | set tabstop=4 7 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/amd64/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2016,2017 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | # Dockerfile to build a Docker image with the Swift tools and binaries and 18 | # its dependencies. 19 | 20 | FROM ibmcom/ubuntu:16.04 21 | MAINTAINER IBM Swift Engineering at IBM Cloud 22 | LABEL Description="Linux Ubuntu 16.04 image with the Swift binaries and tools." 23 | 24 | USER root 25 | 26 | # Set environment variables for image 27 | ARG VERSION=${VERSION} 28 | ENV SWIFT_SNAPSHOT swift-${VERSION}-RELEASE 29 | ENV SWIFT_SNAPSHOT_LOWERCASE swift-${VERSION}-release 30 | ENV UBUNTU_VERSION ubuntu16.04 31 | ENV UBUNTU_VERSION_NO_DOTS ubuntu1604 32 | ENV WORK_DIR / 33 | 34 | # Set WORKDIR 35 | WORKDIR ${WORK_DIR} 36 | 37 | # Linux OS utils and libraries and set clang 3.8 as default 38 | RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y \ 39 | build-essential \ 40 | clang-3.8 \ 41 | git \ 42 | libpython2.7 \ 43 | libicu-dev \ 44 | wget \ 45 | libcurl4-openssl-dev \ 46 | openssl \ 47 | libssl-dev \ 48 | vim \ 49 | libxml2-dev \ 50 | && apt-get clean \ 51 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ 52 | && update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.8 100 \ 53 | && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.8 100 \ 54 | && echo "set -o vi" >> /root/.bashrc 55 | 56 | # Install Swift compiler 57 | RUN wget --progress=dot:giga https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 58 | https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 59 | && gpg --keyserver hkp://pool.sks-keyservers.net \ 60 | --recv-keys \ 61 | '7463 A81A 4B2E EA1B 551F FBCF D441 C977 412B 37AD' \ 62 | '1BE1 E29A 084C B305 F397 D62A 9F59 7F4D 21A5 6D5F' \ 63 | 'A3BA FD35 56A5 9079 C068 94BD 63BC 1CFE 91D3 06C6' \ 64 | '5E4D F843 FB06 5D7F 7E24 FBA2 EF54 30F0 71E1 B235' \ 65 | '8513 444E 2DA3 6B7C 1659 AF4D 7638 F1FB 2B2B 08C4' \ 66 | 'A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561' \ 67 | && gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys \ 68 | && gpg --verify $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 69 | && tar xzvf $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz --strip-components=1 \ 70 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 71 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 72 | && chmod -R go+r /usr/lib/swift \ 73 | && swift --version 74 | 75 | # Add utilities 76 | COPY .vim /root/.vim 77 | COPY .vimrc /root/.vimrc 78 | 79 | CMD /bin/bash 80 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/manifest.yml: -------------------------------------------------------------------------------- 1 | image: ibmcom/swift-ubuntu-xenial:latest 2 | manifests: 3 | - 4 | image: ibmcom/swift-ubuntu-xenial-amd64:latest 5 | platform: 6 | os: linux 7 | architecture: amd64 8 | - 9 | image: ibmcom/swift-ubuntu-xenial-s390x:latest 10 | platform: 11 | os: linux 12 | architecture: s390x 13 | -------------------------------------------------------------------------------- /swift-development/swift-ubuntu-xenial-multiarch/s390x/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2017 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | FROM FROM s390x/ubuntu:16.04 18 | MAINTAINER IBM Swift Engineering at IBM Cloud 19 | 20 | USER root 21 | 22 | # Set environment variables for image 23 | ENV WORK_DIR / 24 | 25 | # Set WORKDIR 26 | WORKDIR ${WORK_DIR} 27 | 28 | # Linux OS utils and libraries and set clang 3.8 as default 29 | RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y \ 30 | build-essential \ 31 | clang-3.8 \ 32 | git \ 33 | libpython2.7 \ 34 | libicu-dev \ 35 | wget \ 36 | libcurl4-openssl-dev \ 37 | openssl \ 38 | libssl-dev \ 39 | libxml2-dev \ 40 | vim \ 41 | && apt-get clean \ 42 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ 43 | && update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.8 100 \ 44 | && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.8 100 \ 45 | && echo "set -o vi" >> /root/.bashrc 46 | 47 | # Install Swift compiler 48 | # This step will only work if you have the necessary binaries in the same folder as this Dockerfile 49 | COPY swift-4.0.3-s390x-ub1604-20180205-R.tgz swift-4.0.3-s390x-ub1604-20180205-R.tgz 50 | COPY binutils-2.27.tar.gz binutils-2.27.tar.gz 51 | 52 | RUN tar -xzvf swift-4.0.3-s390x-ub1604-20180205-R.tgz \ 53 | && tar -xvzf binutils-2.27.tar.gz \ 54 | && rm swift-4.0.3-s390x-ub1604-20180205-R.tgz \ 55 | && rm binutils-2.27.tar.gz \ 56 | && swift --version 57 | 58 | # Add gold linker to PATH 59 | ENV PATH "/opt/binutils-2.27/bin:$PATH" 60 | 61 | # Add utilities 62 | #COPY .vim /root/.vim 63 | #COPY .vimrc /root/.vimrc 64 | 65 | CMD /bin/bash 66 | -------------------------------------------------------------------------------- /swift-runtime/swift-ubuntu-trusty/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2017, 2019 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | FROM ibmcom/ubuntu:14.04 18 | MAINTAINER IBM Swift Engineering at IBM Cloud 19 | LABEL Description="Linux Ubuntu 14.04 image for execution of Swift applications." 20 | 21 | USER root 22 | 23 | # Set environment variables for image 24 | ARG VERSION=${VERSION} 25 | ENV SWIFT_SNAPSHOT swift-${VERSION}-RELEASE 26 | ENV SWIFT_SNAPSHOT_LOWERCASE swift-${VERSION}-release 27 | ENV UBUNTU_VERSION ubuntu14.04 28 | ENV UBUNTU_VERSION_NO_DOTS ubuntu1404 29 | ENV WORK_DIR / 30 | 31 | # Set WORKDIR 32 | WORKDIR ${WORK_DIR} 33 | 34 | # Linux OS utils & Swift libraries 35 | RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y \ 36 | libicu-dev \ 37 | libcurl4-openssl-dev \ 38 | wget \ 39 | && apt-get clean \ 40 | && wget --progress=dot:giga https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 41 | https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 42 | && gpg --keyserver hkp://pool.sks-keyservers.net \ 43 | --recv-keys \ 44 | '7463 A81A 4B2E EA1B 551F FBCF D441 C977 412B 37AD' \ 45 | '1BE1 E29A 084C B305 F397 D62A 9F59 7F4D 21A5 6D5F' \ 46 | 'A3BA FD35 56A5 9079 C068 94BD 63BC 1CFE 91D3 06C6' \ 47 | '5E4D F843 FB06 5D7F 7E24 FBA2 EF54 30F0 71E1 B235' \ 48 | '8513 444E 2DA3 6B7C 1659 AF4D 7638 F1FB 2B2B 08C4' \ 49 | 'A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561' \ 50 | && gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys \ 51 | && gpg --verify $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 52 | && tar xzvf $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz $SWIFT_SNAPSHOT-$UBUNTU_VERSION/usr/lib/swift/linux --strip-components=1 \ 53 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 54 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 55 | && find /usr/lib/swift/linux -type f ! -name '*.so*' -delete \ 56 | && rm -rf /usr/lib/swift/linux/*/ \ 57 | && chmod -R go+r /usr/lib/swift \ 58 | && apt-get remove -y gcc cpp sgml-base icu-devtools gcc-4.8 cpp-4.8 libc6-dev binutils manpages-dev manpages wget pkg-config perl \ 59 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 60 | 61 | CMD /bin/bash 62 | -------------------------------------------------------------------------------- /swift-runtime/swift-ubuntu-xenial-multiarch/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitura/swift-ubuntu-docker/0870d11e37668daad7e1ce25ab9cc6fd6c82594f/swift-runtime/swift-ubuntu-xenial-multiarch/.DS_Store -------------------------------------------------------------------------------- /swift-runtime/swift-ubuntu-xenial-multiarch/amd64/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2016, 2019 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | # Dockerfile to build a Docker image with the Swift tools and binaries and 18 | # its dependencies. 19 | 20 | FROM ibmcom/ubuntu:16.04 21 | MAINTAINER IBM Swift Engineering at IBM Cloud 22 | LABEL Description="Linux Ubuntu 16.04 image for execution of Swift applications." 23 | 24 | USER root 25 | 26 | # Set environment variables for image 27 | ARG VERSION=${VERSION} 28 | ENV SWIFT_SNAPSHOT swift-${VERSION}-RELEASE 29 | ENV SWIFT_SNAPSHOT_LOWERCASE swift-${VERSION}-release 30 | ENV UBUNTU_VERSION ubuntu16.04 31 | ENV UBUNTU_VERSION_NO_DOTS ubuntu1604 32 | ENV WORK_DIR / 33 | 34 | # Set WORKDIR 35 | WORKDIR ${WORK_DIR} 36 | 37 | # Linux OS utils & Swift libraries 38 | RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y \ 39 | libicu-dev \ 40 | libcurl4-openssl-dev \ 41 | wget \ 42 | && apt-get clean \ 43 | && wget --progress=dot:giga https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 44 | https://swift.org/builds/$SWIFT_SNAPSHOT_LOWERCASE/$UBUNTU_VERSION_NO_DOTS/$SWIFT_SNAPSHOT/$SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 45 | && gpg --keyserver hkp://pool.sks-keyservers.net \ 46 | --recv-keys \ 47 | '7463 A81A 4B2E EA1B 551F FBCF D441 C977 412B 37AD' \ 48 | '1BE1 E29A 084C B305 F397 D62A 9F59 7F4D 21A5 6D5F' \ 49 | 'A3BA FD35 56A5 9079 C068 94BD 63BC 1CFE 91D3 06C6' \ 50 | '5E4D F843 FB06 5D7F 7E24 FBA2 EF54 30F0 71E1 B235' \ 51 | '8513 444E 2DA3 6B7C 1659 AF4D 7638 F1FB 2B2B 08C4' \ 52 | 'A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561' \ 53 | && gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys \ 54 | && gpg --verify $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 55 | && tar xzvf $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz $SWIFT_SNAPSHOT-$UBUNTU_VERSION/usr/lib/swift/linux --strip-components=1 \ 56 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz \ 57 | && rm $SWIFT_SNAPSHOT-$UBUNTU_VERSION.tar.gz.sig \ 58 | && find /usr/lib/swift/linux -type f ! -name '*.so*' -delete \ 59 | && rm -rf /usr/lib/swift/linux/*/ \ 60 | && chmod -R go+r /usr/lib/swift \ 61 | && apt-get remove -y gcc cpp sgml-base icu-devtools gcc-4.8 cpp-4.8 libc6-dev binutils manpages-dev manpages wget pkg-config perl \ 62 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 63 | 64 | CMD /bin/bash 65 | -------------------------------------------------------------------------------- /swift-runtime/swift-ubuntu-xenial-multiarch/manifest.yml: -------------------------------------------------------------------------------- 1 | image: ibmcom/swift-ubuntu-xenial-runtime:latest 2 | manifests: 3 | - 4 | image: ibmcom/swift-ubuntu-xenial-runtime-amd64:latest 5 | platform: 6 | os: linux 7 | architecture: amd64 8 | - 9 | image: ibmcom/swift-ubuntu-xenial-runtime-s390x:latest 10 | platform: 11 | os: linux 12 | architecture: s390x 13 | -------------------------------------------------------------------------------- /swift-runtime/swift-ubuntu-xenial-multiarch/s390x/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2017 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | FROM s390x/ubuntu:16.04 18 | MAINTAINER IBM Swift Engineering at IBM Cloud 19 | 20 | USER root 21 | 22 | # Set environment variables for image 23 | ENV WORK_DIR / 24 | 25 | # Set WORKDIR 26 | WORKDIR ${WORK_DIR} 27 | 28 | # Linux OS utils and libraries and set clang 3.8 as default 29 | RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y \ 30 | libicu-dev \ 31 | libcurl4-openssl-dev \ 32 | libedit-dev \ 33 | libedit2 \ 34 | && apt-get clean \ 35 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ 36 | && echo "set -o vi" >> /root/.bashrc 37 | 38 | # Install Swift compiler 39 | # This step will only work if you have the necessary binaries in the same folder as this Dockerfile 40 | COPY swift-4.0.3-s390x-ub1604-20180205-R.tgz swift-4.0.3-s390x-ub1604-20180205-R.tgz 41 | COPY binutils-2.27.tar.gz binutils-2.27.tar.gz 42 | 43 | RUN tar -xzvf swift-4.0.3-s390x-ub1604-20180205-R.tgz \ 44 | && tar -xvzf binutils-2.27.tar.gz \ 45 | && rm swift-4.0.3-s390x-ub1604-20180205-R.tgz \ 46 | && rm binutils-2.27.tar.gz \ 47 | && swift --version 48 | 49 | # Add gold linker to PATH 50 | ENV PATH "/opt/binutils-2.27/bin:$PATH" 51 | 52 | CMD /bin/bash 53 | -------------------------------------------------------------------------------- /ubuntu-14.04/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2017 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | FROM ubuntu:14.04 18 | MAINTAINER IBM Swift Engineering at IBM Cloud 19 | LABEL Description="Hardened Ubuntu 14.04 image." 20 | 21 | # Security & hardening for Ubuntu 14.04 22 | # For details on resolving reported vulnerabilities, see: 23 | # - https://console.ng.bluemix.net/docs/containers/container_security_image.html#container_security_image 24 | # See following URLs for further details: 25 | # - http://tldp.org/LDP/lfs/LFS-BOOK-6.1.1-HTML/chapter06/pwdgroup.html 26 | # - http://www.deer-run.com/~hal/sysadmin/pam_cracklib.html 27 | # - http://www.cyberciti.biz/faq/linux-kernel-etcsysctl-conf-security-hardening/ 28 | RUN sed -i 's/^.*PASS_MAX_DAYS.*$/PASS_MAX_DAYS\t90/' /etc/login.defs && \ 29 | sed -i 's/^.*PASS_MIN_DAYS.*$/PASS_MIN_DAYS\t1/' /etc/login.defs && \ 30 | sed -i 's/^.*PASS_MIN_LEN.*$/PASS_MIN_LEN\t>=\ 8/' /etc/login.defs && \ 31 | sed -i 's/sha512/sha512 minlen=8/' /etc/pam.d/common-password && \ 32 | touch /var/run/utmp /var/log/{btmp,lastlog,wtmp} && \ 33 | chgrp -v utmp /var/run/utmp /var/log/lastlog && \ 34 | chmod -v 664 /var/run/utmp /var/log/lastlog && \ 35 | touch /etc/security/opasswd && \ 36 | chown root:root /etc/security/opasswd && \ 37 | chmod 600 /etc/security/opasswd && \ 38 | grep -q '^net.ipv4.tcp_syncookies' /etc/sysctl.conf && sed -i 's/^net.ipv4.tcp_syncookies.*/net.ipv4.tcp_syncookies = 1/' /etc/sysctl.conf || echo 'net.ipv4.tcp_syncookies = 1' >> /etc/sysctl.conf && \ 39 | grep -q '^net.ipv4.ip_forward' /etc/sysctl.conf && sed -i 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward = 0/' /etc/sysctl.conf || echo 'net.ipv4.ip_forward = 0' >> /etc/sysctl.conf && \ 40 | grep -q '^net.ipv4.icmp_echo_ignore_broadcasts' /etc/sysctl.conf && sed -i 's/^net.ipv4.icmp_echo_ignore_broadcasts.*/net.ipv4.icmp_echo_ignore_broadcasts = 1/' /etc/sysctl.conf || echo 'net.ipv4.icmp_echo_ignore_broadcasts = 1' >> /etc/sysctl.conf 41 | -------------------------------------------------------------------------------- /ubuntu-16.04/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Copyright IBM Corporation 2017 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ## 16 | 17 | FROM ubuntu:16.04 18 | MAINTAINER IBM Swift Engineering at IBM Cloud 19 | LABEL Description="Hardened Ubuntu 16.04 image." 20 | 21 | # Security & hardening for Ubuntu 16.04 22 | # For details on resolving reported vulnerabilities, see: 23 | # - https://console.ng.bluemix.net/docs/containers/container_security_image.html#container_security_image 24 | # See following URLs for further details: 25 | # - http://tldp.org/LDP/lfs/LFS-BOOK-6.1.1-HTML/chapter06/pwdgroup.html 26 | # - http://www.deer-run.com/~hal/sysadmin/pam_cracklib.html 27 | # - http://www.cyberciti.biz/faq/linux-kernel-etcsysctl-conf-security-hardening/ 28 | RUN sed -i 's/^.*PASS_MAX_DAYS.*$/PASS_MAX_DAYS\t90/' /etc/login.defs && \ 29 | sed -i 's/^.*PASS_MIN_DAYS.*$/PASS_MIN_DAYS\t1/' /etc/login.defs && \ 30 | sed -i 's/^.*PASS_MIN_LEN.*$/PASS_MIN_LEN\t>=\ 8/' /etc/login.defs && \ 31 | sed -i 's/sha512/sha512 minlen=8/' /etc/pam.d/common-password && \ 32 | touch /var/run/utmp /var/log/{btmp,lastlog,wtmp} && \ 33 | chgrp -v utmp /var/run/utmp /var/log/lastlog && \ 34 | chmod -v 664 /var/run/utmp /var/log/lastlog && \ 35 | touch /etc/security/opasswd && \ 36 | chown root:root /etc/security/opasswd && \ 37 | chmod 600 /etc/security/opasswd && \ 38 | grep -q '^net.ipv4.tcp_syncookies' /etc/sysctl.conf && sed -i 's/^net.ipv4.tcp_syncookies.*/net.ipv4.tcp_syncookies = 1/' /etc/sysctl.conf || echo 'net.ipv4.tcp_syncookies = 1' >> /etc/sysctl.conf && \ 39 | grep -q '^net.ipv4.ip_forward' /etc/sysctl.conf && sed -i 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward = 0/' /etc/sysctl.conf || echo 'net.ipv4.ip_forward = 0' >> /etc/sysctl.conf && \ 40 | grep -q '^net.ipv4.icmp_echo_ignore_broadcasts' /etc/sysctl.conf && sed -i 's/^net.ipv4.icmp_echo_ignore_broadcasts.*/net.ipv4.icmp_echo_ignore_broadcasts = 1/' /etc/sysctl.conf || echo 'net.ipv4.icmp_echo_ignore_broadcasts = 1' >> /etc/sysctl.conf 41 | -------------------------------------------------------------------------------- /utils/common-utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | # Copyright IBM Corporation 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ## 17 | 18 | #---------------------------------------------------------- 19 | function run { 20 | echo "Running program..." 21 | $BUILD_DIR/$BUILD_CONFIGURATION/$PROGRAM_NAME & 22 | } 23 | 24 | #---------------------------------------------------------- 25 | function init { 26 | echo "Current folder: `pwd`" 27 | echo "Command: $ACTION" 28 | if ! [[ -z $BUILD_CONFIGURATION ]] ; then 29 | echo "Build configuration: $BUILD_CONFIGURATION" 30 | fi 31 | BUILD_DIR=$PWD/.build-ubuntu 32 | mkdir -p $BUILD_DIR 33 | echo "Build folder: $BUILD_DIR" 34 | # Skipping invocation of installSystemLibraries() method for now... 35 | # installSystemLibraries 36 | } 37 | 38 | #---------------------------------------------------------- 39 | function installSystemLibraries { 40 | 41 | # Fetch all of the dependencies 42 | if type "swift" &> /dev/null; then 43 | echo "Fetching Swift packages..." 44 | swift package fetch 45 | fi 46 | 47 | echo "Updating system configuration..." 48 | 49 | # Update the Package cache 50 | sudo apt-get update &> /dev/null 51 | 52 | echo "Installing system dependencies (if any)..." 53 | 54 | # Install all the APT dependencies 55 | egrep -R "Apt *\(" Packages/*/Package.swift \ 56 | | sed -e 's/^.*\.Apt *( *" *//' -e 's/".*$//' \ 57 | | xargs -n 1 sudo apt-get install -y &> /dev/null 58 | } 59 | -------------------------------------------------------------------------------- /utils/run-utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | # Copyright IBM Corporation 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ## 17 | 18 | # Runs your Swift app in a Docker container 19 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 20 | source $dir/common-utils.sh 21 | 22 | #---------------------------------------------------------- 23 | function help { 24 | SCRIPT=`basename "$0"` 25 | cat <<-!!EOF 26 | Usage: $SCRIPT [ run ] 27 | 28 | Where: 29 | run Runs your project 30 | !!EOF 31 | } 32 | 33 | #---------------------------------------------------------- 34 | # MAIN 35 | # --------------------------------------------------------- 36 | # Runtime arguments 37 | ACTION="$1" 38 | PROGRAM_NAME="$2" 39 | BUILD_CONFIGURATION="release" 40 | 41 | # Validate input arguments 42 | [[ ( -z $ACTION ) || ( -z $PROGRAM_NAME ) ]] && help && exit 0 43 | 44 | # Invoke corresponding handler 45 | # Invoke corresponding handler 46 | case $ACTION in 47 | "run") init && run;; 48 | *) help;; 49 | esac 50 | -------------------------------------------------------------------------------- /utils/tools-utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | # Copyright IBM Corporation 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ## 17 | 18 | # Compiles, debugs, or runs your Swift app in a Docker container 19 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 20 | source $dir/common-utils.sh 21 | 22 | #---------------------------------------------------------- 23 | function help { 24 | SCRIPT=`basename "$0"` 25 | cat <<-!!EOF 26 | Usage: $SCRIPT [ build | run | debug | test ] 27 | 28 | Where: 29 | build Compiles your project 30 | run Runs your project 31 | debug Starts debug server and your program 32 | test Runs test cases 33 | !!EOF 34 | } 35 | 36 | #---------------------------------------------------------- 37 | function debugServer { 38 | # Updating ptrace_scope, requires running container in privilege mode 39 | # We should look into creating an apparmor profile at some point... 40 | # https://docs.docker.com/engine/security/apparmor/ 41 | echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope 42 | MIN_SEVER_PORT=$(( DEBUG_PORT + 1 )) 43 | MAX_SEVER_PORT=$(( MIN_SEVER_PORT + 1 )) 44 | lldb-server platform --port-offset=$DEBUG_PORT --listen *:$DEBUG_PORT --min-gdbserver-port $MIN_SEVER_PORT --max-gdbserver-port $MAX_SEVER_PORT --server & 45 | echo "Started debug server on port $DEBUG_PORT (min-gdbserver-port: $MIN_SEVER_PORT, max-gdbserver-port: $MAX_SEVER_PORT)." 46 | } 47 | 48 | #---------------------------------------------------------- 49 | function buildProject { 50 | echo "Compiling the project..." 51 | echo "Build configuration: $BUILD_CONFIGURATION" 52 | if [ -e .swift-build-linux ]; then 53 | echo Custom build command: `cat .swift-build-linux` 54 | BUILD_CMD=$(cat .swift-build-linux) 55 | eval "$BUILD_CMD --configuration $BUILD_CONFIGURATION --build-path $BUILD_DIR" 56 | else 57 | swift build --configuration $BUILD_CONFIGURATION --build-path $BUILD_DIR 58 | fi 59 | } 60 | 61 | #---------------------------------------------------------- 62 | function runTests { 63 | echo "Running tests..." 64 | if [ -e .swift-test-linux ]; then 65 | echo Custom test command: `cat .swift-test-linux` 66 | BUILD_CMD=$(cat .swift-test-linux) 67 | eval "$BUILD_CMD --build-path $BUILD_DIR" 68 | else 69 | swift test --build-path $BUILD_DIR 70 | fi 71 | } 72 | 73 | #---------------------------------------------------------- 74 | # MAIN 75 | # --------------------------------------------------------- 76 | # Runtime arguments 77 | ACTION="$1" 78 | BUILD_CONFIGURATION="$2" 79 | PROGRAM_NAME="$3" 80 | DEBUG_PORT="$4" 81 | 82 | # Validate input arguments 83 | if [[ -z $ACTION ]] ; then 84 | ACTION="build" 85 | BUILD_CONFIGURATION="debug" 86 | fi 87 | 88 | if [ "$ACTION" = "debug" ] ; then 89 | BUILD_CONFIGURATION="debug" 90 | PROGRAM_NAME="$2" 91 | DEBUG_PORT="$3" 92 | fi 93 | 94 | if [ "$ACTION" = "run" ] ; then 95 | BUILD_CONFIGURATION="debug" 96 | fi 97 | 98 | [ "$ACTION" = "build" ] && [[ -z $BUILD_CONFIGURATION ]] && BUILD_CONFIGURATION="debug" 99 | [ "$ACTION" = "run" ] && [[ -z $PROGRAM_NAME ]] && help && exit 0 100 | [ "$ACTION" = "debug" ] && [[ ( -z $PROGRAM_NAME ) || ( -z $DEBUG_PORT ) ]] && help && exit 0 101 | 102 | # Invoke corresponding handler 103 | case $ACTION in 104 | "run") init && run;; 105 | "build") init && buildProject;; 106 | "debug") init && debugServer && buildProject && run;; 107 | "test") init && runTests;; 108 | *) help;; 109 | esac 110 | --------------------------------------------------------------------------------