require 'p4util/tasks' require 'rake/clean' P4Util::Tasks.new do |p4util| p4util.basename = 'api_' p4util.version = 'r14.2' p4util.p4_init_dir = 'p4_web_api/clients/ruby/p4_web_api_client/spec/init.base' end P4Util::Tasks.new do |p4util| p4util.basename = 'proj_' p4util.version = 'r14.2' p4util.p4_init_dir = 'p4_project_services/clients/ruby/p4_project_services_client/spec/init' end desc 'Create a new config.ru in the work/ directory for launching the web apps' task 'work/config.ru' do Dir.mkdir('work') unless Dir.exist?('work') File.open('work/config.ru', 'w') do |f| f.puts <<-END.gsub(/^[ ]{4}/, '') # Avoid any environmental status pollution from your dev environment ENV.keys.select { |k| k =~ /^P4/ }.each { |k| ENV.delete(k) } require 'sequel' DB = Sequel.connect('postgres://localhost:5432/p4_project_services') require 'p4_web_api' api = P4WebAPI::App.new api.settings.p4 = { 'port' => 'localhost:1666', 'charset' => 'auto' } api.settings.token_path = '#{File.absolute_path('work/tokens')}' api.settings.workspace_folder = '#{File.absolute_path('work/workspaces')}' require 'p4_project_services' proj = P4ProjectServices::App.new proj.settings.p4 = { 'port' => 'localhost:1666', 'charset' => 'auto' } proj.settings.token_path = '#{File.absolute_path('work/tokens')}' proj.settings.p4_web_api_url = 'http://localhost:4567' proj.settings.p4_web_api_prefix = '/p4_web_api/v1' require 'p4_phoenix_services' phx = P4PhoenixServices::App.new phx.settings.p4 = { 'port' => 'localhost:1666', 'charset' => 'auto' } phx.settings.token_path = '#{File.absolute_path('work/tokens')}' phx.settings.p4_project_services_url = 'http://localhost:4567' phx.settings.p4_project_services_prefix = '/p4_project_services/v1' phx.settings.p4_web_api_url = 'http://localhost:4567' phx.settings.p4_web_api_prefix = '/p4_web_api/v1' phx.settings.phoenix_updater_url = 'ws://localhost:4568' require 'notification_services' notification = NotificationServices::App.new notification.settings.p4 = { 'port' => 'localhost:1666', 'charset' => 'auto' } notification.settings.token_path = '#{File.absolute_path('work/tokens')}' notification.settings.p4_web_api_url = 'http://localhost:4567' notification.settings.p4_web_api_prefix = '/p4_web_api/v1' notification.settings.p4_notification_services_url = 'http://localhost:4567' notification.settings.p4_notification_services_prefix = '/p4_notification_services/v1' run Rack::URLMap.new( '/p4_web_api' => api, '/p4_project_services' => proj, '/p4_phoenix_services' => phx, '/p4_notification_services' => notification ) END end end desc 'Create the Unicorn config for testing' task 'work/unicorn.rb' do Dir.mkdir('work') unless Dir.exist?('work') File.open('work/unicorn.rb', 'w') do |f| f.puts <<-END.gsub(/^[ ]{6}/, '') pid '#{File.absolute_path('work/unicorn.pid')}' listen 4567 worker_processes 6 END end end namespace :services do desc 'Start p4_web_services unicorn instance (in background)' task :start => ['work/unicorn.rb', 'work/config.ru'] do pid = Process.spawn('bundle exec unicorn -c work/unicorn.rb work/config.ru') Process.detach(pid) File.open('work/p4_web_services.pid', 'w') do |f| f.puts(pid) end retries = 10 while !system('curl http://localhost:4567/') do sleep(0.25) retries -= 1 end system('curl http://localhost:4567') or fail 'did not start services' end desc 'Kills the spawned p4_web_services process (via the PID file)' task :stop do if File.exist?('work/unicorn.pid') pid = IO.read('work/unicorn.pid').to_i Process.kill('TERM', pid) end end end namespace :updater do desc 'Create phoenix_updater start configuration' task :config do Dir.mkdir('work') unless Dir.exist?('work') File.open('work/phoenix_updater', 'w') do |f| f.puts <<-END.gsub(/^[ ]{8}/, '') #!/usr/bin/env ruby require 'phoenix_updater' PhoenixUpdater::Server.start( host: '0.0.0.0', port: 4568 ) END end File.chmod(0755, 'work/phoenix_updater') end desc 'Start phoenix_updater WebSocket service' task :start => :config do pid = Process.spawn('bundle exec work/phoenix_updater') Process.detach(pid) File.open('work/phoenix_updater.pid', 'w') do |f| f.puts(pid) end # TODO handshake to ensure this has started... end desc 'Stop phoenix_updater WebSocket service' task :stop do if File.exist?('work/phoenix_updater.pid') pid = IO.read('work/phoenix_updater.pid').to_i Process.kill('TERM', pid) end end end namespace :nginx do desc 'Creates the nginx config in work/' task :config do Dir.mkdir('work') unless Dir.exist?('work') File.open('work/nginx.conf', 'w') do |f| f.puts <<-END.gsub(/^[ ]{8}/, '') pid #{File.absolute_path('work/nginx.pid')}; error_log #{File.absolute_path('work/nginx.errors.log')}; worker_processes 10; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] $status ' '"$request" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log #{File.absolute_path('work/nginx.access.log')} main; map $http_upgrade $connection_upgrade { default Upgrade; '' close; } upstream websocket { server 127.0.0.1:4568; } server { listen 8080; location /p4_phoenix_services/v1/updater { proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 999999999; rewrite /p4_phoenix_services/v1/updater/(.*) /$1 break; proxy_redirect off; } location / { proxy_pass $scheme://127.0.0.1:4567; } } } END end end desc 'Start nginx locally' task :start => :config do sh "nginx -c #{File.absolute_path('work/nginx.conf')}" or fail 'nginx failed' end desc 'Stop local nginx' task :stop do if File.exist?('work/nginx.pid') pid = IO.read('work/nginx.pid').to_i Process.kill('TERM', pid) end end end namespace :db do desc 'Create a new PostgreSQL configuration for local development usage' task :init do unless Dir.exist?('work/pgdata') FileUtils.mkdir_p('work/pgdata') sh 'initdb -D work/pgdata' or fail 'initdb failed' end end desc 'Start postgres server with data hosted locally (only suitable for development)' task :start => :init do pgdata_dir = File.absolute_path('work/pgdata') sh "pg_ctl -D #{pgdata_dir} start -w" or fail "pg_ctl start failed" end desc 'Create local databases (p4_project_services)' task :create do sh 'createdb p4_project_services' or fail 'createdb failed for p4_project_services' sh 'createdb notification_services' or fail 'createdb failed for notification_services' sh 'createdb p4_phoenix_services' or fail 'createdb failed for p4_phoenix_services' end desc 'Shutdown the postgres server using fast shutdown mode' task :stop do begin sh 'pg_ctl -D work/pgdata stop -m fast -w' rescue puts 'pg_ctl stop failed, not sure why, ignoring and moving on' end end desc 'Stop and remove the temporary postgres data directory' task :clean => :stop do if Dir.exist?('work/pgdata') FileUtils.rmtree('work/pgdata') end end desc 'Run migrations' task :migrate do |t, args| require 'sequel' Sequel.extension :migration puts 'Migrating p4_project_services to latest' url = 'postgres://postgres:rein4ce@192.168.99.100:5432/p4_project_services' db = Sequel.connect(url) Sequel::Migrator.run(db, 'p4_project_services/p4_project_services/migrations') puts 'Migrating notification_services to latest' url = 'postgres://postgres:rein4ce@192.168.99.100:5432/notification_services' db = Sequel.connect(url) Sequel::Migrator.run(db, 'notification_services/notification_services/migrations') puts 'Migrating p4_phoenix_services to latest' url = 'postgres://postgres:rein4ce@192.168.99.100:5432/p4_phoenix_services' db = Sequel.connect(url) Sequel::Migrator.run(db, 'p4_phoenix_services/p4_phoenix_services/migrations') end end begin require 'ci/reporter/rake/rspec' require 'rspec/core/rake_task' ENV['CI_REPORTS'] = 'spec-output' CLEAN.include('spec-output', 'coverage') RSpec::Core::RakeTask.new(:api_spec) do |t| t.pattern = 'p4_web_api/clients/ruby/p4_web_api_client/spec/*.rb' t.ruby_opts = ["-I#{File.absolute_path('p4_web_api/clients/ruby/p4_web_api_client/spec/lib')}"] end task api_spec: 'ci:setup:rspec' RSpec::Core::RakeTask.new(:proj_spec) do |t| t.pattern = 'p4_project_services/clients/ruby/p4_project_services_client/spec/*.rb' t.ruby_opts = ["-I#{File.absolute_path('p4_project_services/clients/ruby/p4_project_services_client/spec/lib')}"] end task proj_spec: 'ci:setup:rspec' RSpec::Core::RakeTask.new(:proj_svc_spec) do |t| t.pattern = 'p4_project_services/p4_project_services/spec/*.rb' end task proj_svc_spec: 'ci:setup:rspec' rescue LoadError # no rspec available end desc 'Rebuild native tools in qt/work directory (please set CMAKE_PREFIX_PATH in environment)' task :qt_build do FileUtils.rmtree('qt/work') if Dir.exist?('qt/work') FileUtils.mkdir('qt/work') system('cd qt/work && cmake .. && make') or fail('qt build failed') end CLEAN.include('qt/work') desc 'Run all qt tests' task :qt_test do system('cd qt/work/p4_phoenix_services_client && ./PhoenixIntegrationTests') or fail('PhoenixIntegrationTests failed') end desc 'Build all gems and copy them to our top-level pkg/ directory' task :build do system('cd p4_web_services_auth && rake build') or fail 'rake gem failed for p4_web_services_auth' system('cd p4_web_api/p4_web_api && rake package') or fail 'rake package failed for p4_web_api' system('cd p4_web_api/clients/ruby/p4_web_api_client && rake build') or fail 'rake build failed for p4_web_api_client' system('cd p4_project_services/p4_project_services_data && rake build') or fail 'rake build failed for p4_project_services_data' system('cd p4_project_services/p4_project_services && rake build') or fail 'rake build failed for p4_project_services' system('cd p4_project_services/clients/ruby/p4_project_services_client && rake build') or fail 'rake build failed for p4_project_services_client' system('cd p4_phoenix_services/p4_phoenix_services && rake build') or fail 'rake build failed for p4_phoenix_services' if Dir.exist?('build') `chmod -R +w build` end Dir.mkdir('build') unless Dir.exist?('build') Dir.mkdir('build/gem') unless Dir.exist?('build/gem') Dir.glob('**/pkg/*.gem').each do |f| FileUtils.copy(f, "build/gem/#{File.basename(f)}") end ['qt/p4_project_services_client', 'qt/p4_phoenix_services_client'].each do |project| project_name = File.basename(project) puts "Preparing project #{project_name} from #{project}" Dir.glob("#{project}/**/*").each do |file| relative_path = file[(project.length+1)..-1] if File.file?(file) FileUtils.mkdir_p("build/#{project_name}/#{File.dirname(relative_path)}") changelist=`p4 changes -m1 '//web-services/p4ws-main/...#have' | awk '{print $2}'`.strip contents = nil File.open(file, 'rb') do |f| contents = f.read.gsub('DEV', changelist) end File.open("build/#{project_name}/#{relative_path}", 'wb') do |f| f.write(contents) end end end end Dir.glob('') end CLEAN.include('**/pkg') desc 'Create doc directory from docbook files (requires ant)' directory 'build/doc' => 'docbook' do FileUtils.rmtree('build/doc') if Dir.exist?('build/doc') sh 'cd docbook && ant publicsite -Ddoc.build.path=../tools/p4-doc/manuals/_build && cd ..' end CLEAN.include('build/doc') require 'sequel' # This use of Rake by Resque, I do not care for. DB = Sequel.connect('postgres://localhost:4567/notification_services') require 'notification_services/workers/webhook_notifier' require 'resque/tasks' namespace :redis do desc 'Start a local redis-server in work/redis' task :start do FileUtils.mkdir_p('work/redis') unless Dir.exist?('work/redis') pid = Process.spawn('redis-server') Process.detach(pid) IO.write('work/redis.pid', pid.to_s) end desc 'Stop the local redis-server' task :stop do if File.exist?('work/redis.pid') pid = IO.read('work/redis.pid').to_i Process.kill('TERM', pid) end end desc 'Remove the redis working directory' task :clean => :stop do FileUtils.rmtree('work/redis') if Dir.exist?('work/redis') File.delete('work/redis.pid') if File.exist?('work/redis.pid') end end