diff --git a/README.md b/README.md
index 431cac4..5abc7ef 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ The following steps will be taken care of:
1. The latest October CMS gets downloaded from github and gets installed
2. All composer dependencies are installed
3. Relevant config entries are moved to a `.env` file for easy customization
-4. Sensible configuration defaults for your `prod` environment get preset
+4. Sensible configuration defaults for your `prod` environment get pre-set
5. Your database gets migrated
6. All demo data gets removed
7. Your selected theme gets downloaded and installed
@@ -27,6 +27,7 @@ The following steps will be taken care of:
## Tested on
* Ubuntu 15.10
+* Ubuntu 16.04
Should work on OS X. Will probably not work on Windows.
@@ -39,7 +40,7 @@ You can now run `october` from your command line.
```bash
$ october
-October CMS Bootstrapper version 0.1.0
+October CMS Bootstrapper version 0.2.0
```
## Usage
@@ -75,7 +76,11 @@ database:
database: bootstrapper
host: 192.168.10.10
-deployment: gitlab
+git:
+ deployment: false
+
+ # Exclude everything except themes and custom plugins in git
+ bareRepo: true
plugins:
- Rainlab.Pages
@@ -87,9 +92,11 @@ plugins:
# - Vendor.Private (user@remote.git)
mail:
+ host: smtp.mailgun.org
name: User Name
address: email@example.com
driver: log
+
```
#### Theme and Plugin syntax
@@ -103,11 +110,28 @@ If no repo is defined the plugins are loaded from the October Marketplace.
When you are done editing your configuration file, simply run `october install` to install October.
+#### Install additional plugins
+
+If at any point in time you need to install additional plugins, simply add them to your `october.yaml` and rerun `october install`. Missing plugins will be installed.
+
### Change config
To change your installation's configuration, simply edit the `.env` file in your project root.
When deploying to production, make sure to edit your `.env.production` template file and rename it to `.env`.
+### Bare repos
+
+If you don't want to have the complete October source code in your repository set the `bareRepo`
+ option to `true`.
+
+ This will set up a `.gitignore` file that excludes everything except your `theme` directory and all the **manually installed** plugins in your `plugins` directory.
+
+ > If you want to deploy a bare repo please read the section `SSH deployments with bare repos` below.
+
+#### Get up and running after `git clone`
+
+After cloning a bare repo for the first time, simply run `october install`. October CMS and all missing plugins will get installed locally on your machine.
+
### SSH deployments
Set the `deployment` option to `false` if you don't want to setup deployments.
@@ -116,6 +140,18 @@ Currently `oc-bootstrapper` supports a simple setup to deploy a project on push
Support for other CI systems is added on request.
+ #### SSH deployments with bare repos
+
+ If you use SSH deployments with a bare repo, make sure to require `oc-bootstrapper` locally in your procect:
+
+ composer require offline/oc-bootstrapper
+
+Then, in your deployment script simply run `./vendor/bin/october install` to install the October source code and all of your plugins during deployment. If the October source code is already available it won't be downloaded again.
+
+If you use the provided GitLab deployment via Envoy make sure to simply uncomment [this line](https://github.com/OFFLINE-GmbH/oc-bootstrapper/blob/fd45b66580f4b1af24880a3b331635a7654cf4ed/templates/Envoy.blade.php#L17).
+
+ It is important that you list every installed plugin in your `october.yaml` file. Otherwise the plugins won't be available after deployment.
+
#### GitLab CI with Envoy
If you use the gitlab deployment option the `.gitlab-ci.yml` and `Envoy.blade.php` files are created for you.
diff --git a/composer.json b/composer.json
index c6c6de4..a8d0e2a 100644
--- a/composer.json
+++ b/composer.json
@@ -16,14 +16,14 @@
"require": {
"guzzlehttp/guzzle": "~6.0",
"cypresslab/gitelephant": "~1.1",
- "symfony/console": "~3.0",
- "symfony/process": "~3.0",
- "symfony/yaml": "~3.0"
+ "symfony/console": "~2.7",
+ "symfony/process": "~2.7",
+ "symfony/yaml": "~2.1|~3.0"
},
"bin": [
"october"
],
"require-dev": {
- "symfony/var-dumper": "~3.0"
+ "symfony/var-dumper": "~2.7"
}
}
diff --git a/composer.lock b/composer.lock
index 5cd2027..1c85243 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "394ba984cf6ae59fb48377aa9271db29",
- "content-hash": "e5bbb712f67aafd81ee7b6573700e448",
+ "hash": "117449dd369d28c9be3d9ac3a3de939b",
+ "content-hash": "9dbbce96a1cedc7b889b0c3612ee3c84",
"packages": [
{
"name": "cypresslab/gitelephant",
@@ -55,96 +55,29 @@
],
"time": "2016-01-26 22:31:30"
},
- {
- "name": "doctrine/inflector",
- "version": "v1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/inflector.git",
- "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
- "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "require-dev": {
- "phpunit/phpunit": "4.*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\Inflector\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
- }
- ],
- "description": "Common String Manipulations with regard to casing and singular/plural rules.",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "inflection",
- "pluralize",
- "singularize",
- "string"
- ],
- "time": "2015-11-06 14:35:42"
- },
{
"name": "guzzlehttp/guzzle",
- "version": "6.2.0",
+ "version": "6.2.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "d094e337976dff9d8e2424e8485872194e768662"
+ "reference": "3f808fba627f2c5b69e2501217bf31af349c1427"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d094e337976dff9d8e2424e8485872194e768662",
- "reference": "d094e337976dff9d8e2424e8485872194e768662",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427",
+ "reference": "3f808fba627f2c5b69e2501217bf31af349c1427",
"shasum": ""
},
"require": {
- "guzzlehttp/promises": "~1.0",
- "guzzlehttp/psr7": "~1.1",
- "php": ">=5.5.0"
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.3.1",
+ "php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
- "phpunit/phpunit": "~4.0",
- "psr/log": "~1.0"
+ "phpunit/phpunit": "^4.0",
+ "psr/log": "^1.0"
},
"type": "library",
"extra": {
@@ -182,20 +115,20 @@
"rest",
"web service"
],
- "time": "2016-03-21 20:02:09"
+ "time": "2016-07-15 17:22:37"
},
{
"name": "guzzlehttp/promises",
- "version": "1.1.0",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
- "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8"
+ "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/bb9024c526b22f3fe6ae55a561fd70653d470aa8",
- "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579",
+ "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579",
"shasum": ""
},
"require": {
@@ -233,20 +166,20 @@
"keywords": [
"promise"
],
- "time": "2016-03-08 01:15:46"
+ "time": "2016-05-18 16:56:05"
},
{
"name": "guzzlehttp/psr7",
- "version": "1.2.3",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b"
+ "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/2e89629ff057ebb49492ba08e6995d3a6a80021b",
- "reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b",
+ "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b",
"shasum": ""
},
"require": {
@@ -262,7 +195,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "1.4-dev"
}
},
"autoload": {
@@ -291,297 +224,7 @@
"stream",
"uri"
],
- "time": "2016-02-18 21:54:00"
- },
- {
- "name": "illuminate/config",
- "version": "v5.2.27",
- "source": {
- "type": "git",
- "url": "https://github.com/illuminate/config.git",
- "reference": "29d25fa086eac092a54859b3cbf7580299fc101e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/illuminate/config/zipball/29d25fa086eac092a54859b3cbf7580299fc101e",
- "reference": "29d25fa086eac092a54859b3cbf7580299fc101e",
- "shasum": ""
- },
- "require": {
- "illuminate/contracts": "5.2.*",
- "illuminate/filesystem": "5.2.*",
- "illuminate/support": "5.2.*",
- "php": ">=5.5.9"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Illuminate\\Config\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
- }
- ],
- "description": "The Illuminate Config package.",
- "homepage": "http://laravel.com",
- "time": "2015-06-22 20:36:58"
- },
- {
- "name": "illuminate/contracts",
- "version": "v5.2.27",
- "source": {
- "type": "git",
- "url": "https://github.com/illuminate/contracts.git",
- "reference": "411b851962c211078ade7664a6976e77a78cd2a5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/illuminate/contracts/zipball/411b851962c211078ade7664a6976e77a78cd2a5",
- "reference": "411b851962c211078ade7664a6976e77a78cd2a5",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Illuminate\\Contracts\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
- }
- ],
- "description": "The Illuminate Contracts package.",
- "homepage": "http://laravel.com",
- "time": "2016-03-07 20:37:17"
- },
- {
- "name": "illuminate/filesystem",
- "version": "v5.2.27",
- "source": {
- "type": "git",
- "url": "https://github.com/illuminate/filesystem.git",
- "reference": "e197f38660beab95743d9d5565d0f11d956288ea"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/illuminate/filesystem/zipball/e197f38660beab95743d9d5565d0f11d956288ea",
- "reference": "e197f38660beab95743d9d5565d0f11d956288ea",
- "shasum": ""
- },
- "require": {
- "illuminate/contracts": "5.2.*",
- "illuminate/support": "5.2.*",
- "php": ">=5.5.9",
- "symfony/finder": "2.8.*|3.0.*"
- },
- "suggest": {
- "league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).",
- "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
- "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0)."
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Illuminate\\Filesystem\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
- }
- ],
- "description": "The Illuminate Filesystem package.",
- "homepage": "http://laravel.com",
- "time": "2016-03-21 14:55:26"
- },
- {
- "name": "illuminate/support",
- "version": "v5.2.27",
- "source": {
- "type": "git",
- "url": "https://github.com/illuminate/support.git",
- "reference": "b8d2131e38fc26e42f742c7af68de1ca726a545c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/illuminate/support/zipball/b8d2131e38fc26e42f742c7af68de1ca726a545c",
- "reference": "b8d2131e38fc26e42f742c7af68de1ca726a545c",
- "shasum": ""
- },
- "require": {
- "doctrine/inflector": "~1.0",
- "ext-mbstring": "*",
- "illuminate/contracts": "5.2.*",
- "paragonie/random_compat": "~1.4",
- "php": ">=5.5.9"
- },
- "suggest": {
- "illuminate/filesystem": "Required to use the composer class (5.2.*).",
- "jeremeamia/superclosure": "Required to be able to serialize closures (~2.2).",
- "symfony/polyfill-php56": "Required to use the hash_equals function on PHP 5.5 (~1.0).",
- "symfony/process": "Required to use the composer class (2.8.*|3.0.*).",
- "symfony/var-dumper": "Improves the dd function (2.8.*|3.0.*)."
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Illuminate\\Support\\": ""
- },
- "files": [
- "helpers.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
- }
- ],
- "description": "The Illuminate Support package.",
- "homepage": "http://laravel.com",
- "time": "2016-03-29 11:17:27"
- },
- {
- "name": "offline/laravel-config-writer",
- "version": "v1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/OFFLINE-GmbH/laravel-config-writer.git",
- "reference": "dcba6accda9f3d0057aeb5c352d31ddab11f9d77"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/OFFLINE-GmbH/laravel-config-writer/zipball/dcba6accda9f3d0057aeb5c352d31ddab11f9d77",
- "reference": "dcba6accda9f3d0057aeb5c352d31ddab11f9d77",
- "shasum": ""
- },
- "require": {
- "illuminate/config": "~5.0.",
- "php": ">=5.4.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "October\\Rain\\Config\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Alexey Bobkov",
- "email": "aleksey.bobkov@gmail.com"
- },
- {
- "name": "Samuel Georges",
- "email": "daftspunky@gmail.com"
- }
- ],
- "description": "Configuration extension",
- "homepage": "http://octobercms.com",
- "keywords": [
- "config",
- "laravel",
- "october",
- "october cms",
- "write"
- ],
- "time": "2016-03-30 05:52:31"
- },
- {
- "name": "paragonie/random_compat",
- "version": "v1.4.1",
- "source": {
- "type": "git",
- "url": "https://github.com/paragonie/random_compat.git",
- "reference": "c7e26a21ba357863de030f0b9e701c7d04593774"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774",
- "reference": "c7e26a21ba357863de030f0b9e701c7d04593774",
- "shasum": ""
- },
- "require": {
- "php": ">=5.2.0"
- },
- "require-dev": {
- "phpunit/phpunit": "4.*|5.*"
- },
- "suggest": {
- "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
- },
- "type": "library",
- "autoload": {
- "files": [
- "lib/random.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Paragon Initiative Enterprises",
- "email": "security@paragonie.com",
- "homepage": "https://paragonie.com"
- }
- ],
- "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
- "keywords": [
- "csprng",
- "pseudorandom",
- "random"
- ],
- "time": "2016-03-18 20:34:03"
+ "time": "2016-06-24 23:00:38"
},
{
"name": "phpcollection/phpcollection",
@@ -734,26 +377,26 @@
},
{
"name": "symfony/console",
- "version": "v3.0.3",
+ "version": "v2.8.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04"
+ "reference": "c392a6ec72f2122748032c2ad6870420561ffcfa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/2ed5e2706ce92313d120b8fe50d1063bcfd12e04",
- "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04",
+ "url": "https://api.github.com/repos/symfony/console/zipball/c392a6ec72f2122748032c2ad6870420561ffcfa",
+ "reference": "c392a6ec72f2122748032c2ad6870420561ffcfa",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
+ "php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"psr/log": "~1.0",
- "symfony/event-dispatcher": "~2.8|~3.0",
- "symfony/process": "~2.8|~3.0"
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
+ "symfony/process": "~2.1|~3.0.0"
},
"suggest": {
"psr/log": "For using the console logger",
@@ -763,7 +406,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
@@ -790,20 +433,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2016-02-28 16:24:34"
+ "time": "2016-06-29 07:02:14"
},
{
"name": "symfony/filesystem",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451"
+ "reference": "322da5f0910d8aa0b25fa65ffccaba68dbddb890"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/23ae8f9648d0a7fe94a47c8e20e5bf37c489a451",
- "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/322da5f0910d8aa0b25fa65ffccaba68dbddb890",
+ "reference": "322da5f0910d8aa0b25fa65ffccaba68dbddb890",
"shasum": ""
},
"require": {
@@ -812,7 +455,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -839,20 +482,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2016-02-23 15:16:06"
+ "time": "2016-06-29 05:41:56"
},
{
"name": "symfony/finder",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723"
+ "reference": "8201978de88a9fa0923e18601bb17f1df9c721e7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723",
- "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/8201978de88a9fa0923e18601bb17f1df9c721e7",
+ "reference": "8201978de88a9fa0923e18601bb17f1df9c721e7",
"shasum": ""
},
"require": {
@@ -861,7 +504,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -888,20 +531,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2016-01-27 05:14:46"
+ "time": "2016-06-29 05:41:56"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.1.1",
+ "version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "1289d16209491b584839022f29257ad859b8532d"
+ "reference": "dff51f72b0706335131b00a7f49606168c582594"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
- "reference": "1289d16209491b584839022f29257ad859b8532d",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
+ "reference": "dff51f72b0706335131b00a7f49606168c582594",
"shasum": ""
},
"require": {
@@ -913,7 +556,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "1.2-dev"
}
},
"autoload": {
@@ -947,29 +590,29 @@
"portable",
"shim"
],
- "time": "2016-01-20 09:13:37"
+ "time": "2016-05-18 14:26:46"
},
{
"name": "symfony/process",
- "version": "v3.0.3",
+ "version": "v2.8.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "dfecef47506179db2501430e732adbf3793099c8"
+ "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/dfecef47506179db2501430e732adbf3793099c8",
- "reference": "dfecef47506179db2501430e732adbf3793099c8",
+ "url": "https://api.github.com/repos/symfony/process/zipball/89f33c16796415ccfd8bb3cf8d520cbb79899bfe",
+ "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
@@ -996,29 +639,29 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2016-02-02 13:44:19"
+ "time": "2016-06-29 05:29:29"
},
{
"name": "symfony/yaml",
- "version": "v3.0.3",
+ "version": "v2.8.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c"
+ "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/b5ba64cd67ecd6887f63868fa781ca094bd1377c",
- "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/dba4bb5846798cd12f32e2d8f3f35d77045773c8",
+ "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
@@ -1045,22 +688,22 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2016-02-23 15:16:06"
+ "time": "2016-06-29 05:29:29"
}
],
"packages-dev": [
{
"name": "symfony/var-dumper",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "9a6a883c48acb215d4825ce9de61dccf93d62074"
+ "reference": "39492b8b8fe514163e677bf154fd80f6cc995759"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9a6a883c48acb215d4825ce9de61dccf93d62074",
- "reference": "9a6a883c48acb215d4825ce9de61dccf93d62074",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/39492b8b8fe514163e677bf154fd80f6cc995759",
+ "reference": "39492b8b8fe514163e677bf154fd80f6cc995759",
"shasum": ""
},
"require": {
@@ -1076,7 +719,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -1110,7 +753,7 @@
"debug",
"dump"
],
- "time": "2016-02-13 09:23:44"
+ "time": "2016-06-29 05:41:56"
}
],
"aliases": [],
diff --git a/october b/october
index 5482c79..b06fa59 100755
--- a/october
+++ b/october
@@ -8,7 +8,7 @@ if (file_exists(__DIR__.'/../../autoload.php')) {
require __DIR__.'/vendor/autoload.php';
}
-$app = new Symfony\Component\Console\Application('October CMS Bootstrapper', '0.1.0');
+$app = new Symfony\Component\Console\Application('October CMS Bootstrapper', '0.2.0');
$app->add(new \OFFLINE\Bootstrapper\October\Console\InitCommand);
$app->add(new \OFFLINE\Bootstrapper\October\Console\InstallCommand);
$app->run();
diff --git a/src/Config/Setup.php b/src/Config/Setup.php
index 1f14836..c0ea780 100644
--- a/src/Config/Setup.php
+++ b/src/Config/Setup.php
@@ -4,6 +4,8 @@
use OFFLINE\Bootstrapper\October\Util\KeyGenerator;
+use OFFLINE\Bootstrapper\October\Util\RunsProcess;
+use Symfony\Component\Console\Output\OutputInterface;
/**
* Class Setup
@@ -11,6 +13,8 @@
*/
class Setup
{
+ use RunsProcess;
+
/**
* @var Config
*/
@@ -19,15 +23,21 @@ class Setup
* @var Writer
*/
protected $writer;
+ /**
+ * @var OutputInterface
+ */
+ protected $output;
/**
* Setup constructor.
*
- * @param Config $config
+ * @param Config $config
+ * @param OutputInterface $output
*/
- public function __construct(Config $config)
+ public function __construct(Config $config, OutputInterface $output)
{
$this->config = $config;
+ $this->output = $output;
$this->writer = new Writer();
}
@@ -38,43 +48,60 @@ public function __construct(Config $config)
*/
public function config()
{
- $this->database();
- $this->theme();
$this->app();
+ $this->theme();
$this->mail();
- $this->cms();
}
/**
* Write .env files.
*
* @return $this
+ * @throws \Symfony\Component\Process\Exception\LogicException
*/
public function env()
{
$this->writer->backupExistingEnv();
+ $this->runProcess('php artisan october:env', 'Failed to create env config!');
$lines = [
- 'APP_ENV' => 'dev',
- 'APP_URL' => $this->config->app['url'],
- 'APP_KEY' => (new KeyGenerator())->generate(),
- 'APP_DEBUG' => (bool)$this->config->app['debug'] ? 'true' : 'false',
+ 'APP_DEBUG' => (bool)$this->config->app['debug'] ? 'true' : 'false',
+ 'APP_URL' => $this->config->app['url'],
+ 'APP_KEY' => (new KeyGenerator())->generate(),
+ 'APP_ENV' => 'dev',
'',
- 'CMS_EDGE_UPDATES' => (bool)$this->config->cms['edgeUpdates'] ? 'true' : 'false',
- 'CMS_ASSETS_CACHE' => 'false',
- 'CMS_ROUTES_CACHE' => 'false',
+ 'DB_CONNECTION' => $this->config->database['connection'],
+ 'DB_HOST' => $this->config->database['host'],
+ 'DB_PORT' => $this->config->database['port'],
+ 'DB_DATABASE' => $this->config->database['database'],
+ 'DB_USERNAME' => $this->config->database['username'],
+ 'DB_PASSWORD' => $this->config->database['password'],
'',
- 'DB_CONNECTION' => $this->config->database['connection'],
- 'DB_USERNAME' => $this->config->database['username'],
- 'DB_PASSWORD' => $this->config->database['password'],
- 'DB_DATABASE' => $this->config->database['database'],
- 'DB_HOST' => $this->config->database['host'],
+ 'REDIS_HOST' => '127.0.0.1',
+ 'REDIS_PASSWORD' => 'null',
+ 'REDIS_PORT' => '6379',
'',
- 'MAIL_DRIVER' => $this->config->mail['driver'],
- 'MAIL_NAME' => '"' . $this->config->mail['name'] . '"',
- 'MAIL_ADDRESS' => $this->config->mail['address'],
+ 'CACHE_DRIVER' => 'file',
+ 'SESSION_DRIVER' => 'file',
+ 'QUEUE_DRIVER' => 'sync',
+ '',
+ 'MAIL_DRIVER' => $this->config->mail['driver'],
+ 'MAIL_HOST' => '"' . $this->config->mail['host'] . '"',
+ 'MAIL_PORT' => '587',
+ 'MAIL_ENCRYPTION' => 'tls',
+ 'MAIL_USERNAME' => null,
+ 'MAIL_PASSWORD' => null,
+ 'MAIL_NAME' => '"' . $this->config->mail['name'] . '"',
+ 'MAIL_ADDRESS' => $this->config->mail['address'],
+ '',
+ 'ASSETS_CACHE' => 'false',
+ 'ROUTES_CACHE' => 'false',
+ 'LINK_POLICY' => 'detect',
+ 'ENABLE_CSRF' => 'false',
];
+ $this->writer->removeCurrentEnv();
+
foreach ($lines as $key => $value) {
$this->writer->writeEnvFile($key, $value);
}
@@ -85,52 +112,6 @@ public function env()
return $this;
}
- /**
- * Write the mail configuration.
- *
- * @return void
- */
- protected function mail()
- {
- $values = [
- 'driver' => "env('MAIL_DRIVER', 'log')",
- ];
- $this->writer->write('mail', $values);
-
- // Replace the inline 'address/name' config entry separately
- // since this edge case is not supported by the generic
- // Writer->write method.
- $contents = file_get_contents($this->writer->filePath('mail'));
-
- $regex = "/'address'\s+=>\s+'[^']+',\s+\'name\'\s+=>\s+'[^']+'/";
- $replace = "'address' => env('MAIL_ADDRESS'), 'name' => env('MAIL_NAME')";
-
- file_put_contents($this->writer->filePath('mail'), preg_replace($regex, $replace, $contents));
- }
-
- /**
- * Write the database configuration.
- *
- * @return void
- */
- protected function database()
- {
- $values = ['default' => "env('DB_CONNECTION')"];
-
- foreach ($this->config->database as $key => $setting) {
- // Do nothing for the "connection" config entry since
- // this only specifies which "default" to use. This
- // entry is set separately above.
- if ($key === 'connection') {
- continue;
- }
-
- $values[$key] = "env('DB_" . strtoupper($key) . "')";
- }
-
- $this->writer->write('database', $values);
- }
-
/**
* Write the app configuration.
*
@@ -139,32 +120,12 @@ protected function database()
protected function app()
{
$values = [
- 'url' => "env('APP_URL')",
- 'key' => "env('APP_KEY')",
- 'debug' => "env('APP_DEBUG', false)",
'locale' => $this->config->app['locale'],
];
$this->writer->write('app', $values);
}
- /**
- * Write the cms configuration.
- *
- * @return void
- */
- protected function cms()
- {
- $values = [
- 'edgeUpdates' => "env('CMS_EDGE_UPDATES', false)",
- 'enableRoutesCache' => "env('CMS_ROUTES_CACHE', true)",
- 'enableAssetCache' => "env('CMS_ASSETS_CACHE', true)",
- 'enableCsrfProtection' => "env('CMS_CSRF_PROTECTION', true)",
- ];
-
- $this->writer->write('cms', $values);
- }
-
/**
* Set the default theme.
*
@@ -188,4 +149,21 @@ protected function theme()
return true;
}
+ /**
+ * Write the mail configuration.
+ *
+ * @return void
+ */
+ protected function mail()
+ {
+ // Replace the inline 'address/name' config entry separately
+ // since this edge case is not supported by the generic
+ // Writer->write method.
+ $contents = file_get_contents($this->writer->filePath('mail'));
+
+ $regex = "/'address'\s+=>\s+'[^']+',\s+\'name\'\s+=>\s+'[^']+'/";
+ $replace = "'address' => env('MAIL_ADDRESS'), 'name' => env('MAIL_NAME')";
+
+ file_put_contents($this->writer->filePath('mail'), preg_replace($regex, $replace, $contents));
+ }
}
\ No newline at end of file
diff --git a/src/Config/Writer.php b/src/Config/Writer.php
index 95556b8..d0d3a4c 100644
--- a/src/Config/Writer.php
+++ b/src/Config/Writer.php
@@ -63,6 +63,20 @@ public function backupExistingEnv()
if (file_exists($env)) {
copy($env, $env . '.' . uniqid('original_', false));
+ $this->removeCurrentEnv();
+ }
+ }
+
+ /**
+ * Remove existing .env file.
+ *
+ * @return void
+ */
+ public function removeCurrentEnv()
+ {
+ $env = getcwd() . DS . '.env';
+
+ if (file_exists($env)) {
unlink($env);
}
}
@@ -101,7 +115,9 @@ public function createEnvProduction()
$this->replaceLine('MAIL_DRIVER', 'MAIL_DRIVER=mail', $file);
- $this->removeLines(['CMS_ASSETS_CACHE', 'CMS_ROUTES_CACHE'], $file);
+ $this->replaceLine('ASSETS_CACHE', 'ASSETS_CACHE=true', $file);
+ $this->replaceLine('ROUTES_CACHE', 'ROUTES_CACHE=true', $file);
+ $this->replaceLine('ENABLE_CSRF', 'ENABLE_CSRF=true', $file);
return $this;
}
@@ -186,7 +202,7 @@ public function write($file, array $values)
foreach ($values as $key => $value) {
// No quotes for env() calls
- $replace = substr($value, 0, 4) === 'env(' ? $value : "'{$value}'";
+ $replace = substr($value, 0, 4) === 'env(' ? $value : "'{$value}'";
// Replace "key => value" entries in the file's contents
$contents = preg_replace("/('{$key}'\s+=>\s+)([^\n\]]+),/", "$1" . $replace . ',', $contents);
}
diff --git a/src/Config/Yaml.php b/src/Config/Yaml.php
index bb69841..6f468f3 100644
--- a/src/Config/Yaml.php
+++ b/src/Config/Yaml.php
@@ -46,10 +46,6 @@ public function __construct($file, Parser $parser = null)
*/
public function __get($name)
{
- if ( ! isset($this->config[$name])) {
- throw new \RuntimeException("There is no config entry called $name");
- }
-
- return $this->config[$name];
+ return isset($this->config[$name]) ? $this->config[$name] : null;
}
}
\ No newline at end of file
diff --git a/src/Console/InstallCommand.php b/src/Console/InstallCommand.php
index 6c2ee4e..df03488 100644
--- a/src/Console/InstallCommand.php
+++ b/src/Console/InstallCommand.php
@@ -9,15 +9,16 @@
use OFFLINE\Bootstrapper\October\Installer\PluginInstaller;
use OFFLINE\Bootstrapper\October\Installer\ThemeInstaller;
use OFFLINE\Bootstrapper\October\Util\Composer;
+use OFFLINE\Bootstrapper\October\Util\Gitignore;
+use OFFLINE\Bootstrapper\October\Util\RunsProcess;
use OFFLINE\Bootstrapper\October\Util\UsesTemplate;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Exception\LogicException;
-use Symfony\Component\Process\Process;
-use ZipArchive;
/**
* Class InstallCommand
@@ -25,22 +26,24 @@
*/
class InstallCommand extends Command
{
- use UsesTemplate;
-
- /**
- * Exit code for processes
- */
- const EXIT_CODE_OK = 0;
+ use UsesTemplate, RunsProcess;
/**
* @var
*/
public $config;
-
/**
* @var OutputInterface
*/
protected $output;
+ /**
+ * @var Gitignore
+ */
+ protected $gitignore;
+ /**
+ * @var bool
+ */
+ protected $firstRun;
/**
* Configure the command options.
@@ -52,7 +55,13 @@ protected function configure()
{
$this
->setName('install')
- ->setDescription('Install October CMS.');
+ ->setDescription('Install October CMS.')
+ ->addOption(
+ 'force',
+ null,
+ InputOption::VALUE_NONE,
+ 'Make the installer behave as if it is run for the first time. Existing files may get overwritten.'
+ );
}
/**
@@ -74,6 +83,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
throw new RuntimeException('The Zip PHP extension is not installed. Please install it and try again.');
}
+ $force = $input->getOption('force');
+ $this->firstRun = ! is_dir(getcwd() . DS . 'bootstrap') || $force;
+
$this->output = $output;
$configFile = getcwd() . DS . 'october.yaml';
@@ -81,56 +93,66 @@ protected function execute(InputInterface $input, OutputInterface $output)
return $output->writeln('october.yaml not found. Run october init first.');
}
- $this->config = new Yaml($configFile);
+ $this->config = new Yaml($configFile);
+ $this->gitignore = new Gitignore($this->getGitignore());
$output->writeln('Downloading latest October CMS...');
- (new OctoberCms())->download();
+ try {
+ (new OctoberCms())->download($force);
+ } catch (\LogicException $e) {
+ $output->writeln('' . $e->getMessage() . '');
+ }
$output->writeln('Installing composer dependencies...');
(new Composer())->install();
$output->writeln('Setting up config files...');
- $this->writeConfig();
+ $this->writeConfig($force);
- $output->writeln('Migrating Database...');
+ $output->writeln('Migrating database...');
$this->runProcess('php artisan october:up', 'Migrations failed!');
- $output->writeln('Removing demo data...');
- $this->runProcess('php artisan october:fresh', 'Failed to remove demo data!');
-
- $output->writeln('Clearing cache...');
- $this->runProcess('php artisan clear-compiled', 'Failed to clear compiled files!');
- $this->runProcess('php artisan cache:clear', 'Failed to clear cache!');
-
$output->writeln('Installing Theme...');
try {
- (new ThemeInstaller($this->config))->install();
+ (new ThemeInstaller($this->config, $this->gitignore, $this->output))->install();
} catch (\RuntimeException $e) {
- $output->writeln('' . $e->getMessage() . '');
+ $output->writeln('' . $e->getMessage() . '');
}
$output->writeln('Installing Plugins...');
try {
- (new PluginInstaller($this->config))->install();
+ (new PluginInstaller($this->config, $this->gitignore, $this->output))->install();
} catch (\RuntimeException $e) {
- $output->writeln('' . $e->getMessage() . '');
+ $output->writeln('' . $e->getMessage() . '');
}
+ $output->writeln('Migrating plugin tables...');
+ $this->runProcess('php artisan october:up', 'Migrations failed!');
+
$output->writeln('Setting up deployments...');
try {
- (new DeploymentInstaller($this->config))->install();
+ (new DeploymentInstaller($this->config, $this->gitignore, $this->output))->install($force);
} catch (\RuntimeException $e) {
$output->writeln("${e}");
}
$output->writeln('Creating .gitignore...');
- $this->gitignore();
+ $this->gitignore->write();
- $output->writeln('Creating README...');
- $this->readme();
+ if ($this->firstRun) {
+ $output->writeln('Removing demo data...');
+ $this->runProcess('php artisan october:fresh', 'Failed to remove demo data!');
+
+ $output->writeln('Creating README...');
+ $this->readme();
+
+ $output->writeln('Cleaning up...');
+ $this->cleanup();
+ }
- $output->writeln('Cleaning up...');
- $this->cleanup();
+ $output->writeln('Clearing cache...');
+ $this->runProcess('php artisan clear-compiled', 'Failed to clear compiled files!');
+ $this->runProcess('php artisan cache:clear', 'Failed to clear cache!');
$output->writeln('Application ready! Build something amazing.');
@@ -139,25 +161,37 @@ protected function execute(InputInterface $input, OutputInterface $output)
/**
* Create the .env and config files.
- *
- * @return void
+ *
+ * @param bool $force
*/
- protected function writeConfig()
+ protected function writeConfig($force = false)
{
- $setup = new Setup($this->config);
+ if ( ! $this->firstRun || (file_exists(getcwd() . DS . '.env') && $force === false)) {
+ return $this->output->writeln('-> Configuration already set up. Use --force to regenerate.');
+ }
+ $setup = new Setup($this->config, $this->output);
$setup->env()->config();
}
/**
- * Copy the .gitignore template.
- *
- * @return void
+ * Get the .gitignore template.
+ *
+ * @return string
*/
- protected function gitignore()
+ protected function getGitignore()
{
- $template = $this->getTemplate('gitignore');
- copy($template, getcwd() . DS . '.gitignore');
+ $target = getcwd() . DS . '.gitignore';
+ if (file_exists($target)) {
+ return $target;
+ }
+
+ $file = $this->config->git['bareRepo'] ? 'gitignore.bare' : 'gitignore';
+ $template = $this->getTemplate($file);
+
+ copy($template, $target);
+
+ return $target;
}
/**
@@ -173,46 +207,13 @@ protected function readme()
protected function cleanup()
{
- $remove = ['CONTRIBUTING.md', 'CHANGELOG.md'];
- foreach ($remove as $file) {
- @unlink(getcwd() . DS . $file);
+ if ( ! $this->firstRun) {
+ return;
}
- }
- /**
- * Runs a process and checks it's result.
- * Prints an error message if necessary.
- *
- * @param $command
- * @param $errorMessage
- *
- * @return bool
- * @throws \Symfony\Component\Process\Exception\RuntimeException
- * @throws \Symfony\Component\Process\Exception\LogicException
- */
- protected function runProcess($command, $errorMessage)
- {
- $exitCode = (new Process($command))->run();
-
- return $this->checkResult($exitCode, $errorMessage);
- }
-
- /**
- * Checks the result of a process.
- *
- * @param $exitCode
- * @param $message
- *
- * @return bool
- */
- protected function checkResult($exitCode, $message)
- {
- if ($exitCode !== $this::EXIT_CODE_OK) {
- $this->output->writeln('' . $message . '');
-
- return false;
+ $remove = ['CONTRIBUTING.md', 'CHANGELOG.md', 'ISSUE_TEMPLATE.md'];
+ foreach ($remove as $file) {
+ @unlink(getcwd() . DS . $file);
}
-
- return true;
}
}
diff --git a/src/Downloader/OctoberCms.php b/src/Downloader/OctoberCms.php
index 2f106ee..1646d2e 100644
--- a/src/Downloader/OctoberCms.php
+++ b/src/Downloader/OctoberCms.php
@@ -25,12 +25,18 @@ public function __construct()
/**
* Download latest October CMS.
*
- * @throws LogicException
- * @throws RuntimeException
+ * @param bool $force
+ *
* @return $this
+ * @throws \Symfony\Component\Process\Exception\RuntimeException
+ * @throws \Symfony\Component\Process\Exception\LogicException
*/
- public function download()
+ public function download($force = false)
{
+ if($this->alreadyInstalled($force)) {
+ throw new \LogicException('-> October is already installed. Use --force to reinstall.');
+ }
+
$this->fetchZip()
->extract()
->fetchHtaccess()
@@ -118,4 +124,14 @@ protected function makeFilename()
return getcwd() . DS . 'october_' . md5(time() . uniqid('oc-', true)) . '.zip';
}
+ /**
+ * @param $force
+ *
+ * @return bool
+ */
+ protected function alreadyInstalled($force)
+ {
+ return ! $force && is_dir(getcwd() . DS . 'bootstrap') && is_dir(getcwd() . DS . 'modules');
+ }
+
}
\ No newline at end of file
diff --git a/src/Installer/BaseInstaller.php b/src/Installer/BaseInstaller.php
index 07357dc..0b58bae 100644
--- a/src/Installer/BaseInstaller.php
+++ b/src/Installer/BaseInstaller.php
@@ -4,7 +4,9 @@
use OFFLINE\Bootstrapper\October\Config\Config;
+use OFFLINE\Bootstrapper\October\Util\Gitignore;
use RuntimeException;
+use Symfony\Component\Console\Output\OutputInterface;
abstract class BaseInstaller
{
@@ -12,6 +14,14 @@ abstract class BaseInstaller
* Exit code for processes
*/
const EXIT_CODE_OK = 0;
+ /**
+ * @var Gitignore
+ */
+ protected $gitignore;
+ /**
+ * @var OutputInterface
+ */
+ protected $output;
public abstract function install();
@@ -23,11 +33,15 @@ public abstract function install();
/**
* DeploymentInstaller constructor.
*
- * @param Config $config
+ * @param Config $config
+ * @param Gitignore $gitignore
+ * @param OutputInterface $output
*/
- public function __construct(Config $config)
+ public function __construct(Config $config, Gitignore $gitignore, OutputInterface $output)
{
- $this->config = $config;
+ $this->config = $config;
+ $this->gitignore = $gitignore;
+ $this->output = $output;
}
/**
@@ -86,4 +100,8 @@ public function rmdir($dir)
return rmdir($dir);
}
+
+ protected function write($line) {
+ $this->output->writeln($line);
+ }
}
\ No newline at end of file
diff --git a/src/Installer/DeploymentInstaller.php b/src/Installer/DeploymentInstaller.php
index 14d5b63..43c3a33 100644
--- a/src/Installer/DeploymentInstaller.php
+++ b/src/Installer/DeploymentInstaller.php
@@ -12,6 +12,7 @@
class DeploymentInstaller extends BaseInstaller
{
use UsesTemplate;
+ protected $force = false;
/**
* Install the deployment setup.
@@ -20,19 +21,27 @@ class DeploymentInstaller extends BaseInstaller
* @throws \Symfony\Component\Process\Exception\RuntimeException
* @throws \Symfony\Component\Process\Exception\InvalidArgumentException
*/
- public function install()
+ public function install($force = false)
{
try {
- $deployment = $this->config->deployment;
+ $deployment = $this->config->git['deployment'];
} catch (\RuntimeException $e) {
// Config entry is not set.
return false;
}
+ // Deployments are disabled
+ if ($deployment === false) {
+ return true;
+ }
+
if ( ! method_exists($this, $deployment)) {
+ $this->write('-> Unknown deployment option "' . $deployment . '"');
return false;
}
+ $this->force = $force;
+
return $this->{$deployment}();
}
@@ -40,11 +49,18 @@ public function install()
* Copy the neccessary tempalte files.
*
* @return void
+ * @throws \LogicException
*/
public function gitlab()
{
- copy($this->getTemplate('gitlab-ci.yml'), getcwd() . DS . '.gitlab-ci.yml');
- copy($this->getTemplate('Envoy.blade.php'), getcwd() . DS . 'Envoy.blade.php');
- copy($this->getTemplate('git.cron.sh'), getcwd() . DS . 'git.cron.sh');
+ $base = getcwd() . DS;
+
+ if(! $this->force && file_exists($base . '.gitlab-ci.yml')) {
+ return $this->write('-> Deployment is already set up. Use --force to overwrite');
+ }
+
+ copy($this->getTemplate('gitlab-ci.yml'), $base . '.gitlab-ci.yml');
+ copy($this->getTemplate('Envoy.blade.php'), $base . 'Envoy.blade.php');
+ copy($this->getTemplate('git.cron.sh'), $base . 'git.cron.sh');
}
}
\ No newline at end of file
diff --git a/src/Installer/PluginInstaller.php b/src/Installer/PluginInstaller.php
index a37739f..abf960e 100644
--- a/src/Installer/PluginInstaller.php
+++ b/src/Installer/PluginInstaller.php
@@ -4,6 +4,7 @@
use GitElephant\Repository;
+use OFFLINE\Bootstrapper\October\Util\Gitignore;
use Symfony\Component\Process\Exception\LogicException;
use Symfony\Component\Process\Exception\RuntimeException;
use Symfony\Component\Process\Process;
@@ -16,22 +17,29 @@ class PluginInstaller extends BaseInstaller
{
/**
* Install a plugin via git or artisan.
- *
- * @throws \RuntimeException
- * @throws LogicException
- * @throws RuntimeException
- * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
+ *
+ * @param Gitignore $gitignore
+ *
+ * @return bool
*/
public function install()
{
try {
$config = $this->config->plugins;
} catch (\RuntimeException $e) {
+ $this->write(' - Nothing to install');
+
// No plugin set
return false;
}
+ $isBare = (bool)$this->config->git['bareRepo'];
+ $exceptions = [];
+
foreach ($config as $plugin) {
+
+ $this->write(' - ' . $plugin . '');
+
list($vendor, $plugin, $remote) = $this->parse($plugin);
$vendor = strtolower($vendor);
$plugin = strtolower($plugin);
@@ -47,20 +55,24 @@ public function install()
$this->mkdir($pluginDir);
if ( ! $this->isEmpty($pluginDir)) {
- throw new RuntimeException(
- sprintf('Your plugin directory "%s" is not empty. Cannot clone your repo into it.', $pluginDir)
- );
+ $this->write(' -> ' . sprintf('Plugin "%s" already installed. Skipping.', $plugin) . '');
+ continue;
}
$repo = Repository::open($pluginDir);
try {
$repo->cloneFrom($remote, $pluginDir);
} catch (RuntimeException $e) {
- throw new RuntimeException('Error while cloning plugin repo: ' . $e->getMessage());
+ $this->write(' - ' . 'Error while cloning plugin repo: ' . $e->getMessage() . '');
+ continue;
}
(new Process("php artisan plugin:refresh {$vendor}.{$plugin}"))->run();
+ if ($isBare) {
+ $this->gitignore->addPlugin($vendor, $plugin);
+ }
+
$this->cleanup($pluginDir);
}
diff --git a/src/Installer/ThemeInstaller.php b/src/Installer/ThemeInstaller.php
index ebe78db..23c9645 100644
--- a/src/Installer/ThemeInstaller.php
+++ b/src/Installer/ThemeInstaller.php
@@ -22,6 +22,7 @@ class ThemeInstaller extends BaseInstaller
* @throws RuntimeException
* @throws InvalidArgumentException
* @throws \RuntimeException
+ * @throws \LogicException
*/
public function install()
{
@@ -41,9 +42,8 @@ public function install()
$this->mkdir($themeDir);
if ( ! $this->isEmpty($themeDir)) {
- throw new RuntimeException(
- sprintf('Your theme directory "%s" is not empty. Cannot clone your repo into it.', $themeDir)
- );
+ $this->write(sprintf('-> Theme "%s" is already installed. Skipping.', $theme));
+ return;
}
$repo = Repository::open($themeDir);
diff --git a/src/Util/Composer.php b/src/Util/Composer.php
index 38e7a8e..ec54382 100644
--- a/src/Util/Composer.php
+++ b/src/Util/Composer.php
@@ -49,7 +49,24 @@ protected function findComposer()
*/
public function install()
{
- (new Process($this->composer . ' install --no-scripts'))
+ (new Process($this->composer . ' install --no-scripts --no-interaction'))
+ ->setTimeout(3600)
+ ->run();
+ }
+
+ /**
+ * Composer require
+ *
+ * @return void
+ * @throws \Symfony\Component\Process\Exception\LogicException
+ * @throws \Symfony\Component\Process\Exception\RuntimeException
+ * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
+ */
+ public function addDependency($package)
+ {
+ $package = escapeshellarg($package);
+
+ (new Process($this->composer . ' require ' . $package . '--no-interaction'))
->setTimeout(3600)
->run();
}
diff --git a/src/Util/Gitignore.php b/src/Util/Gitignore.php
new file mode 100644
index 0000000..a53273e
--- /dev/null
+++ b/src/Util/Gitignore.php
@@ -0,0 +1,65 @@
+file = $file;
+ $this->contents = file($file);
+ }
+
+ public function write()
+ {
+ file_put_contents($this->file, $this->contents);
+ }
+
+ public function add($line)
+ {
+ if ($this->hasLine($line)) {
+ return;
+ }
+
+ $this->contents[] = $line . PHP_EOL;
+ }
+
+ public function hasLine($line)
+ {
+ foreach ($this->contents as $entry) {
+ if (strtolower($line) === strtolower($entry)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected function newLine()
+ {
+ $this->contents[] = PHP_EOL . PHP_EOL;
+ }
+
+ public function addPlugin($vendor, $plugin)
+ {
+ $header = sprintf("# %s.%s", $vendor, $plugin);
+ if ($this->hasLine($header)) {
+ return;
+ }
+
+ $this->newLine();
+ $this->add($header);
+ $this->add('!plugins/' . $vendor);
+ $this->add('!plugins/' . $vendor . '/' . $plugin);
+ $this->add('!plugins/' . $vendor . '/' . $plugin . '/**/*');
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/Util/RunsProcess.php b/src/Util/RunsProcess.php
new file mode 100644
index 0000000..6e19cba
--- /dev/null
+++ b/src/Util/RunsProcess.php
@@ -0,0 +1,45 @@
+run();
+
+ return $this->checkProcessResult($exitCode, $errorMessage);
+ }
+
+ /**
+ * Checks the result of a process.
+ *
+ * @param $exitCode
+ * @param $message
+ *
+ * @return bool
+ */
+ protected function checkProcessResult($exitCode, $message)
+ {
+ if ($exitCode !== 0) {
+ $this->output->writeln('' . $message . '');
+
+ return false;
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/templates/Envoy.blade.php b/templates/Envoy.blade.php
index 0fbda76..d9777fd 100644
--- a/templates/Envoy.blade.php
+++ b/templates/Envoy.blade.php
@@ -13,6 +13,8 @@
git pull
[ ! -f "composer.phar" ] && wget https://getcomposer.org/composer.phar
php composer.phar install --no-interaction --no-dev --prefer-dist
+ ## Enable this line when using bare repos
+ # ./vendor/bin/october install
php artisan -v october:up
git status -s
@endtask
diff --git a/templates/gitignore.bare b/templates/gitignore.bare
new file mode 100644
index 0000000..c43c175
--- /dev/null
+++ b/templates/gitignore.bare
@@ -0,0 +1,10 @@
+*
+!.gitignore
+!composer.*
+!.env.*
+!october.yaml
+!Envoy.blade.php
+!.gitlab-ci.yml
+!themes
+!themes/**/*
+!plugins
diff --git a/templates/october.yaml b/templates/october.yaml
index 86ac2f5..8fcb905 100644
--- a/templates/october.yaml
+++ b/templates/october.yaml
@@ -9,12 +9,15 @@ cms:
database:
connection: mysql
- username: homestead
- password: secret
- database: bootstrapper
- host: 192.168.10.10
+ host: localhost
+ port: 3306
+ username: root
+ password: password
+ database: myproject
-deployment: false
+git:
+ deployment: false
+ bareRepo: true # Exclude everything except themes and custom plugins in git
plugins:
- Rainlab.Pages
@@ -26,6 +29,7 @@ plugins:
# - Vendor.Private (user@remote.git)
mail:
+ host: smtp.mailgun.org
name: User Name
address: email@example.com
driver: log