├── jenkins_ci ├── cookbooks │ ├── libffi │ │ ├── metadata.rb │ │ ├── config │ │ │ └── rpmforge.repo │ │ └── recipes │ │ │ └── default.rb │ ├── jenkins-setup │ │ ├── Berksfile │ │ ├── metadata.rb │ │ ├── templates │ │ │ ├── integration-job.xml.erb │ │ │ └── build-job.xml.erb │ │ ├── recipes │ │ │ └── default.rb │ │ └── files │ │ │ └── credentials.xml │ └── ruby │ │ ├── metadata.rb │ │ └── recipes │ │ └── default.rb ├── metadata.rb ├── roles │ ├── ruby.rb │ ├── jenkins.rb │ └── java.rb ├── Berksfile └── Vagrantfile ├── components ├── users │ ├── src │ │ ├── main │ │ │ ├── scss │ │ │ │ └── test.scss │ │ │ ├── javascript │ │ │ │ ├── config.js │ │ │ │ ├── app.js │ │ │ │ └── messages.js │ │ │ ├── coffeescript │ │ │ │ ├── app.coffee │ │ │ │ └── messages.coffee │ │ │ ├── resources │ │ │ │ └── templates │ │ │ │ │ └── home.html │ │ │ └── java │ │ │ │ └── com.websiteskeleton.users │ │ │ │ ├── UsersUiController.java │ │ │ │ ├── User.java │ │ │ │ └── UsersApiController.java │ │ └── test │ │ │ └── java │ │ │ ├── coffeescript │ │ │ └── karma.conf.coffee │ │ │ └── unit │ │ │ ├── UsersApiControllerTest.java │ │ │ └── UsersUiControllerTest.java │ ├── .gitignore │ ├── config.js │ ├── environment.js │ ├── package.json │ ├── build.gradle │ └── gulpfile.js └── products │ ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── websiteskeleton │ │ │ └── products │ │ │ ├── Product.java │ │ │ └── ProductsController.java │ └── test │ │ └── java │ │ └── unit │ │ └── ProductsControllerTest.java │ └── build.gradle ├── applications └── core │ ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.yml │ │ │ └── application-test.yml │ │ └── java │ │ │ └── com │ │ │ └── websiteskeleton │ │ │ └── core │ │ │ ├── ApplicationConfiguration.java │ │ │ └── Application.java │ └── test │ │ └── java │ │ ├── helpers │ │ ├── AcceptanceTest.java │ │ └── AcceptanceFluentTest.java │ │ ├── UsersApiTest.java │ │ ├── UsersPageTest.java │ │ └── ProductsTest.java │ └── build.gradle ├── .travis.yml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitignore ├── README.md ├── gradlew.bat └── gradlew /jenkins_ci/cookbooks/libffi/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'libffi' 2 | version '0.0.1' -------------------------------------------------------------------------------- /components/users/src/main/scss/test.scss: -------------------------------------------------------------------------------- 1 | .test { 2 | height: 25px; 3 | } -------------------------------------------------------------------------------- /components/users/.gitignore: -------------------------------------------------------------------------------- 1 | src/main/resources/css/* 2 | src/main/resources/js/* 3 | -------------------------------------------------------------------------------- /components/users/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apiUrl: '<% apiUrl %>' 3 | }; 4 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/jenkins-setup/Berksfile: -------------------------------------------------------------------------------- 1 | source "https://supermarket.getchef.com" 2 | 3 | metadata 4 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/ruby/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'ruby' 2 | version '0.0.1' 3 | 4 | depends 'rbenv', '~> 1.7.1' -------------------------------------------------------------------------------- /applications/core/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | some: 2 | yaml: 3 | property: You are using application.yml! -------------------------------------------------------------------------------- /components/users/src/main/javascript/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apiUrl: 'http://localhost:3030' 3 | }; 4 | -------------------------------------------------------------------------------- /applications/core/src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | some: 2 | yaml: 3 | property: You are using application-test.yml! -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/jenkins-setup/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'jenkins-setup' 2 | version '0.0.1' 3 | 4 | depends 'jenkins', '~> 2.2.2' -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | script: 5 | - ./gradlew clean assemble test -Dspring.profiles.active=test 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeanbza/git-java-websiteskeleton/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'websiteskeleton' 2 | 3 | include 'applications/core' 4 | 5 | include 'components/users' 6 | include 'components/products' -------------------------------------------------------------------------------- /jenkins_ci/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'skeleton-ci' 2 | version '0.0.1' 3 | 4 | depends 'libffi', '~> 0.0.1' 5 | depends 'libyaml', '~> 0.1.0' 6 | depends 'java', '~> 1.31.0' -------------------------------------------------------------------------------- /components/users/src/main/coffeescript/app.coffee: -------------------------------------------------------------------------------- 1 | domready = require('domready') 2 | messages = require('./messages.coffee') 3 | 4 | domready -> 5 | messages.sayHi() 6 | -------------------------------------------------------------------------------- /components/users/src/main/coffeescript/messages.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | greeting: "Hello from the script of Coffee, yummy coffee", 3 | sayHi: -> 4 | console.log(@greeting) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.log 3 | *.err 4 | *.lock 5 | .vagrant* 6 | logs 7 | *.pid 8 | *.state 9 | .gradle 10 | build 11 | *.class 12 | .idea 13 | classes* 14 | node_modules 15 | -------------------------------------------------------------------------------- /components/users/src/main/javascript/app.js: -------------------------------------------------------------------------------- 1 | var domready = require("domready"); 2 | var messages = require('./messages'); 3 | 4 | domready(function () { 5 | messages.sayHi(); 6 | }); 7 | -------------------------------------------------------------------------------- /jenkins_ci/roles/ruby.rb: -------------------------------------------------------------------------------- 1 | name 'ruby' 2 | description 'Install Ruby and everything needed for capybara-webkit' 3 | run_list( 4 | 'recipe[yum-epel]', 5 | 'recipe[libyaml]', 6 | 'recipe[libffi]', 7 | 'recipe[ruby]' 8 | ) -------------------------------------------------------------------------------- /jenkins_ci/Berksfile: -------------------------------------------------------------------------------- 1 | source "https://supermarket.getchef.com" 2 | 3 | cookbook 'libffi', :path => 'cookbooks/libffi' 4 | cookbook 'ruby', :path => 'cookbooks/ruby' 5 | cookbook 'jenkins-setup', :path => 'cookbooks/jenkins-setup' 6 | 7 | metadata 8 | -------------------------------------------------------------------------------- /components/users/environment.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dev: { 3 | apiUrl: 'http://localhost:3030', 4 | env: 'dev' 5 | }, 6 | test: { 7 | apiUrl: 'http://localhost:3031', 8 | env: 'test' 9 | } 10 | }; -------------------------------------------------------------------------------- /jenkins_ci/roles/jenkins.rb: -------------------------------------------------------------------------------- 1 | name 'jenkins' 2 | description 'set up jenkins for this project' 3 | default_attributes( 4 | 'jenkins' => { 5 | 'master' => { 6 | 'port' => '9090' 7 | } 8 | } 9 | ) 10 | run_list( 11 | 'recipe[jenkins-setup]' 12 | ) -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Jan 20 08:04:04 MST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip 7 | -------------------------------------------------------------------------------- /components/users/src/main/javascript/messages.js: -------------------------------------------------------------------------------- 1 | var config = require('./config'); 2 | 3 | module.exports = { 4 | greeting: "Hello from the script of JavaScript", 5 | sayHi: function () { 6 | console.log(this.greeting); 7 | console.log("The current apiUrl is " + config.apiUrl); 8 | } 9 | }; -------------------------------------------------------------------------------- /jenkins_ci/roles/java.rb: -------------------------------------------------------------------------------- 1 | name 'java' 2 | description 'Install Oracle Java' 3 | default_attributes( 4 | 'java' => { 5 | 'install_flavor' => 'oracle', 6 | 'jdk_version' => '8', 7 | 'oracle' => { 8 | 'accept_oracle_download_terms' => true 9 | } 10 | } 11 | ) 12 | run_list( 13 | 'recipe[java]' 14 | ) -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/libffi/config/rpmforge.repo: -------------------------------------------------------------------------------- 1 | #Name: RPMforge RPM Repository for Red Hat Enterprise 6 - dag 2 | #URL: http://rpmforge.net/ 3 | [rpmforge] 4 | name = Red Hat Enterprise $releasever - RPMforge.net - dag 5 | mirrorlist = http://apt.sw.be/redhat/el6/en/mirrors-rpmforge 6 | enabled = 1 7 | protect = 0 8 | gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag 9 | gpgcheck = 1 -------------------------------------------------------------------------------- /applications/core/src/test/java/helpers/AcceptanceTest.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import com.websiteskeleton.core.Application; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.*; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | @RunWith(SpringJUnit4ClassRunner.class) 9 | @SpringApplicationConfiguration(classes = Application.class) 10 | @WebIntegrationTest("server.port:0") 11 | public abstract class AcceptanceTest { 12 | } -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/libffi/recipes/default.rb: -------------------------------------------------------------------------------- 1 | rpmforge_path = File.expand_path('../../config/rpmforge.repo', __FILE__) 2 | 3 | file '/etc/yum.repos.d/rpmforge.repo' do 4 | owner 'root' 5 | group 'root' 6 | mode '0600' 7 | action :create 8 | content File.open(rpmforge_path, 'rb').read 9 | end 10 | 11 | execute 'Download the the rpmforge gpg key' do 12 | command 'rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt' 13 | end 14 | 15 | execute 'Install libffi-devel via yum' do 16 | command 'yes | yum install libffi-devel' 17 | end -------------------------------------------------------------------------------- /applications/core/src/test/java/helpers/AcceptanceFluentTest.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import com.websiteskeleton.core.Application; 4 | import org.fluentlenium.adapter.FluentTest; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.*; 7 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 | 9 | @RunWith(SpringJUnit4ClassRunner.class) 10 | @SpringApplicationConfiguration(classes = Application.class) 11 | @WebIntegrationTest("server.port:0") 12 | public abstract class AcceptanceFluentTest extends FluentTest { 13 | } -------------------------------------------------------------------------------- /components/users/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "users", 3 | "version": "1.0.0", 4 | "description": "Users Component", 5 | "dependencies": { 6 | "bootstrap": "^3.3.5", 7 | "domready": "^1.0.8", 8 | "jquery": "^2.1.4" 9 | }, 10 | "devDependencies": { 11 | "browserify": "^11.0.1", 12 | "coffeeify": "^1.1.0", 13 | "gulp": "^3.9.0", 14 | "gulp-concat": "^2.6.0", 15 | "gulp-karma": "0.0.4", 16 | "gulp-replace": "^0.5.4", 17 | "gulp-sass": "^2.0.4", 18 | "karma": "^0.12", 19 | "vinyl-source-stream": "^1.1.0", 20 | "yargs": "^3.24.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /components/users/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 |
10 |

Hello world!

11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /applications/core/src/main/java/com/websiteskeleton/core/ApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.core; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.*; 5 | import org.springframework.web.client.RestTemplate; 6 | 7 | @Configuration 8 | public class ApplicationConfiguration { 9 | @Value("${some.yaml.property}") String someYamlProperty; 10 | 11 | @Bean 12 | public String someYamlProperty() { 13 | return someYamlProperty; 14 | } 15 | 16 | @Bean RestTemplate restTemplate() { 17 | return new RestTemplate(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /applications/core/src/test/java/UsersApiTest.java: -------------------------------------------------------------------------------- 1 | import helpers.AcceptanceTest; 2 | import org.junit.Test; 3 | import org.springframework.beans.factory.annotation.Value; 4 | 5 | import static com.jayway.restassured.RestAssured.get; 6 | import static org.hamcrest.CoreMatchers.equalTo; 7 | 8 | public class UsersApiTest extends AcceptanceTest { 9 | @Value("${local.server.port}") 10 | private int port; 11 | 12 | @Test 13 | public void testGetUsers() { 14 | get("http://127.0.0.1:" + port + "/users") 15 | .then().assertThat().body("get(0).name", equalTo("Bob")) 16 | .and().assertThat().body("get(1).name", equalTo("Sue")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /applications/core/src/main/java/com/websiteskeleton/core/Application.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.core; 2 | 3 | import org.slf4j.*; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.context.annotation.ComponentScan; 7 | 8 | @SpringBootApplication 9 | @ComponentScan(basePackages = "com.websiteskeleton") 10 | public class Application { 11 | private static final Logger logger = LoggerFactory.getLogger(Application.class); 12 | 13 | public static void main(String[] args) { 14 | logger.info("Starting app"); 15 | 16 | SpringApplication.run(Application.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jenkins_ci/Vagrantfile: -------------------------------------------------------------------------------- 1 | # NOTE: Latest version of vagrant has some weird issues when you halt or reload 2 | # Delete .vagrant/machines/default/virtualbox/synced_folders to fix 3 | 4 | VAGRANTFILE_API_VERSION = '2' 5 | 6 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 7 | # Centos 7 box 8 | config.vm.box = 'http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.0_chef-provisionerless.box' 9 | 10 | # Jenkins 11 | config.vm.network 'forwarded_port', guest: 9090, host: 9000 12 | 13 | config.omnibus.chef_version = :latest 14 | config.berkshelf.enabled = true 15 | 16 | config.vm.provision 'chef_solo' do |chef| 17 | chef.roles_path = 'roles' 18 | chef.add_role('ruby') 19 | chef.add_role('java') 20 | chef.add_role('jenkins') 21 | end 22 | end -------------------------------------------------------------------------------- /applications/core/src/test/java/UsersPageTest.java: -------------------------------------------------------------------------------- 1 | import helpers.AcceptanceFluentTest; 2 | import org.junit.Test; 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.test.context.ActiveProfiles; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | @ActiveProfiles("test") 9 | public class UsersPageTest extends AcceptanceFluentTest { 10 | @Value("${local.server.port}") 11 | private int port; 12 | 13 | @Test 14 | public void testGetIndex() { 15 | goTo("http://127.0.0.1:" + port); 16 | assertThat(pageSource()).contains("Hello world!"); 17 | } 18 | 19 | @Test 20 | public void testGetHealth() { 21 | goTo("http://127.0.0.1:" + port + "/health"); 22 | assertThat(pageSource()).contains("OK: You are using application-test.yml!"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/ruby/recipes/default.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'rbenv' 2 | include_recipe 'rbenv::ruby_build' 3 | 4 | ruby_ver = '2.2.0' 5 | 6 | ENV['LD_LIBRARY_PATH'] = '/usr/local/lib' 7 | 8 | # Install qt 9 | yum_package 'qtwebkit-devel.x86_64' 10 | 11 | link '/usr/bin/qmake' do 12 | to '/usr/lib64/qt4/bin/qmake' 13 | end 14 | 15 | # Install ruby 16 | rbenv_ruby ruby_ver 17 | 18 | # Install bundler 19 | rbenv_gem 'bundler' do 20 | ruby_version ruby_ver 21 | end 22 | 23 | execute "set ruby global version to #{ruby_ver}" do 24 | command "rbenv global #{ruby_ver}" 25 | end 26 | 27 | execute 'open up rbenv directory for jenkins to use' do 28 | command 'chmod -R 777 /opt/rbenv' 29 | user 'root' 30 | end 31 | 32 | execute 'add LD_LIBRARY_PATH to vagrant bash profile' do 33 | command "echo 'export LD_LIBRARY_PATH=/usr/local/lib' >> /home/vagrant/.bash_profile" 34 | end -------------------------------------------------------------------------------- /components/users/src/main/java/com.websiteskeleton.users/UsersUiController.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.users; 2 | 3 | import org.springframework.beans.factory.annotation.*; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | @Controller 9 | public class UsersUiController { 10 | private String someYamlProperty; 11 | 12 | @Autowired 13 | public UsersUiController(String someYamlProperty) { 14 | this.someYamlProperty = someYamlProperty; 15 | } 16 | 17 | @RequestMapping(value = "/", method = RequestMethod.GET) 18 | public String getIndex() { 19 | return "home"; 20 | } 21 | 22 | @RequestMapping(value = "/health", produces = MediaType.APPLICATION_JSON_VALUE) 23 | @ResponseBody 24 | public String getHealth() { 25 | return "OK: " + someYamlProperty; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /components/users/src/main/java/com.websiteskeleton.users/User.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.users; 2 | 3 | public class User { 4 | private String name; 5 | 6 | public User(String name) { 7 | this.name = name; 8 | } 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "User{" + 17 | "name='" + name + '\'' + 18 | '}'; 19 | } 20 | 21 | @Override 22 | public boolean equals(Object o) { 23 | if (this == o) 24 | return true; 25 | if (o == null || getClass() != o.getClass()) 26 | return false; 27 | 28 | User user = (User) o; 29 | 30 | return !(name != null ? !name.equals(user.name) : user.name != null); 31 | 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return name != null ? name.hashCode() : 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /components/products/src/main/java/com/websiteskeleton/products/Product.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.products; 2 | 3 | public class Product { 4 | private String name; 5 | 6 | public Product(String name) { 7 | this.name = name; 8 | } 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "Product{" + 17 | "name='" + name + '\'' + 18 | '}'; 19 | } 20 | 21 | @Override 22 | public boolean equals(Object o) { 23 | if (this == o) 24 | return true; 25 | if (o == null || getClass() != o.getClass()) 26 | return false; 27 | 28 | Product product = (Product) o; 29 | 30 | return !(name != null ? !name.equals(product.name) : product.name != null); 31 | 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return name != null ? name.hashCode() : 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /components/products/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | sourceCompatibility = 1.8 4 | targetCompatibility = 1.8 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | compile( 12 | "org.springframework:spring-core:$springVersion", 13 | "org.springframework:spring-web:$springVersion", 14 | "org.springframework:spring-webmvc:$springVersion", 15 | 16 | "org.springframework.boot:spring-boot-starter:$springBootVersion", 17 | "org.springframework.boot:spring-boot-starter-tomcat:$springBootVersion", 18 | 19 | "org.slf4j:slf4j-api:$slf4jVersion", 20 | 'javax.servlet:javax.servlet-api:3.1.0', 21 | 'com.fasterxml.jackson.core:jackson-databind:2.6.1', 22 | 'com.jayway.restassured:rest-assured:2.5.0', 23 | ) 24 | 25 | testCompile( 26 | "org.springframework:spring-test:$springVersion", 27 | 'junit:junit:4.11', 28 | 'org.hamcrest:hamcrest-library:1.3', 29 | 'org.mockito:mockito-core:1.9.5', 30 | ) 31 | } -------------------------------------------------------------------------------- /components/users/src/test/java/coffeescript/karma.conf.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (config) -> 2 | config.set 3 | reporters: ['dots'] 4 | 5 | preprocessors: 6 | '**/*.coffee': ['coffee'] 7 | 8 | autoWatch: true 9 | basePath: '../' 10 | frameworks: ['jasmine'] 11 | exclude: [] 12 | port: 8080 13 | 14 | # Start these browsers, currently available: 15 | # - Chrome 16 | # - ChromeCanary 17 | # - Firefox 18 | # - Opera 19 | # - Safari (only Mac) 20 | # - PhantomJS 21 | # - IE (only Windows) 22 | browsers: [ 23 | 'PhantomJS' 24 | ] 25 | 26 | # Which plugins to enable 27 | plugins: [ 28 | 'karma-coffee-preprocessor', 29 | 'karma-phantomjs-launcher', 30 | 'karma-jasmine', 31 | 'karma-spec-reporter' 32 | ] 33 | 34 | # Continuous Integration mode 35 | # if true, it capture browsers, run tests and exit 36 | # singleRun: true, 37 | colors: true 38 | 39 | # level of logging 40 | # possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 41 | logLevel: config.LOG_INFO -------------------------------------------------------------------------------- /components/users/src/main/java/com.websiteskeleton.users/UsersApiController.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.users; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import java.util.List; 11 | 12 | import static java.util.Arrays.asList; 13 | 14 | @Controller 15 | public class UsersApiController { 16 | private ObjectMapper objectMapper; 17 | 18 | @Autowired 19 | public UsersApiController(ObjectMapper objectMapper) { 20 | this.objectMapper = objectMapper; 21 | } 22 | 23 | @RequestMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE) 24 | @ResponseBody 25 | public String getUsers() throws JsonProcessingException { 26 | List users = asList( 27 | new User("Bob"), 28 | new User("Sue") 29 | ); 30 | 31 | return objectMapper.writeValueAsString(users); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/jenkins-setup/templates/integration-job.xml.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | true 10 | false 11 | false 12 | false 13 | 14 | false 15 | /var/lib/jenkins/jobs/<%= @app_name %>ProviderBuild/workspace 16 | 17 | 18 | cp /var/lib/jenkins/jobs/<%= @app_name %>Build/workspace/applications/core/build/libs/applications/core.war /opt/jetty/webapps/core.war 19 | /opt/jetty/bin/jetty.sh restart 20 | echo 'Waiting for jetty to reboot..' 21 | sleep 5 22 | cd /var/lib/jenkins/jobs/<%= @app_name %>Build/workspace/integration_tests && bundle && rspec 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/jenkins-setup/recipes/default.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'jenkins::master' 2 | 3 | jenkins_plugin 'git' 4 | jenkins_plugin 'gradle' 5 | 6 | cookbook_file 'credentials.xml' do 7 | owner 'jenkins' 8 | group 'jenkins' 9 | mode '0644' 10 | path '/var/lib/jenkins/credentials.xml' 11 | end 12 | 13 | def create_test_jobs(app_name, git_repo) 14 | build_job = File.join(Chef::Config[:file_cache_path], "#{app_name}-build-job.xml") 15 | 16 | # PLEASE NOTE: You WILL need to set up your own credentials 17 | template build_job do 18 | source 'build-job.xml.erb' 19 | variables({:git_repo => git_repo}) 20 | end 21 | 22 | jenkins_job "#{app_name}Build" do 23 | config build_job 24 | end 25 | 26 | integration_job = File.join(Chef::Config[:file_cache_path], "#{app_name}-build-job.xml") 27 | 28 | template integration_job do 29 | source 'integration-job.xml.erb' 30 | variables({:app_name => app_name}) 31 | end 32 | 33 | jenkins_job "#{app_name}IntegrationTests" do 34 | config integration_job 35 | end 36 | end 37 | 38 | create_test_jobs('Skeleton', 'https://github.com/jadekler/git-spring-websiteskeleton.git') -------------------------------------------------------------------------------- /components/users/src/test/java/unit/UsersApiControllerTest.java: -------------------------------------------------------------------------------- 1 | package unit; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.websiteskeleton.users.UsersApiController; 5 | import org.junit.*; 6 | import org.springframework.test.web.servlet.MockMvc; 7 | 8 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 9 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 10 | import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; 11 | 12 | public class UsersApiControllerTest { 13 | private MockMvc mockMvc; 14 | 15 | @Before 16 | public void setup() throws Exception { 17 | UsersApiController controller = new UsersApiController(new ObjectMapper()); 18 | mockMvc = standaloneSetup(controller).build(); 19 | } 20 | 21 | @Test 22 | public void testGetUsers() throws Exception { 23 | String sampleJson = "[" + 24 | "{\"name\":\"Bob\"}," + 25 | "{\"name\":\"Sue\"}" + 26 | "]"; 27 | 28 | mockMvc.perform(get("/users")) 29 | .andExpect(status().isOk()) 30 | .andExpect(content().string(sampleJson)) 31 | .andExpect(header().string("content-type", "application/json")); 32 | } 33 | } -------------------------------------------------------------------------------- /components/users/src/test/java/unit/UsersUiControllerTest.java: -------------------------------------------------------------------------------- 1 | package unit; 2 | 3 | import com.websiteskeleton.users.UsersUiController; 4 | import org.junit.*; 5 | import org.mockito.InjectMocks; 6 | import org.springframework.test.web.servlet.MockMvc; 7 | 8 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 9 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 10 | import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; 11 | 12 | public class UsersUiControllerTest { 13 | @InjectMocks UsersUiController controller; 14 | 15 | private MockMvc mockMvc; 16 | 17 | @Before 18 | public void setup() throws Exception { 19 | controller = new UsersUiController("foo bar"); 20 | mockMvc = standaloneSetup(controller).build(); 21 | } 22 | 23 | @Test 24 | public void testGetIndex() throws Exception { 25 | mockMvc.perform(get("/")) 26 | .andExpect(status().isOk()) 27 | .andExpect(view().name("home")); 28 | } 29 | 30 | @Test 31 | public void testGetHealth() throws Exception { 32 | mockMvc.perform(get("/health")) 33 | .andExpect(status().isOk()) 34 | .andExpect(content().string("OK: foo bar")) 35 | .andExpect(header().string("content-type", "application/json")); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /components/users/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'gulp' 3 | 4 | sourceCompatibility = 1.8 5 | targetCompatibility = 1.8 6 | 7 | buildscript { 8 | repositories { 9 | jcenter() 10 | } 11 | dependencies { 12 | classpath 'be.filipblondeel.gradle:gradle-gulp-plugin:0.1' 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | compile( 22 | "org.springframework:spring-core:$springVersion", 23 | "org.springframework:spring-web:$springVersion", 24 | "org.springframework:spring-webmvc:$springVersion", 25 | 26 | "org.springframework.boot:spring-boot-starter:$springBootVersion", 27 | "org.springframework.boot:spring-boot-starter-tomcat:$springBootVersion", 28 | "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion", 29 | 30 | "org.slf4j:slf4j-api:$slf4jVersion", 31 | 'javax.servlet:javax.servlet-api:3.1.0', 32 | 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b01', 33 | 'com.fasterxml.jackson.core:jackson-databind:2.6.1', 34 | ) 35 | 36 | testCompile ( 37 | "org.springframework:spring-test:$springVersion", 38 | 'junit:junit:4.11', 39 | 'org.hamcrest:hamcrest-library:1.3', 40 | 'org.mockito:mockito-core:1.9.5', 41 | ) 42 | } 43 | 44 | gulp_build.dependsOn installGulp 45 | gulp_build.dependsOn npmInstall 46 | 47 | assemble.dependsOn gulp_build 48 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/jenkins-setup/files/credentials.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | GLOBAL 11 | aaaaaaaa-bbbb-cccc-ddd-eeeeeeeeeeee 12 | The credentials that are associated with my github repo 13 | ci ssh key 14 | abcdefghijklmnopqrstuvwx 15 | 16 | 17 | put your private ssh key here 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /components/products/src/main/java/com/websiteskeleton/products/ProductsController.java: -------------------------------------------------------------------------------- 1 | package com.websiteskeleton.products; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.*; 9 | import org.springframework.web.client.*; 10 | 11 | import java.util.*; 12 | 13 | import static java.util.Arrays.asList; 14 | 15 | @Controller 16 | public class ProductsController { 17 | private final ObjectMapper objectMapper; 18 | private final RestTemplate restTemplate; 19 | 20 | @Autowired 21 | public ProductsController(RestTemplate restTemplate, ObjectMapper objectMapper) { 22 | this.restTemplate = restTemplate; 23 | this.objectMapper = objectMapper; 24 | } 25 | 26 | @RequestMapping(value = "/products", produces = MediaType.APPLICATION_JSON_VALUE) 27 | @ResponseBody 28 | public String getProducts() throws JsonProcessingException { 29 | List products = new ArrayList<>(); 30 | products.addAll(asList(new Product("Super Glue"), new Product("Kool-Aide"))); 31 | Optional externalProduct = Optional.empty(); 32 | 33 | try { 34 | String externalProductString = restTemplate.getForObject("http://localhost:6789/external-product", String.class); 35 | externalProduct = Optional.of(new Product(externalProductString)); 36 | } catch (RestClientException e) { 37 | // server is down - ignore 38 | } 39 | 40 | externalProduct.ifPresent(products::add); 41 | 42 | return objectMapper.writeValueAsString(products); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /applications/core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'spring-boot' 3 | 4 | sourceCompatibility = 1.8 5 | targetCompatibility = 1.8 6 | 7 | buildscript { 8 | repositories { 9 | mavenCentral() 10 | } 11 | dependencies { 12 | classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE' 13 | } 14 | } 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | String seleniumVersion = '2.47.1' 21 | String fluentleniumVersion = '0.10.3' 22 | 23 | dependencies { 24 | compile( 25 | project(':components/users'), 26 | project(':components/products'), 27 | 28 | "org.springframework:spring-context:$springVersion", 29 | "org.springframework:spring-core:$springVersion", 30 | "org.springframework:spring-web:$springVersion", 31 | "org.springframework:spring-webmvc:$springVersion", 32 | 33 | "org.springframework.boot:spring-boot-starter:$springBootVersion", 34 | "org.springframework.boot:spring-boot-starter-tomcat:$springBootVersion", 35 | 36 | 'javax.servlet:javax.servlet-api:3.1.0', 37 | ) 38 | 39 | testCompile( 40 | "org.springframework:spring-test:$springVersion", 41 | 42 | 'junit:junit:4.11', 43 | 44 | "com.jayway.restassured:rest-assured:$restAssuredVersion", 45 | "com.jayway.restassured:json-schema-validator:$restAssuredVersion", 46 | 47 | "org.mock-server:mockserver-integration-testing:$mockserverVersion", 48 | "org.mock-server:mockserver-netty:$mockserverVersion", 49 | 50 | "org.seleniumhq.selenium:selenium-java:$seleniumVersion", 51 | "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion", 52 | 53 | "org.fluentlenium:fluentlenium-core:$fluentleniumVersion", 54 | "org.fluentlenium:fluentlenium-assertj:$fluentleniumVersion", 55 | ) 56 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # git-spring-websiteskeleton 2 | 3 | [![Build Status](https://travis-ci.org/jadekler/git-java-websiteskeleton.svg?branch=master)](https://travis-ci.org/jadekler/git-java-websiteskeleton) 4 | 5 | -- 6 | 7 | A website skeleton written with JDK1.8, Spring 4.2 (spring-boot and spring-framework), multi-component Gradle, thymeleaf, 8 | JUnit tests, and FluentLenium+Rest-Assured acceptance tests. 9 | 10 | -- 11 | 12 | ## Installation and running 13 | 14 | 1. `brew install node` 15 | 1. [Download and install JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) 16 | 1. `git clone https://github.com/jadekler/git-spring-websiteskeleton.git`. I'll assume you cloned this at 17 | `~/workspace/git-spring-websiteskeleton` 18 | 1. `cd ~/workspace/git-spring-websiteskeleton` 19 | 1. `./gradlew bootRun` 20 | 1. Navigate to `http://localhost:8080` 21 | 22 | NOTE: The `applications/core` master component is where all components with `components` get compiled into one final 23 | application - note the project compiles happening at `applications/core/build.gradle`. 24 | 25 | ## Running tests 26 | 27 | `./gradlew clean test` 28 | 29 | ## Setting up Jenkins CI (with vagrant, virtualbox, chef) 30 | 31 | 1. [Install chef-dk](https://downloads.chef.io/chef-dk/) 32 | 1. [Install vagrant](http://www.vagrantup.com/downloads.html) 33 | 1. [Install virtualbox](https://www.virtualbox.org/wiki/Downloads) 34 | - Note: if you get an error about `vboxsf`, [download Virtualbox 4.3.20 here](https://www.virtualbox.org/wiki/Download_Old_Builds_4_3) 35 | 1. `vagrant plugin install vagrant-berkshelf` 36 | 1. `vagrant plugin install vagrant-omnibus` 37 | 1. `vagrant plugin install vagrant-vbguest` (possibly optional - install this if you see `Failed to mount folders in Linux guest.`) 38 | 1. `cd ~/workspace/git-spring-websiteskeleton/jenkins_ci && vagrant up --provision` 39 | 40 | ## Additional notes 41 | 42 | - The java chef downloads from oracle (sigh). If your connection is slow or spotty, it may fail on a curl command. Give it 43 | a couple of shots (`vagrant provision` will do it) until the curl successfully completes 44 | -------------------------------------------------------------------------------- /applications/core/src/test/java/ProductsTest.java: -------------------------------------------------------------------------------- 1 | import helpers.AcceptanceTest; 2 | import org.junit.*; 3 | import org.mockserver.client.server.MockServerClient; 4 | import org.mockserver.verify.VerificationTimes; 5 | import org.springframework.beans.factory.annotation.Value; 6 | 7 | import static com.jayway.restassured.RestAssured.get; 8 | import static org.hamcrest.CoreMatchers.equalTo; 9 | import static org.mockserver.integration.ClientAndServer.startClientAndServer; 10 | import static org.mockserver.model.HttpRequest.request; 11 | import static org.mockserver.model.HttpResponse.response; 12 | 13 | public class ProductsTest extends AcceptanceTest { 14 | @Value("${local.server.port}") 15 | private int port; 16 | 17 | private MockServerClient mockServer; 18 | 19 | @Before 20 | public void setup() { 21 | mockServer = startClientAndServer(6789); 22 | } 23 | 24 | @After 25 | public void teardown() { 26 | mockServer.stop(); 27 | } 28 | 29 | @Test 30 | public void testGetProducts() { 31 | mockServer 32 | .when(request().withMethod("GET").withPath("/external-product")) 33 | .respond(response().withStatusCode(200).withBody("Some External Product")); 34 | 35 | get("http://127.0.0.1:" + port + "/products") 36 | .then().assertThat().body("size()", equalTo(3)) 37 | .and().assertThat().body("get(0).name", equalTo("Super Glue")) 38 | .and().assertThat().body("get(1).name", equalTo("Kool-Aide")) 39 | .and().assertThat().body("get(2).name", equalTo("Some External Product")); 40 | 41 | mockServer.verify(request().withMethod("GET") 42 | .withPath("/external-product"), 43 | VerificationTimes.exactly(1)); 44 | } 45 | 46 | @Test 47 | public void testGetProducts_ExternalServerNotFound() { 48 | mockServer 49 | .when(request().withMethod("GET").withPath("/external-product")) 50 | .respond(response().withStatusCode(404)); 51 | 52 | get("http://127.0.0.1:" + port + "/products") 53 | .then().assertThat().body("size()", equalTo(2)) 54 | .and().assertThat().body("get(0).name", equalTo("Super Glue")) 55 | .and().assertThat().body("get(1).name", equalTo("Kool-Aide")); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /components/products/src/test/java/unit/ProductsControllerTest.java: -------------------------------------------------------------------------------- 1 | package unit; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.websiteskeleton.products.ProductsController; 5 | import org.junit.*; 6 | import org.mockito.*; 7 | import org.springframework.test.web.servlet.MockMvc; 8 | import org.springframework.web.client.*; 9 | 10 | import static org.mockito.Matchers.*; 11 | import static org.mockito.Mockito.doReturn; 12 | import static org.mockito.Mockito.doThrow; 13 | import static org.mockito.MockitoAnnotations.initMocks; 14 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 15 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 16 | import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; 17 | 18 | public class ProductsControllerTest { 19 | @InjectMocks ProductsController controller; 20 | 21 | @Mock RestTemplate restTemplate; 22 | 23 | private MockMvc mockMvc; 24 | 25 | @Before 26 | public void setup() throws Exception { 27 | initMocks(this); 28 | 29 | controller = new ProductsController(restTemplate, new ObjectMapper()); 30 | mockMvc = standaloneSetup(controller).build(); 31 | } 32 | 33 | @Test 34 | public void testGetProducts() throws Exception { 35 | doReturn("Some External Product").when(restTemplate).getForObject(anyString(), eq(String.class)); 36 | 37 | String expectedJson = "[" + 38 | "{\"name\":\"Super Glue\"}," + 39 | "{\"name\":\"Kool-Aide\"}," + 40 | "{\"name\":\"Some External Product\"}" + 41 | "]"; 42 | 43 | mockMvc.perform(get("/products")) 44 | .andExpect(status().isOk()) 45 | .andExpect(content().string(expectedJson)) 46 | .andExpect(header().string("content-type", "application/json")); 47 | } 48 | 49 | @Test 50 | public void testGetProducts_ExternalServerNotFound() throws Exception { 51 | doThrow(new RestClientException("server unavailable")).when(restTemplate).getForObject(anyString(), eq(String.class)); 52 | 53 | String expectedJson = "[" + 54 | "{\"name\":\"Super Glue\"}," + 55 | "{\"name\":\"Kool-Aide\"}" + 56 | "]"; 57 | 58 | mockMvc.perform(get("/products")) 59 | .andExpect(status().isOk()) 60 | .andExpect(content().string(expectedJson)) 61 | .andExpect(header().string("content-type", "application/json")); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /jenkins_ci/cookbooks/jenkins-setup/templates/build-job.xml.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 2 10 | 11 | 12 | <%= @git_repo %> 13 | aaaaaaaa-bbbb-cccc-ddd-eeeeeeeeeeee 14 | 15 | 16 | 17 | 18 | */master 19 | 20 | 21 | false 22 | 23 | 24 | 25 | true 26 | false 27 | true 28 | false 29 | 30 | 31 | * * * * * 32 | false 33 | 34 | 35 | false 36 | 37 | 38 | 39 | 40 | clean build 41 | 42 | 43 | (Default) 44 | true 45 | false 46 | true 47 | false 48 | 49 | 50 | 51 | 52 | 53 | SUCCESS 54 | 0 55 | BLUE 56 | true 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /components/users/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Gulp Dependencies 4 | var gulp = require('gulp'); 5 | var sass = require('gulp-sass'); 6 | var concat = require('gulp-concat'); 7 | var replace = require('gulp-replace'); 8 | var karma = require('gulp-karma'); 9 | 10 | var browserify = require('browserify'); 11 | var source = require('vinyl-source-stream'); 12 | 13 | 14 | // Other Dependencies 15 | var yargs = require('yargs').argv; 16 | 17 | // Environment Setup 18 | var ENVS = require('./environment'); 19 | var env = ENVS.dev; 20 | var passedArg = 'dev'; 21 | var buildDir = "./src/main/resources/META-INF/resources"; 22 | 23 | /* SCSS*/ 24 | gulp.task('scss', function () { 25 | gulp.src('./src/main/scss/**/*.scss') 26 | .pipe(sass().on('error', function (err) { 27 | console.error(err); 28 | })) 29 | .pipe(concat('app.css')) 30 | .pipe(gulp.dest(buildDir + '/css/')); 31 | }); 32 | 33 | /* JavaScript */ 34 | gulp.task('browserify:js', ['config'], function () { 35 | return browserify('./src/main/javascript/app.js').bundle() 36 | // vinyl-source-stream makes the bundle compatible with gulp 37 | .pipe(source('app.js')) 38 | .pipe(gulp.dest(buildDir + '/js/')); 39 | }); 40 | /* CoffeeScript */ 41 | gulp.task('browserify:coffee', function () { 42 | return browserify('./src/main/coffeescript/app.coffee').transform('coffeeify').bundle() 43 | // vinyl-source-stream makes the bundle compatible with gulp 44 | .pipe(source('app.coffee.js')) 45 | .pipe(gulp.dest(buildDir + '/js/')); 46 | }); 47 | gulp.task('browserify', ['browserify:js', 'browserify:coffee']); 48 | 49 | // Vendor node components with artifacts 50 | gulp.task('vendor:javascript', function () { 51 | gulp.src([ 52 | './node_modules/jquery/dist/jquery.min.js', 53 | './node_modules/bootstrap/dist/js/bootstrap.min.js' 54 | ]).pipe(concat('vendor.js')) 55 | .pipe(gulp.dest(buildDir + '/js/')) 56 | }); 57 | gulp.task('vendor:styles', function () { 58 | gulp.src([ 59 | './node_modules/bootstrap/dist/css/bootstrap.min.css', 60 | './node_modules/bootstrap/dist/css/bootstrap-theme.min.css' 61 | ]).pipe(concat('vendor.css')) 62 | .pipe(gulp.dest(buildDir + '/css/')) 63 | }); 64 | gulp.task('vendor', ['vendor:javascript', 'vendor:styles']); 65 | 66 | /* Environment based config */ 67 | gulp.task('config', ['environment'], function () { 68 | gulp.src('./config.js') 69 | .pipe(replace('<% apiUrl %>', env.apiUrl)) 70 | .pipe(gulp.dest('./src/main/javascript')); 71 | }); 72 | 73 | /* Environment Tasks */ 74 | gulp.task('environment', function () { 75 | if (yargs.env !== undefined && ENVS[yargs.env] !== undefined) { 76 | env = ENVS[yargs.env]; 77 | passedArg = yargs.env; 78 | } 79 | }); 80 | 81 | /* Testing Tasks */ 82 | gulp.task('karma', ['build'], function (done) { 83 | var files = [ 84 | //TODO: figure this out 85 | ]; 86 | if (yargs.f !== undefined) { 87 | files.push(yargs.f); 88 | } else { 89 | files.push('./src/test/coffeescript/**/*.coffee'); 90 | } 91 | gulp.src(files).pipe(karma({ 92 | files: files, 93 | configFile: __dirname + '/spec/karma.conf.coffee', 94 | singleRun: true 95 | })).on('error', function (err) { 96 | process.exit(1); 97 | }); 98 | }); 99 | 100 | gulp.task('karma:run', ['reset'], function () { 101 | gulp.start('karma'); 102 | }); 103 | 104 | gulp.task('test', function () { 105 | yargs.env = 'test'; 106 | gulp.start('karma:run'); 107 | }); 108 | 109 | /* Default Tasks */ 110 | gulp.task('build', ['environment', 'config', 'scss', 'vendor', 'browserify']); 111 | gulp.task('default', ['build']); -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | --------------------------------------------------------------------------------