Updated build and versioning system
Added versioning file instead of using git tags (Step towards removing git as a dependancy in the future) Updated gulpfile to fit with verisioning system and cleaned up node dependancies. Fixes #108
Showing
14 changed files
with
64 additions
and
120 deletions
| ... | @@ -17,10 +17,7 @@ class SettingController extends Controller | ... | @@ -17,10 +17,7 @@ class SettingController extends Controller |
| 17 | $this->setPageTitle('Settings'); | 17 | $this->setPageTitle('Settings'); |
| 18 | 18 | ||
| 19 | // Get application version | 19 | // Get application version |
| 20 | - $version = false; | 20 | + $version = trim(file_get_contents(base_path('version'))); |
| 21 | - if (function_exists('exec')) { | ||
| 22 | - $version = exec('git describe --always --tags '); | ||
| 23 | - } | ||
| 24 | 21 | ||
| 25 | return view('settings/index', ['version' => $version]); | 22 | return view('settings/index', ['version' => $version]); |
| 26 | } | 23 | } | ... | ... |
| ... | @@ -11,29 +11,20 @@ use BookStack\Ownable; | ... | @@ -11,29 +11,20 @@ use BookStack\Ownable; |
| 11 | */ | 11 | */ |
| 12 | function versioned_asset($file = '') | 12 | function versioned_asset($file = '') |
| 13 | { | 13 | { |
| 14 | - // Don't require css and JS assets for testing | 14 | + static $version = null; |
| 15 | - if (config('app.env') === 'testing') return ''; | 15 | + |
| 16 | - | 16 | + if (is_null($version)) { |
| 17 | - static $manifest = null; | 17 | + $versionFile = base_path('version'); |
| 18 | - $manifestPath = 'build/manifest.json'; | 18 | + $version = trim(file_get_contents($versionFile)); |
| 19 | - | ||
| 20 | - if (is_null($manifest) && file_exists($manifestPath)) { | ||
| 21 | - $manifest = json_decode(file_get_contents(public_path($manifestPath)), true); | ||
| 22 | - } else if (!file_exists($manifestPath)) { | ||
| 23 | - if (config('app.env') !== 'production') { | ||
| 24 | - $path = public_path($manifestPath); | ||
| 25 | - $error = "No {$path} file found, Ensure you have built the css/js assets using gulp."; | ||
| 26 | - } else { | ||
| 27 | - $error = "No {$manifestPath} file found, Ensure you are using the release version of BookStack"; | ||
| 28 | - } | ||
| 29 | - throw new \Exception($error); | ||
| 30 | } | 19 | } |
| 31 | 20 | ||
| 32 | - if (isset($manifest[$file])) { | 21 | + $additional = ''; |
| 33 | - return baseUrl($manifest[$file]); | 22 | + if (config('app.env') === 'development') { |
| 23 | + $additional = sha1_file(public_path($file)); | ||
| 34 | } | 24 | } |
| 35 | 25 | ||
| 36 | - throw new InvalidArgumentException("File {$file} not defined in asset manifest."); | 26 | + $path = $file . '?version=' . urlencode($version) . $additional; |
| 27 | + return baseUrl($path); | ||
| 37 | } | 28 | } |
| 38 | 29 | ||
| 39 | /** | 30 | /** | ... | ... |
| 1 | var elixir = require('laravel-elixir'); | 1 | var elixir = require('laravel-elixir'); |
| 2 | 2 | ||
| 3 | -// Custom extensions | 3 | +elixir(mix => { |
| 4 | -var gulp = require('gulp'); | 4 | + mix.sass('styles.scss'); |
| 5 | -var Task = elixir.Task; | 5 | + mix.sass('print-styles.scss'); |
| 6 | -var fs = require('fs'); | 6 | + mix.sass('export-styles.scss'); |
| 7 | - | 7 | + mix.browserify('global.js', './public/js/common.js'); |
| 8 | -elixir.extend('queryVersion', function(inputFiles) { | ||
| 9 | - new Task('queryVersion', function() { | ||
| 10 | - var manifestObject = {}; | ||
| 11 | - var uidString = Date.now().toString(16).slice(4); | ||
| 12 | - for (var i = 0; i < inputFiles.length; i++) { | ||
| 13 | - var file = inputFiles[i]; | ||
| 14 | - manifestObject[file] = file + '?version=' + uidString; | ||
| 15 | - } | ||
| 16 | - var fileContents = JSON.stringify(manifestObject, null, 1); | ||
| 17 | - fs.writeFileSync('public/build/manifest.json', fileContents); | ||
| 18 | - }).watch(['./public/css/*.css', './public/js/*.js']); | ||
| 19 | -}); | ||
| 20 | - | ||
| 21 | -elixir(function(mix) { | ||
| 22 | - mix.sass('styles.scss') | ||
| 23 | - .sass('print-styles.scss') | ||
| 24 | - .sass('export-styles.scss') | ||
| 25 | - .browserify('global.js', 'public/js/common.js') | ||
| 26 | - .queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']); | ||
| 27 | }); | 8 | }); | ... | ... |
| 1 | { | 1 | { |
| 2 | "private": true, | 2 | "private": true, |
| 3 | - "devDependencies": { | 3 | + "scripts": { |
| 4 | - "gulp": "^3.9.0" | 4 | + "prod": "gulp --production", |
| 5 | + "dev": "gulp watch" | ||
| 5 | }, | 6 | }, |
| 6 | - "dependencies": { | 7 | + "devDependencies": { |
| 7 | "angular": "^1.5.5", | 8 | "angular": "^1.5.5", |
| 8 | "angular-animate": "^1.5.5", | 9 | "angular-animate": "^1.5.5", |
| 9 | "angular-resource": "^1.5.5", | 10 | "angular-resource": "^1.5.5", |
| 10 | "angular-sanitize": "^1.5.5", | 11 | "angular-sanitize": "^1.5.5", |
| 11 | - "angular-ui-sortable": "^0.14.0", | 12 | + "angular-ui-sortable": "^0.15.0", |
| 12 | - "babel-runtime": "^5.8.29", | ||
| 13 | - "bootstrap-sass": "^3.0.0", | ||
| 14 | "dropzone": "^4.0.1", | 13 | "dropzone": "^4.0.1", |
| 15 | - "laravel-elixir": "^5.0.0", | 14 | + "gulp": "^3.9.0", |
| 15 | + "laravel-elixir": "^6.0.0-11", | ||
| 16 | + "laravel-elixir-browserify-official": "^0.1.3", | ||
| 16 | "marked": "^0.3.5", | 17 | "marked": "^0.3.5", |
| 17 | "moment": "^2.12.0", | 18 | "moment": "^2.12.0", |
| 18 | "zeroclipboard": "^2.2.0" | 19 | "zeroclipboard": "^2.2.0" | ... | ... |
| ... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
| 30 | <env name="AUTH_METHOD" value="standard"/> | 30 | <env name="AUTH_METHOD" value="standard"/> |
| 31 | <env name="DISABLE_EXTERNAL_SERVICES" value="true"/> | 31 | <env name="DISABLE_EXTERNAL_SERVICES" value="true"/> |
| 32 | <env name="LDAP_VERSION" value="3"/> | 32 | <env name="LDAP_VERSION" value="3"/> |
| 33 | + <env name="STORAGE_TYPE" value="local"/> | ||
| 33 | <env name="GITHUB_APP_ID" value="aaaaaaaaaaaaaa"/> | 34 | <env name="GITHUB_APP_ID" value="aaaaaaaaaaaaaa"/> |
| 34 | <env name="GITHUB_APP_SECRET" value="aaaaaaaaaaaaaa"/> | 35 | <env name="GITHUB_APP_SECRET" value="aaaaaaaaaaaaaa"/> |
| 35 | <env name="GOOGLE_APP_ID" value="aaaaaaaaaaaaaa"/> | 36 | <env name="GOOGLE_APP_ID" value="aaaaaaaaaaaaaa"/> | ... | ... |
public/build/.gitignore
deleted
100644 → 0
| ... | @@ -2,13 +2,15 @@ | ... | @@ -2,13 +2,15 @@ |
| 2 | 2 | ||
| 3 | [](https://github.com/ssddanbrown/BookStack/releases/latest) | 3 | [](https://github.com/ssddanbrown/BookStack/releases/latest) |
| 4 | [](https://github.com/ssddanbrown/BookStack/blob/master/LICENSE) | 4 | [](https://github.com/ssddanbrown/BookStack/blob/master/LICENSE) |
| 5 | -[](https://travis-ci.org/ssddanbrown/BookStack) | 5 | +[](https://travis-ci.org/BookStackApp/BookStack) |
| 6 | 6 | ||
| 7 | A platform for storing and organising information and documentation. General information and documentation for BookStack can be found at https://www.bookstackapp.com/. | 7 | A platform for storing and organising information and documentation. General information and documentation for BookStack can be found at https://www.bookstackapp.com/. |
| 8 | 8 | ||
| 9 | * [Installation Instructions](https://www.bookstackapp.com/docs/admin/installation) | 9 | * [Installation Instructions](https://www.bookstackapp.com/docs/admin/installation) |
| 10 | * [Documentation](https://www.bookstackapp.com/docs) | 10 | * [Documentation](https://www.bookstackapp.com/docs) |
| 11 | -* [Demo Instance](https://demo.bookstackapp.com) *(Login username: `admin@example.com`. Password: `password`)* | 11 | +* [Demo Instance](https://demo.bookstackapp.com) |
| 12 | + * *Username: `admin@example.com`* | ||
| 13 | + * *Password: `password`* | ||
| 12 | * [BookStack Blog](https://www.bookstackapp.com/blog) | 14 | * [BookStack Blog](https://www.bookstackapp.com/blog) |
| 13 | 15 | ||
| 14 | ## Development & Testing | 16 | ## Development & Testing |
| ... | @@ -29,7 +31,7 @@ php artisan migrate --database=mysql_testing | ... | @@ -29,7 +31,7 @@ php artisan migrate --database=mysql_testing |
| 29 | php artisan db:seed --class=DummyContentSeeder --database=mysql_testing | 31 | php artisan db:seed --class=DummyContentSeeder --database=mysql_testing |
| 30 | ``` | 32 | ``` |
| 31 | 33 | ||
| 32 | -Once done you can run `phpunit` (or `./vendor/bin/phpunit` if `phpunit` is not found) in the application root directory to run all tests. | 34 | +Once done you can run `phpunit` in the application root directory to run all tests. |
| 33 | 35 | ||
| 34 | ## License | 36 | ## License |
| 35 | 37 | ||
| ... | @@ -51,3 +53,5 @@ These are the great projects used to help build BookStack: | ... | @@ -51,3 +53,5 @@ These are the great projects used to help build BookStack: |
| 51 | * [TinyColorPicker](http://www.dematte.at/tinyColorPicker/index.html) | 53 | * [TinyColorPicker](http://www.dematte.at/tinyColorPicker/index.html) |
| 52 | * [Marked](https://github.com/chjj/marked) | 54 | * [Marked](https://github.com/chjj/marked) |
| 53 | * [Moment.js](http://momentjs.com/) | 55 | * [Moment.js](http://momentjs.com/) |
| 56 | + | ||
| 57 | +Additionally, Thank you [BrowserStack](https://www.browserstack.com/) for supporting us and making cross-browser testing easy. | ... | ... |
| 1 | - | ||
| 2 | -<div class="image-picker"> | ||
| 3 | - <div> | ||
| 4 | - <img ng-if="image && image !== 'none'" ng-src="{{image}}" ng-class="{{imageClass}}" alt="Image Preview"> | ||
| 5 | - <img ng-if="image === '' && defaultImage" ng-src="{{defaultImage}}" ng-class="{{imageClass}}" alt="Image Preview"> | ||
| 6 | - </div> | ||
| 7 | - <button class="button" type="button" ng-click="showImageManager()">Select Image</button> | ||
| 8 | - <br> | ||
| 9 | - | ||
| 10 | - <button class="text-button" ng-click="reset()" type="button">Reset</button> | ||
| 11 | - <span ng-show="showRemove" class="sep">|</span> | ||
| 12 | - <button ng-show="showRemove" class="text-button neg" ng-click="remove()" type="button">Remove</button> | ||
| 13 | - | ||
| 14 | - <input type="hidden" ng-attr-name="{{name}}" ng-attr-id="{{name}}" ng-attr-value="{{value}}"> | ||
| 15 | -</div> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | "use strict"; | 1 | "use strict"; |
| 2 | 2 | ||
| 3 | -const moment = require('moment'); | 3 | +import moment from 'moment'; |
| 4 | +import 'moment/locale/en-gb'; | ||
| 5 | +moment.locale('en-gb'); | ||
| 4 | 6 | ||
| 5 | module.exports = function (ngApp, events) { | 7 | module.exports = function (ngApp, events) { |
| 6 | 8 | ||
| ... | @@ -729,20 +731,3 @@ module.exports = function (ngApp, events) { | ... | @@ -729,20 +731,3 @@ module.exports = function (ngApp, events) { |
| 729 | }]); | 731 | }]); |
| 730 | 732 | ||
| 731 | }; | 733 | }; |
| 732 | - | ||
| 733 | - | ||
| 734 | - | ||
| 735 | - | ||
| 736 | - | ||
| 737 | - | ||
| 738 | - | ||
| 739 | - | ||
| 740 | - | ||
| 741 | - | ||
| 742 | - | ||
| 743 | - | ||
| 744 | - | ||
| 745 | - | ||
| 746 | - | ||
| 747 | - | ||
| 748 | - | ... | ... |
| ... | @@ -2,10 +2,6 @@ | ... | @@ -2,10 +2,6 @@ |
| 2 | const DropZone = require('dropzone'); | 2 | const DropZone = require('dropzone'); |
| 3 | const markdown = require('marked'); | 3 | const markdown = require('marked'); |
| 4 | 4 | ||
| 5 | -const toggleSwitchTemplate = require('./components/toggle-switch.html'); | ||
| 6 | -const imagePickerTemplate = require('./components/image-picker.html'); | ||
| 7 | -const dropZoneTemplate = require('./components/drop-zone.html'); | ||
| 8 | - | ||
| 9 | module.exports = function (ngApp, events) { | 5 | module.exports = function (ngApp, events) { |
| 10 | 6 | ||
| 11 | /** | 7 | /** |
| ... | @@ -16,7 +12,12 @@ module.exports = function (ngApp, events) { | ... | @@ -16,7 +12,12 @@ module.exports = function (ngApp, events) { |
| 16 | ngApp.directive('toggleSwitch', function () { | 12 | ngApp.directive('toggleSwitch', function () { |
| 17 | return { | 13 | return { |
| 18 | restrict: 'A', | 14 | restrict: 'A', |
| 19 | - template: toggleSwitchTemplate, | 15 | + template: ` |
| 16 | + <div class="toggle-switch" ng-click="switch()" ng-class="{'active': isActive}"> | ||
| 17 | + <input type="hidden" ng-attr-name="{{name}}" ng-attr-value="{{value}}"/> | ||
| 18 | + <div class="switch-handle"></div> | ||
| 19 | + </div> | ||
| 20 | + `, | ||
| 20 | scope: true, | 21 | scope: true, |
| 21 | link: function (scope, element, attrs) { | 22 | link: function (scope, element, attrs) { |
| 22 | scope.name = attrs.name; | 23 | scope.name = attrs.name; |
| ... | @@ -94,7 +95,22 @@ module.exports = function (ngApp, events) { | ... | @@ -94,7 +95,22 @@ module.exports = function (ngApp, events) { |
| 94 | ngApp.directive('imagePicker', ['$http', 'imageManagerService', function ($http, imageManagerService) { | 95 | ngApp.directive('imagePicker', ['$http', 'imageManagerService', function ($http, imageManagerService) { |
| 95 | return { | 96 | return { |
| 96 | restrict: 'E', | 97 | restrict: 'E', |
| 97 | - template: imagePickerTemplate, | 98 | + template: ` |
| 99 | + <div class="image-picker"> | ||
| 100 | + <div> | ||
| 101 | + <img ng-if="image && image !== 'none'" ng-src="{{image}}" ng-class="{{imageClass}}" alt="Image Preview"> | ||
| 102 | + <img ng-if="image === '' && defaultImage" ng-src="{{defaultImage}}" ng-class="{{imageClass}}" alt="Image Preview"> | ||
| 103 | + </div> | ||
| 104 | + <button class="button" type="button" ng-click="showImageManager()">Select Image</button> | ||
| 105 | + <br> | ||
| 106 | + | ||
| 107 | + <button class="text-button" ng-click="reset()" type="button">Reset</button> | ||
| 108 | + <span ng-show="showRemove" class="sep">|</span> | ||
| 109 | + <button ng-show="showRemove" class="text-button neg" ng-click="remove()" type="button">Remove</button> | ||
| 110 | + | ||
| 111 | + <input type="hidden" ng-attr-name="{{name}}" ng-attr-id="{{name}}" ng-attr-value="{{value}}"> | ||
| 112 | + </div> | ||
| 113 | + `, | ||
| 98 | scope: { | 114 | scope: { |
| 99 | name: '@', | 115 | name: '@', |
| 100 | resizeHeight: '@', | 116 | resizeHeight: '@', |
| ... | @@ -161,7 +177,11 @@ module.exports = function (ngApp, events) { | ... | @@ -161,7 +177,11 @@ module.exports = function (ngApp, events) { |
| 161 | ngApp.directive('dropZone', [function () { | 177 | ngApp.directive('dropZone', [function () { |
| 162 | return { | 178 | return { |
| 163 | restrict: 'E', | 179 | restrict: 'E', |
| 164 | - template: dropZoneTemplate, | 180 | + template: ` |
| 181 | + <div class="dropzone-container"> | ||
| 182 | + <div class="dz-message">Drop files or click here to upload</div> | ||
| 183 | + </div> | ||
| 184 | + `, | ||
| 165 | scope: { | 185 | scope: { |
| 166 | uploadUrl: '@', | 186 | uploadUrl: '@', |
| 167 | eventSuccess: '=', | 187 | eventSuccess: '=', |
| ... | @@ -904,17 +924,3 @@ module.exports = function (ngApp, events) { | ... | @@ -904,17 +924,3 @@ module.exports = function (ngApp, events) { |
| 904 | }; | 924 | }; |
| 905 | }]); | 925 | }]); |
| 906 | }; | 926 | }; |
| 907 | - | ||
| 908 | - | ||
| 909 | - | ||
| 910 | - | ||
| 911 | - | ||
| 912 | - | ||
| 913 | - | ||
| 914 | - | ||
| 915 | - | ||
| 916 | - | ||
| 917 | - | ||
| 918 | - | ||
| 919 | - | ||
| 920 | - | ... | ... |
-
Please register or sign in to post a comment