2014-02-12 10:23:40 +00:00
fs = require " fs "
module.exports = (grunt) ->
grunt . loadNpmTasks ' grunt-contrib-coffee '
grunt . loadNpmTasks ' grunt-contrib-less '
grunt . loadNpmTasks ' grunt-contrib-clean '
grunt . loadNpmTasks ' grunt-mocha-test '
grunt . loadNpmTasks ' grunt-available-tasks '
grunt . loadNpmTasks ' grunt-contrib-requirejs '
grunt . loadNpmTasks ' grunt-bunyan '
2015-03-17 16:59:17 +00:00
grunt . loadNpmTasks ' grunt-sed '
grunt . loadNpmTasks ' grunt-git-rev-parse '
2015-10-09 09:11:38 +00:00
grunt . loadNpmTasks ' grunt-file-append '
2015-11-12 12:38:35 +00:00
grunt . loadNpmTasks ' grunt-file-append '
grunt . loadNpmTasks ' grunt-env '
2016-06-15 11:08:11 +00:00
grunt . loadNpmTasks ' grunt-newer '
grunt . loadNpmTasks ' grunt-contrib-watch '
grunt . loadNpmTasks ' grunt-parallel '
grunt . loadNpmTasks ' grunt-exec '
2016-07-01 14:04:39 +00:00
# grunt.loadNpmTasks 'grunt-contrib-imagemin'
2016-07-04 15:03:29 +00:00
# grunt.loadNpmTasks 'grunt-sprity'
2015-10-09 09:11:38 +00:00
2014-09-08 13:19:24 +00:00
config =
2016-06-15 11:08:11 +00:00
exec:
run:
command : " node app.js | ./node_modules/logger-sharelatex/node_modules/bunyan/bin/bunyan --color "
2016-07-10 10:04:51 +00:00
cssmin:
2016-07-10 10:10:43 +00:00
command : " node_modules/clean-css/bin/cleancss --s0 -o public/stylesheets/style.css public/stylesheets/style.css "
2016-06-15 11:08:11 +00:00
watch:
coffee:
2016-06-18 18:16:45 +00:00
files: ' public/**/*.coffee '
2016-06-15 11:08:11 +00:00
tasks: [ ' quickcompile:coffee ' ]
options: { }
less:
files: ' **/*.less '
tasks: [ ' compile:css ' ]
options: { }
parallel:
run:
tasks : [ ' exec ' , ' watch ' ]
options:
grunt : true
stream : true
2014-02-12 10:23:40 +00:00
2016-06-18 15:50:56 +00:00
2016-06-30 13:58:54 +00:00
# imagemin:
# dynamic:
# files: [{
# expand: true
# cwd: 'public/img/'
# src: ['**/*.{png,jpg,gif}']
# dest: 'public/img/'
# }]
# options:
# interlaced:false
# optimizationLevel: 7
2016-06-18 18:16:45 +00:00
2016-07-04 15:03:29 +00:00
# sprity:
# sprite:
# options:
# cssPath:"/img/"
# 'style': '../../public/stylesheets/app/sprites.less'
# margin: 0
# src: ['./public/img/flags/24/*.png']
# dest: './public/img/sprite'
2016-06-18 18:16:45 +00:00
2016-06-18 15:50:56 +00:00
2014-02-12 10:23:40 +00:00
coffee:
app_dir:
expand: true ,
flatten: false ,
cwd: ' app/coffee ' ,
src: [ ' **/*.coffee ' ] ,
dest: ' app/js/ ' ,
ext: ' .js '
app:
src: ' app.coffee '
dest: ' app.js '
2014-03-18 15:06:10 +00:00
2014-02-12 10:23:40 +00:00
sharejs:
options:
join: true
files:
" public/js/libs/sharejs.js " : [
2014-07-08 11:01:32 +00:00
" public/coffee/ide/editor/sharejs/header.coffee "
" public/coffee/ide/editor/sharejs/vendor/types/helpers.coffee "
" public/coffee/ide/editor/sharejs/vendor/types/text.coffee "
" public/coffee/ide/editor/sharejs/vendor/types/text-api.coffee "
" public/coffee/ide/editor/sharejs/vendor/client/microevent.coffee "
" public/coffee/ide/editor/sharejs/vendor/client/doc.coffee "
" public/coffee/ide/editor/sharejs/vendor/client/ace.coffee "
2014-02-12 10:23:40 +00:00
]
client:
expand: true ,
flatten: false ,
cwd: ' public/coffee ' ,
src: [ ' **/*.coffee ' ] ,
dest: ' public/js/ ' ,
ext: ' .js '
smoke_tests:
expand: true ,
flatten: false ,
cwd: ' test/smoke/coffee ' ,
src: [ ' **/*.coffee ' ] ,
dest: ' test/smoke/js/ ' ,
ext: ' .js '
unit_tests:
expand: true ,
flatten: false ,
cwd: ' test/UnitTests/coffee ' ,
src: [ ' **/*.coffee ' ] ,
dest: ' test/UnitTests/js/ ' ,
ext: ' .js '
2016-03-08 15:59:04 +00:00
acceptance_tests:
expand: true ,
flatten: false ,
cwd: ' test/acceptance/coffee ' ,
src: [ ' **/*.coffee ' ] ,
dest: ' test/acceptance/js/ ' ,
ext: ' .js '
2014-02-12 10:23:40 +00:00
less:
app:
files:
2014-06-04 15:14:35 +00:00
" public/stylesheets/style.css " : " public/stylesheets/style.less "
2014-02-12 10:23:40 +00:00
2016-07-10 10:04:51 +00:00
2016-06-18 20:49:32 +00:00
2015-11-12 12:38:35 +00:00
env:
run:
add:
NODE_TLS_REJECT_UNAUTHORIZED : 0
2016-06-15 11:08:11 +00:00
2014-02-12 10:23:40 +00:00
requirejs:
compile:
options:
2014-06-16 17:29:55 +00:00
optimize : " uglify2 "
uglify2:
mangle: false
2014-02-12 10:23:40 +00:00
appDir: " public/js "
baseUrl: " ./ "
dir: " public/minjs "
inlineText: false
preserveLicenseComments: false
paths:
2015-01-29 18:31:11 +00:00
" moment " : " libs/moment-2.9.0 "
2015-01-29 18:11:38 +00:00
" mathjax " : " /js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML "
2016-02-03 15:07:06 +00:00
" libs/pdf " : " libs/pdfjs-1.3.91/pdf "
2014-02-12 10:23:40 +00:00
shim:
" libs/pdf " :
2016-02-03 15:07:06 +00:00
deps: [ " libs/pdfjs-1.3.91/compatibility " ]
2014-02-12 10:23:40 +00:00
skipDirOptimize: true
modules: [
{
name: " main " ,
2014-07-08 11:01:32 +00:00
exclude: [ " libs " ]
2014-02-12 10:23:40 +00:00
} , {
name: " ide " ,
2014-12-01 14:36:23 +00:00
exclude: [ " libs " , " libs/pdf " ]
2014-02-12 10:23:40 +00:00
} , {
2014-07-08 11:01:32 +00:00
name: " libs "
2014-11-04 12:01:53 +00:00
} , {
name: " ace/mode-latex "
2014-02-12 10:23:40 +00:00
}
2014-11-04 12:01:53 +00:00
2014-02-12 10:23:40 +00:00
]
clean:
app: [ " app/js " ]
unit_tests: [ " test/UnitTests/js " ]
2016-03-08 15:59:04 +00:00
acceptance_tests: [ " test/acceptance/js " ]
2014-02-12 10:23:40 +00:00
mochaTest:
unit:
src: [ " test/UnitTests/js/ #{ grunt . option ( ' feature ' ) or ' ** ' } /*.js " ]
options:
reporter: grunt . option ( ' reporter ' ) or ' spec '
grep: grunt . option ( " grep " )
smoke:
src: [ ' test/smoke/js/**/*.js ' ]
options:
reporter: grunt . option ( ' reporter ' ) or ' spec '
grep: grunt . option ( " grep " )
2016-03-08 15:59:04 +00:00
acceptance:
src: [ " test/acceptance/js/ #{ grunt . option ( ' feature ' ) or ' ** ' } /*.js " ]
options:
2016-03-10 11:13:57 +00:00
timeout: 10000
2016-03-08 15:59:04 +00:00
reporter: grunt . option ( ' reporter ' ) or ' spec '
grep: grunt . option ( " grep " )
2014-02-12 10:23:40 +00:00
2015-03-17 16:59:17 +00:00
" git-rev-parse " :
version:
options:
prop: ' commit '
2015-10-09 09:11:38 +00:00
file_append:
default_options: files: [ {
append: ' \n //ide.js is complete - used for automated testing '
input: ' public/minjs/ide.js '
output: ' public/minjs/ide.js '
} ]
2015-03-17 16:59:17 +00:00
sed:
version:
path: " app/views/sentry.jade "
pattern: ' @@COMMIT@@ ' ,
replacement: ' <%= commit %> ' ,
release:
path: " app/views/sentry.jade "
pattern: " @@RELEASE@@ "
replacement: process . env . BUILD_NUMBER || " (unknown build) "
2014-02-12 10:23:40 +00:00
2016-06-30 13:58:54 +00:00
2016-06-15 11:08:11 +00:00
2014-02-12 10:23:40 +00:00
availabletasks:
tasks:
options:
2016-06-15 11:08:11 +00:00
filter: ' exclude ' ,
tasks: [
' coffee '
' less '
' clean '
' mochaTest '
' availabletasks '
' wrap_sharejs '
' requirejs '
' execute '
' bunyan '
]
groups:
" Compile tasks " : [
" compile:server "
" compile:client "
" compile:tests "
" compile "
" compile:unit_tests "
" compile:smoke_tests "
" compile:css "
" compile:minify "
" install "
]
" Test tasks " : [
" test:unit "
" test:acceptance "
]
" Run tasks " : [
" run "
" default "
]
" Misc " : [
" help "
]
2014-02-12 10:23:40 +00:00
2014-09-08 13:19:24 +00:00
moduleCompileServerTasks = [ ]
moduleCompileUnitTestTasks = [ ]
moduleUnitTestTasks = [ ]
2014-09-08 16:33:30 +00:00
moduleCompileClientTasks = [ ]
moduleIdeClientSideIncludes = [ ]
2014-10-03 10:32:59 +00:00
moduleMainClientSideIncludes = [ ]
2014-09-08 13:23:47 +00:00
if fs . existsSync " ./modules "
for module in fs . readdirSync " ./modules "
2014-09-08 14:40:46 +00:00
if fs . existsSync " ./modules/ #{ module } /index.coffee "
config . coffee [ " module_ #{ module } _server " ] = {
expand: true ,
flatten: false ,
cwd: " modules/ #{ module } /app/coffee " ,
src: [ ' **/*.coffee ' ] ,
dest: " modules/ #{ module } /app/js " ,
ext: ' .js '
}
config . coffee [ " module_ #{ module } _index " ] = {
src: " modules/ #{ module } /index.coffee " ,
dest: " modules/ #{ module } /index.js "
}
moduleCompileServerTasks . push " coffee:module_ #{ module } _server "
moduleCompileServerTasks . push " coffee:module_ #{ module } _index "
config . coffee [ " module_ #{ module } _unit_tests " ] = {
expand: true ,
flatten: false ,
cwd: " modules/ #{ module } /test/unit/coffee " ,
src: [ ' **/*.coffee ' ] ,
dest: " modules/ #{ module } /test/unit/js " ,
ext: ' .js '
}
config . mochaTest [ " module_ #{ module } _unit " ] = {
src: [ " modules/ #{ module } /test/unit/js/*.js " ]
options:
reporter: grunt . option ( ' reporter ' ) or ' spec '
grep: grunt . option ( " grep " )
}
moduleCompileUnitTestTasks . push " coffee:module_ #{ module } _unit_tests "
moduleUnitTestTasks . push " mochaTest:module_ #{ module } _unit "
2014-09-08 16:33:30 +00:00
2014-10-03 10:32:59 +00:00
if fs . existsSync " ./modules/ #{ module } /public/coffee/ide/index.coffee "
2014-09-08 16:33:30 +00:00
config . coffee [ " module_ #{ module } _client_ide " ] = {
expand: true ,
flatten: false ,
cwd: " modules/ #{ module } /public/coffee/ide " ,
src: [ ' **/*.coffee ' ] ,
dest: " public/js/ide/ #{ module } " ,
ext: ' .js '
}
moduleCompileClientTasks . push " coffee:module_ #{ module } _client_ide "
moduleIdeClientSideIncludes . push " ide/ #{ module } /index "
2014-10-03 10:32:59 +00:00
if fs . existsSync " ./modules/ #{ module } /public/coffee/main/index.coffee "
config . coffee [ " module_ #{ module } _client_main " ] = {
expand: true ,
flatten: false ,
cwd: " modules/ #{ module } /public/coffee/main " ,
src: [ ' **/*.coffee ' ] ,
dest: " public/js/main/ #{ module } " ,
ext: ' .js '
}
moduleCompileClientTasks . push " coffee:module_ #{ module } _client_main "
moduleMainClientSideIncludes . push " main/ #{ module } /index "
2014-09-08 13:19:24 +00:00
grunt . initConfig config
2014-02-12 10:23:40 +00:00
grunt . registerTask ' wrap_sharejs ' , ' Wrap the compiled ShareJS code for AMD module loading ' , () ->
content = fs . readFileSync " public/js/libs/sharejs.js "
fs . writeFileSync " public/js/libs/sharejs.js " , """
2014-07-09 17:20:57 +00:00
define ( [ " ace/ace " ] , function ( ) {
2014-02-12 10:23:40 +00:00
#{content}
return window . sharejs ;
} ) ;
"""
grunt . registerTask ' help ' , ' Display this help list ' , ' availabletasks '
2014-09-08 13:19:24 +00:00
grunt . registerTask ' compile:modules:server ' , ' Compile all the modules ' , moduleCompileServerTasks
grunt . registerTask ' compile:modules:unit_tests ' , ' Compile all the modules unit tests ' , moduleCompileUnitTestTasks
2014-09-08 16:33:30 +00:00
grunt . registerTask ' compile:modules:client ' , ' Compile all the module client side code ' , moduleCompileClientTasks
grunt . registerTask ' compile:modules:inject_clientside_includes ' , () ->
content = fs . readFileSync ( " public/js/ide.js " ) . toString ( )
2014-10-08 11:22:04 +00:00
content = content . replace ( /, "__IDE_CLIENTSIDE_INCLUDES__"/g , moduleIdeClientSideIncludes . map ( (i) -> " , \" #{ i } \" " ) . join ( " " ) )
2014-09-08 16:33:30 +00:00
fs . writeFileSync " public/js/ide.js " , content
2014-10-03 10:32:59 +00:00
content = fs . readFileSync ( " public/js/main.js " ) . toString ( )
2014-10-08 11:22:04 +00:00
content = content . replace ( /, "__MAIN_CLIENTSIDE_INCLUDES__"/g , moduleMainClientSideIncludes . map ( (i) -> " , \" #{ i } \" " ) . join ( " " ) )
2014-10-03 10:32:59 +00:00
fs . writeFileSync " public/js/main.js " , content
2014-09-08 16:33:30 +00:00
2014-09-08 13:19:24 +00:00
grunt . registerTask ' compile:server ' , ' Compile the server side coffee script ' , [ ' clean:app ' , ' coffee:app ' , ' coffee:app_dir ' , ' compile:modules:server ' ]
2014-09-08 16:33:30 +00:00
grunt . registerTask ' compile:client ' , ' Compile the client side coffee script ' , [ ' coffee:client ' , ' coffee:sharejs ' , ' wrap_sharejs ' , " compile:modules:client " , ' compile:modules:inject_clientside_includes ' ]
2014-02-12 10:23:40 +00:00
grunt . registerTask ' compile:css ' , ' Compile the less files to css ' , [ ' less ' ]
2016-07-10 10:04:51 +00:00
grunt . registerTask ' compile:minify ' , ' Concat and minify the client side js ' , [ ' requirejs ' , " file_append " , " exec:cssmin " , ]
2014-02-12 10:23:40 +00:00
grunt . registerTask ' compile:unit_tests ' , ' Compile the unit tests ' , [ ' clean:unit_tests ' , ' coffee:unit_tests ' ]
2016-03-08 15:59:04 +00:00
grunt . registerTask ' compile:acceptance_tests ' , ' Compile the acceptance tests ' , [ ' clean:acceptance_tests ' , ' coffee:acceptance_tests ' ]
2014-02-12 10:23:40 +00:00
grunt . registerTask ' compile:smoke_tests ' , ' Compile the smoke tests ' , [ ' coffee:smoke_tests ' ]
grunt . registerTask ' compile:tests ' , ' Compile all the tests ' , [ ' compile:smoke_tests ' , ' compile:unit_tests ' ]
grunt . registerTask ' compile ' , ' Compiles everything need to run web-sharelatex ' , [ ' compile:server ' , ' compile:client ' , ' compile:css ' ]
2016-06-15 11:08:11 +00:00
grunt . registerTask ' quickcompile:coffee ' , ' Compiles only changed coffee files ' , [ ' newer:coffee ' ]
2014-02-12 10:23:40 +00:00
grunt . registerTask ' install ' , " Compile everything when installing as an npm module " , [ ' compile ' ]
2015-06-16 09:53:18 +00:00
grunt . registerTask ' test:unit ' , ' Run the unit tests (use --grep=<regex> or --feature=<feature> for individual tests) ' , [ ' compile:server ' , ' compile:modules:server ' , ' compile:unit_tests ' , ' compile:modules:unit_tests ' , ' mochaTest:unit ' ] . concat ( moduleUnitTestTasks )
2016-03-08 15:59:04 +00:00
grunt . registerTask ' test:acceptance ' , ' Run the acceptance tests (use --grep=<regex> or --feature=<feature> for individual tests) ' , [ ' compile:acceptance_tests ' , ' mochaTest:acceptance ' ]
2014-02-12 10:23:40 +00:00
grunt . registerTask ' test:smoke ' , ' Run the smoke tests ' , [ ' compile:smoke_tests ' , ' mochaTest:smoke ' ]
2014-09-08 13:19:24 +00:00
grunt . registerTask ' test:modules:unit ' , ' Run the unit tests for the modules ' , [ ' compile:modules:server ' , ' compile:modules:unit_tests ' ] . concat ( moduleUnitTestTasks )
2014-02-12 10:23:40 +00:00
2016-06-15 11:08:11 +00:00
grunt . registerTask ' run ' , " Compile and run the web-sharelatex server " , [ ' compile ' , ' env:run ' , ' parallel ' ]
2014-02-12 10:23:40 +00:00
grunt . registerTask ' default ' , ' run '
2015-03-17 16:59:17 +00:00
grunt . registerTask ' version ' , " Write the version number into sentry.jade " , [ ' git-rev-parse ' , ' sed ' ]
2015-11-18 15:21:48 +00:00
2016-06-15 11:08:11 +00:00
2015-03-19 17:36:50 +00:00
grunt . registerTask ' create-admin-user ' , " Create a user with the given email address and make them an admin. Update in place if the user already exists " , () ->
done = @ async ( )
email = grunt . option ( " email " )
if ! email ?
console . error " Usage: grunt create-admin-user --email joe@example.com "
process . exit ( 1 )
settings = require " settings-sharelatex "
UserRegistrationHandler = require " ./app/js/Features/User/UserRegistrationHandler "
2015-05-26 14:24:09 +00:00
OneTimeTokenHandler = require " ./app/js/Features/Security/OneTimeTokenHandler "
2015-03-19 17:36:50 +00:00
UserRegistrationHandler . registerNewUser {
email: email
password: require ( " crypto " ) . randomBytes ( 32 ) . toString ( " hex " )
} , (error, user) ->
if error ? and error ? . message != " EmailAlreadyRegistered "
throw error
user.isAdmin = true
user . save (error) ->
throw error if error ?
ONE_WEEK = 7 * 24 * 60 * 60 # seconds
2015-05-26 14:24:09 +00:00
OneTimeTokenHandler . getNewToken user . _id , { expiresIn: ONE_WEEK } , (err, token)->
2015-03-19 17:36:50 +00:00
return next ( err ) if err ?
console . log " "
console . log """
Successfully created #{email} as an admin user.
Please visit the following URL to set a password for #{email} and log in:
#{settings.siteUrl}/user/password/set?passwordResetToken=#{token}
"""
2016-06-08 14:36:08 +00:00
done ( )
grunt . registerTask ' delete-user ' , " deletes a user and all their data " , () ->
done = @ async ( )
email = grunt . option ( " email " )
if ! email ?
console . error " Usage: grunt delete-user --email joe@example.com "
process . exit ( 1 )
settings = require " settings-sharelatex "
UserGetter = require " ./app/js/Features/User/UserGetter "
UserDeleter = require " ./app/js/Features/User/UserDeleter "
UserGetter . getUser email : email , (error, user) ->
if error ?
throw error
if ! user ?
console . log ( " user #{ email } not in database, potentially already deleted " )
return done ( )
UserDeleter . deleteUser user . _id , (err)->
if err ?
throw err
done ( )