circus-deployment 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. data/LICENSE +23 -0
  2. data/README.md +0 -0
  3. data/bin/circus +24 -0
  4. data/lib/bundler/circus_bundler.rb +24 -0
  5. data/lib/bundler/circus_util.rb +43 -0
  6. data/lib/bundler/patches.rb +18 -0
  7. data/lib/circus/act.rb +74 -0
  8. data/lib/circus/actstore_client.rb +30 -0
  9. data/lib/circus/agents/agent.rb +59 -0
  10. data/lib/circus/agents/client.rb +77 -0
  11. data/lib/circus/agents/connection.rb +76 -0
  12. data/lib/circus/agents/conversation.rb +17 -0
  13. data/lib/circus/agents/dbus_connection.rb +85 -0
  14. data/lib/circus/agents/dbus_logger.rb +34 -0
  15. data/lib/circus/agents/encoding.rb +32 -0
  16. data/lib/circus/agents/logger.rb +52 -0
  17. data/lib/circus/agents/params.rb +47 -0
  18. data/lib/circus/agents/ssh_connection.rb +120 -0
  19. data/lib/circus/application.rb +99 -0
  20. data/lib/circus/booth_client.rb +25 -0
  21. data/lib/circus/booth_tool.rb +98 -0
  22. data/lib/circus/cli.rb +147 -0
  23. data/lib/circus/clown_client.rb +27 -0
  24. data/lib/circus/connection_builder.rb +32 -0
  25. data/lib/circus/external_util.rb +14 -0
  26. data/lib/circus/local_config.rb +65 -0
  27. data/lib/circus/profiles/base.rb +115 -0
  28. data/lib/circus/profiles/django.rb +90 -0
  29. data/lib/circus/profiles/jekyll.rb +90 -0
  30. data/lib/circus/profiles/make_base.rb +17 -0
  31. data/lib/circus/profiles/pure_py.rb +46 -0
  32. data/lib/circus/profiles/pure_rb.rb +48 -0
  33. data/lib/circus/profiles/python_base.rb +39 -0
  34. data/lib/circus/profiles/rack.rb +59 -0
  35. data/lib/circus/profiles/ruby_base.rb +52 -0
  36. data/lib/circus/profiles/shell.rb +46 -0
  37. data/lib/circus/profiles.rb +10 -0
  38. data/lib/circus/repos/git.rb +42 -0
  39. data/lib/circus/repos/mercurial.rb +42 -0
  40. data/lib/circus/repos.rb +16 -0
  41. data/lib/circus/resource_allocator_client.rb +19 -0
  42. data/lib/circus/stdout_logger.rb +11 -0
  43. data/lib/circus/version.rb +3 -0
  44. data/lib/circus.rb +9 -0
  45. data/vendor/ruby-dbus/COPYING +504 -0
  46. data/vendor/ruby-dbus/ChangeLog +782 -0
  47. data/vendor/ruby-dbus/HOWTO-RELEASE +14 -0
  48. data/vendor/ruby-dbus/NEWS +104 -0
  49. data/vendor/ruby-dbus/README +53 -0
  50. data/vendor/ruby-dbus/Rakefile +47 -0
  51. data/vendor/ruby-dbus/doc/tutorial/src/00.index.page +12 -0
  52. data/vendor/ruby-dbus/doc/tutorial/src/10.intro.page +127 -0
  53. data/vendor/ruby-dbus/doc/tutorial/src/20.basic_client.page +174 -0
  54. data/vendor/ruby-dbus/doc/tutorial/src/30.service.page +121 -0
  55. data/vendor/ruby-dbus/doc/tutorial/src/default.css +129 -0
  56. data/vendor/ruby-dbus/doc/tutorial/src/default.template +46 -0
  57. data/vendor/ruby-dbus/examples/gdbus/gdbus +255 -0
  58. data/vendor/ruby-dbus/examples/gdbus/gdbus.glade +184 -0
  59. data/vendor/ruby-dbus/examples/gdbus/launch.sh +4 -0
  60. data/vendor/ruby-dbus/examples/no-introspect/nm-test.rb +21 -0
  61. data/vendor/ruby-dbus/examples/no-introspect/tracker-test.rb +16 -0
  62. data/vendor/ruby-dbus/examples/rhythmbox/playpause.rb +25 -0
  63. data/vendor/ruby-dbus/examples/service/call_service.rb +25 -0
  64. data/vendor/ruby-dbus/examples/service/service_newapi.rb +51 -0
  65. data/vendor/ruby-dbus/examples/simple/call_introspect.rb +34 -0
  66. data/vendor/ruby-dbus/examples/utils/listnames.rb +11 -0
  67. data/vendor/ruby-dbus/examples/utils/notify.rb +19 -0
  68. data/vendor/ruby-dbus/lib/dbus/auth.rb +156 -0
  69. data/vendor/ruby-dbus/lib/dbus/bus.rb +750 -0
  70. data/vendor/ruby-dbus/lib/dbus/export.rb +133 -0
  71. data/vendor/ruby-dbus/lib/dbus/introspect.rb +544 -0
  72. data/vendor/ruby-dbus/lib/dbus/marshall.rb +443 -0
  73. data/vendor/ruby-dbus/lib/dbus/matchrule.rb +100 -0
  74. data/vendor/ruby-dbus/lib/dbus/message.rb +293 -0
  75. data/vendor/ruby-dbus/lib/dbus/type.rb +222 -0
  76. data/vendor/ruby-dbus/lib/dbus.rb +89 -0
  77. data/vendor/ruby-dbus/ruby-dbus.gemspec +28 -0
  78. data/vendor/ruby-dbus/setup.rb +1585 -0
  79. data/vendor/ruby-dbus/test/Makefile +4 -0
  80. data/vendor/ruby-dbus/test/bus_driver_test.rb +21 -0
  81. data/vendor/ruby-dbus/test/server_robustness_test.rb +41 -0
  82. data/vendor/ruby-dbus/test/server_test.rb +44 -0
  83. data/vendor/ruby-dbus/test/service_newapi.rb +99 -0
  84. data/vendor/ruby-dbus/test/session_bus_test_manual.rb +20 -0
  85. data/vendor/ruby-dbus/test/signal_test.rb +57 -0
  86. data/vendor/ruby-dbus/test/t1 +4 -0
  87. data/vendor/ruby-dbus/test/t2.rb +66 -0
  88. data/vendor/ruby-dbus/test/t3-ticket27.rb +18 -0
  89. data/vendor/ruby-dbus/test/t5-report-dbus-interface.rb +58 -0
  90. data/vendor/ruby-dbus/test/t6-loop.rb +85 -0
  91. data/vendor/ruby-dbus/test/test_all +26 -0
  92. data/vendor/ruby-dbus/test/test_server +74 -0
  93. data/vendor/ruby-dbus/test/variant_test.rb +66 -0
  94. metadata +225 -0
@@ -0,0 +1,115 @@
1
+ require 'net/http'
2
+ require 'yaml'
3
+ require 'circus/external_util'
4
+
5
+ module Circus
6
+ module Profiles
7
+ PROFILES=[]
8
+
9
+ # Base functionality for an Profile
10
+ class Base
11
+ def initialize(name, dir, props)
12
+ @name = name
13
+ @dir = dir
14
+ @props = props
15
+ end
16
+
17
+ def package_base_dir?
18
+ true
19
+ end
20
+
21
+ def extra_dirs
22
+ []
23
+ end
24
+
25
+ def package_for_dev(logger, run_dir)
26
+ return false unless prepare_for_dev(logger, run_dir)
27
+ write_run_script(run_dir) do |f|
28
+ f.write(dev_run_script_content.strip)
29
+ end
30
+ end
31
+
32
+ def package_for_deploy(logger, run_dir)
33
+ return false unless prepare_for_deploy(logger, run_dir)
34
+ write_run_script(run_dir) do |f|
35
+ f.write(deploy_run_script_content.strip)
36
+ end
37
+ File.open(File.join(run_dir, 'requirements.yaml'), 'w') do |f|
38
+ f.write(requirements.to_yaml)
39
+ end
40
+ end
41
+
42
+ def cleanup_after_deploy(logger, overlay_dir)
43
+ end
44
+
45
+ # Overriden by subclasses to specify the resources that they require. Defaults to a resource
46
+ # hash provided in the act definition
47
+ def requirements
48
+ (@props['requirements'] || {}).dup
49
+ end
50
+
51
+ protected
52
+ # Overriden by subclasses to handle development preparation. Defaults to the same as the deployment preparation.
53
+ def prepare_for_dev(logger, run_dir)
54
+ prepare_for_deploy(logger, run_dir)
55
+ end
56
+
57
+ # Overriden by classes to handle generating the run script content for development.
58
+ def dev_run_script_content
59
+ end
60
+
61
+ # Overriden by subclasses to handle deployment preparation
62
+ def prepare_for_deploy(logger, run_dir)
63
+ true
64
+ end
65
+
66
+ # Overriden by classes to handle generating the run script content for deployment.
67
+ def deploy_run_script_content
68
+ end
69
+
70
+ def write_run_script(run_dir)
71
+ File.open(File.join(run_dir, 'run'), 'w') do |f|
72
+ yield f
73
+ end
74
+ File.chmod 0777, File.join(run_dir, 'run')
75
+ end
76
+
77
+ def shell_run_script
78
+ <<-EOT
79
+ #!/bin/sh
80
+
81
+ #{yield}
82
+ EOT
83
+ end
84
+
85
+ def write_dev_run_script(run_dir)
86
+ write_run_script(run_dir) do |f|
87
+ base_template = <<-EOT
88
+ #!/bin/sh
89
+
90
+ cd #{@dir}
91
+ EOT
92
+
93
+ f.write(base_template.lstrip)
94
+ yield f
95
+ end
96
+ end
97
+
98
+ def write_deploy_run_script(run_dir)
99
+ write_run_script(run_dir) do |f|
100
+ base_template = <<-EOT
101
+ #!/bin/sh
102
+
103
+ EOT
104
+
105
+ f.write(base_template.lstrip)
106
+ yield f
107
+ end
108
+ end
109
+
110
+ def run_external(logger, desc, cmd)
111
+ ExternalUtil.run_external(logger, desc, cmd)
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,90 @@
1
+ require File.expand_path('../python_base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class Django < PythonBase
6
+ DJANGO_APP_PROPERTY='django-app'
7
+
8
+ # Checks if this is a Django application. Will accept the application if it
9
+ # has a file named manage.py, or has a 'django-app' property describing the entry point.
10
+ def self.accepts?(name, dir, props)
11
+ return true if props.include? DJANGO_APP_PROPERTY
12
+ return File.exists?(File.join(dir, "manage.py"))
13
+ end
14
+
15
+ def initialize(name, dir, props)
16
+ super(name, dir, props)
17
+
18
+ @manage_script = props[DJANGO_APP_PROPERTY] || "manage.py"
19
+ end
20
+
21
+ # The name of this profile
22
+ def name
23
+ "django"
24
+ end
25
+
26
+ def prepare_for_deploy(logger, overlay_dir)
27
+ return false unless super
28
+
29
+ File.open(File.join(overlay_dir, 'local_settings.py'), 'w') do |f|
30
+ f.write <<-EOT
31
+ import os
32
+
33
+ DATABASE_ENGINE = 'postgresql_psycopg2'
34
+ DATABASE_NAME = os.getenv('DATABASE_NAME')
35
+ DATABASE_USER = os.getenv('DATABASE_USER')
36
+ DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')
37
+ DATABASE_HOST = os.getenv('DATABASE_HOST')
38
+ EOT
39
+ end
40
+ true
41
+ end
42
+
43
+ def dev_run_script_content
44
+ shell_run_script do
45
+ <<-EOT
46
+ cd #{@dir}
47
+ exec vendor/bin/python #{@manage_script} runserver
48
+ EOT
49
+ end
50
+ end
51
+
52
+ def deploy_run_script_content
53
+ shell_run_script do
54
+ <<-EOT
55
+ exec vendor/bin/python #{@manage_script} runserver --noreload 0.0.0.0:$LISTEN_PORT
56
+ EOT
57
+ end
58
+ end
59
+
60
+ # Describes the requirements of the deployed application. Django applications automatically
61
+ # require a database with accessible credentials.
62
+ def requirements
63
+ res = super
64
+
65
+ db_name = @props['database_name'] || @name
66
+ res['resources'] ||= []
67
+ res['resources'] << {
68
+ 'type' => 'Postgres',
69
+ 'name' => db_name,
70
+ 'user' => @props['database_user'] || db_name,
71
+ 'password' => @props['database_password'] || db_name
72
+ }
73
+
74
+ # TODO: The clown should be able to automatically allocate listening ports
75
+ res['system-properties'] ||= {}
76
+ res['system-properties']['LISTEN_PORT'] = 3000
77
+
78
+ # TODO: The clown should be able to automatically respond with DB details
79
+ res['system-properties']['DATABASE_NAME'] = db_name
80
+ res['system-properties']['DATABASE_USER'] = db_name
81
+ res['system-properties']['DATABASE_PASSWORD'] = @props['database_password'] || db_name
82
+ res['system-properties']['DATABASE_HOST'] = 'localhost'
83
+
84
+ res
85
+ end
86
+ end
87
+
88
+ PROFILES << Django
89
+ end
90
+ end
@@ -0,0 +1,90 @@
1
+ require File.expand_path('../base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class Jekyll < Base
6
+ # Checks if this is a Jekyll site based on whether there is a file named
7
+ # _config.yml on the root directory
8
+ def self.accepts?(name, dir, props)
9
+ return File.exists?(File.join(dir, "_config.yml"))
10
+ end
11
+
12
+ def initialize(name, dir, props)
13
+ super(name, dir, props)
14
+ end
15
+
16
+ # The name of this profile
17
+ def name
18
+ "jekyll"
19
+ end
20
+
21
+ def package_base_dir?
22
+ false
23
+ end
24
+
25
+ def extra_dirs
26
+ ["#{@dir}/_site"]
27
+ end
28
+
29
+ def prepare_for_deploy(logger, overlay_dir)
30
+ run_external(logger, 'Generate site with Jekyll', "cd #{@dir}; jekyll")
31
+
32
+ # Create lighttpd.conf
33
+ File.open(File.join(overlay_dir, 'lighttpd.conf'), 'w') do |f|
34
+ f.write <<-EOT
35
+ server.document-root = "_site/"
36
+
37
+ server.port = env.HTTPD_PORT
38
+
39
+ mimetype.assign = (
40
+ ".html" => "text/html",
41
+ ".txt" => "text/plain",
42
+ ".css" => "text/css",
43
+ ".jpg" => "image/jpeg",
44
+ ".png" => "image/png"
45
+ )
46
+
47
+ static-file.exclude-extensions = ( ".yaml" )
48
+ index-file.names = ( "index.html" )
49
+ EOT
50
+ end
51
+ true
52
+ end
53
+
54
+ def cleanup_after_deploy(logger, overlay_dir)
55
+ FileUtils.rm_rf(File.join(@dir, '_site'))
56
+ end
57
+
58
+ def dev_run_script_content
59
+ shell_run_script do
60
+ <<-EOT
61
+ cd #{@dir}
62
+ exec jekyll --auto --server
63
+ EOT
64
+ end
65
+ end
66
+
67
+ def deploy_run_script_content
68
+ shell_run_script do
69
+ <<-EOT
70
+ exec lighttpd -D -f lighttpd.conf
71
+ EOT
72
+ end
73
+ end
74
+
75
+ # Describes the resources required by the deployed application. Jekyll sites automatically
76
+ # require a port to serve content on.
77
+ def requirements
78
+ res = super
79
+
80
+ # TODO: The clown should be able to automatically allocate listening ports
81
+ res['system-properties'] ||= {}
82
+ res['system-properties']['HTTPD_PORT'] = 3000
83
+
84
+ res
85
+ end
86
+ end
87
+
88
+ PROFILES << Jekyll
89
+ end
90
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path('../base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class MakeBase < Base
6
+ # Development preparation is the same as deployment
7
+ def prepare_for_dev(logger, run_dir)
8
+ prepare_for_deploy(logger, run_dir)
9
+ end
10
+
11
+ def prepare_for_deploy(logger, overlay_dir)
12
+ # Build the application
13
+ run_external(logger, 'Compile application', "cd #{@dir}; make")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path('../python_base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class PurePy < PythonBase
6
+ PUREPY_APP_PROPERTY='purepy-app'
7
+
8
+ # Checks if this is a pure python application. Will accept the application if it
9
+ # has a file named <name>.py, or has a 'purepy-app' property describing the entry point.
10
+ def self.accepts?(name, dir, props)
11
+ return true if props.include? PUREPY_APP_PROPERTY
12
+ return File.exists?(File.join(dir, "#{name}.py"))
13
+ end
14
+
15
+ def initialize(name, dir, props)
16
+ super(name, dir, props)
17
+
18
+ @py_script = props[PUREPY_APP_PROPERTY] || "#{name}.py"
19
+ end
20
+
21
+ # The name of this profile
22
+ def name
23
+ "pure-py"
24
+ end
25
+
26
+ def dev_run_script_content
27
+ shell_run_script do
28
+ <<-EOT
29
+ cd #{@dir}
30
+ exec vendor/bin/python #{@py_script}
31
+ EOT
32
+ end
33
+ end
34
+
35
+ def deploy_run_script_content
36
+ shell_run_script do
37
+ <<-EOT
38
+ exec vendor/bin/python #{@py_script}
39
+ EOT
40
+ end
41
+ end
42
+ end
43
+
44
+ PROFILES << PurePy
45
+ end
46
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../ruby_base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class PureRb < RubyBase
6
+ PURERB_APP_PROPERTY='purerb-app'
7
+
8
+ # Checks if this is a pure ruby application. Will accept the application if it
9
+ # has a file named <name>.rb, or has a 'purerb-app' property describing the entry point.
10
+ def self.accepts?(name, dir, props)
11
+ return true if props.include? PURERB_APP_PROPERTY
12
+ return File.exists?(File.join(dir, "#{name}.rb"))
13
+ end
14
+
15
+ def initialize(name, dir, props)
16
+ super(name, dir, props)
17
+
18
+ @rb_script = props[PURERB_APP_PROPERTY] || "#{name}.rb"
19
+ end
20
+
21
+ # The name of this profile
22
+ def name
23
+ "pure-rb"
24
+ end
25
+
26
+ # Just run the script in development
27
+ def dev_run_script_content
28
+ shell_run_script do
29
+ <<-EOT
30
+ cd #{@dir}
31
+ exec ruby #{@rb_script}
32
+ EOT
33
+ end
34
+ end
35
+
36
+ # Install our gems and then run in deployment
37
+ def deploy_run_script_content
38
+ shell_run_script do
39
+ <<-EOT
40
+ exec ruby #{@rb_script}
41
+ EOT
42
+ end
43
+ end
44
+ end
45
+
46
+ PROFILES << PureRb
47
+ end
48
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path('../base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class PythonBase < Base
6
+ # Development preparation is the same as deployment
7
+ def prepare_for_dev(logger, run_dir)
8
+ prepare_for_deploy(logger, run_dir)
9
+ end
10
+
11
+ def prepare_for_deploy(logger, overlay_dir)
12
+ # Build the virtualenv
13
+ if has_depsfile?
14
+ unless File.exists? "#{@dir}/vendor"
15
+ return false unless run_external(logger, "Create virtualenv", "cd #{@dir}; virtualenv --no-site-packages vendor")
16
+ end
17
+
18
+ File.read(depsfile_fn).lines.each do |dep|
19
+ return false unless run_external(logger, "Install dep #{dep}",
20
+ "cd #{@dir}; vendor/bin/easy_install -q \"#{dep.strip}\"")
21
+ end
22
+
23
+ return false unless run_external(logger, "Make virtualenv relocatable", "cd #{@dir}; virtualenv --relocatable vendor")
24
+ end
25
+
26
+ true
27
+ end
28
+
29
+ protected
30
+ def depsfile_fn
31
+ "#{@dir}/Pydeps"
32
+ end
33
+
34
+ def has_depsfile?
35
+ File.exists? depsfile_fn
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path('../ruby_base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class Rack < RubyBase
6
+ RACKFILE_NAME='ruby-rackfile'
7
+
8
+ # Checks if this is a rack applcation. Will accept the application if it has a config.ru, or if the
9
+ # properties describe the location of an alternative rack entry point.
10
+ def self.accepts?(name, dir, props)
11
+ return true if props.include? RACKFILE_NAME
12
+ return File.exists?(File.join(dir, 'config.ru'))
13
+ end
14
+
15
+ def initialize(name, dir, props)
16
+ super(name, dir, props)
17
+
18
+ @rackup_name = props[RACKFILE_NAME] || 'config.ru'
19
+ end
20
+
21
+ # The name of this profile
22
+ def name
23
+ "rack"
24
+ end
25
+
26
+ def dev_run_script_content
27
+ shell_run_script do
28
+ <<-EOT
29
+ cd #{@dir}
30
+ exec bundle exec thin -R #{@rackup_name} -p #{listen_port} start
31
+ EOT
32
+ end
33
+ end
34
+
35
+ def deploy_run_script_content
36
+ shell_run_script do
37
+ <<-EOT
38
+ exec bundle exec vendor/bin/thin -R #{@rackup_name} -p #{listen_port} start
39
+ EOT
40
+ end
41
+ end
42
+
43
+ def extra_dirs
44
+ if has_gemfile?
45
+ ["#{@dir}/.bundle"]
46
+ else
47
+ []
48
+ end
49
+ end
50
+
51
+ private
52
+ def listen_port
53
+ @props['web-app-port'] || 3000
54
+ end
55
+ end
56
+
57
+ PROFILES << Rack
58
+ end
59
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path('../base', __FILE__)
2
+ require 'fileutils'
3
+ require 'bundler/circus_util'
4
+
5
+ module Circus
6
+ module Profiles
7
+ class RubyBase < Base
8
+ BUNDLER_TOOL=File.expand_path('../../../bundler/circus_bundler.rb', __FILE__)
9
+
10
+ def initialize(name, dir, props)
11
+ super(name, dir, props)
12
+ end
13
+
14
+ # No dev preparation required. Don't override dev_run_script_content, since it is the
15
+ # same as the deployment variant.
16
+ def prepare_for_dev(logger, run_dir); true; end
17
+
18
+ def prepare_for_deploy(logger, overlay_dir)
19
+ # Run the gem bundler if necessary
20
+ if has_gemfile?
21
+ logger.info("Bundling gems")
22
+ run_external(logger, 'gem bundling', "cd #{@dir}; ruby #{BUNDLER_TOOL}")
23
+ end
24
+
25
+ true
26
+ end
27
+
28
+ def cleanup_after_deploy(logger, overlay_dir)
29
+ Bundler::CircusUtil.unfix_external_paths(@dir)
30
+ end
31
+
32
+ def extra_dirs
33
+ if has_gemfile?
34
+ ["#{@dir}/.bundle"]
35
+ else
36
+ []
37
+ end
38
+ end
39
+
40
+ protected
41
+ def has_gemfile?
42
+ File.exists? "#{@dir}/Gemfile"
43
+ end
44
+
45
+ # class LoggingShell
46
+ # def say(msg)
47
+ # puts msg
48
+ # end
49
+ # end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path('../make_base', __FILE__)
2
+
3
+ module Circus
4
+ module Profiles
5
+ class Shell < MakeBase
6
+ SHELL_APP_PROPERTY='shell-app'
7
+
8
+ # Checks if this is a shell applcation. Will accept the application if it
9
+ # has a file named <name>.sh, or has a 'shell-app' property describing the entry point.
10
+ def self.accepts?(name, dir, props)
11
+ return true if props.include? SHELL_APP_PROPERTY
12
+ return File.exists?(File.join(dir, "#{name}.sh"))
13
+ end
14
+
15
+ def initialize(name, dir, props)
16
+ super(name, dir, props)
17
+
18
+ @sh_script = props[SHELL_APP_PROPERTY] || "#{name}.sh"
19
+ end
20
+
21
+ # The name of this profile
22
+ def name
23
+ "shell"
24
+ end
25
+
26
+ def dev_run_script_content
27
+ shell_run_script do
28
+ <<-EOT
29
+ cd #{@dir}
30
+ exec sh #{@sh_script}
31
+ EOT
32
+ end
33
+ end
34
+
35
+ def deploy_run_script_content
36
+ shell_run_script do
37
+ <<-EOT
38
+ exec sh #{@sh_script}
39
+ EOT
40
+ end
41
+ end
42
+ end
43
+
44
+ PROFILES << Shell
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../profiles/base', __FILE__)
2
+ require File.expand_path('../profiles/ruby_base', __FILE__)
3
+ require File.expand_path('../profiles/rack', __FILE__)
4
+ require File.expand_path('../profiles/pure_rb', __FILE__)
5
+ require File.expand_path('../profiles/python_base', __FILE__)
6
+ require File.expand_path('../profiles/pure_py', __FILE__)
7
+ require File.expand_path('../profiles/make_base', __FILE__)
8
+ require File.expand_path('../profiles/shell', __FILE__)
9
+ require File.expand_path('../profiles/django', __FILE__)
10
+ require File.expand_path('../profiles/jekyll', __FILE__)
@@ -0,0 +1,42 @@
1
+ module Circus
2
+ module Repos
3
+ class Git
4
+ # Checks if the current directory (or a parent) are Git working trees. Uses
5
+ # a call to git remote to test (which will fail with a non-zero exit if the
6
+ # tree isn't a valid git tree)
7
+ def self.accepts_dir? dir_name
8
+ `git remote >/dev/null 2>/dev/null`
9
+ $? == 0
10
+ end
11
+
12
+ def self.accepts_id?(key)
13
+ key == 'git'
14
+ end
15
+
16
+ def self.type_id
17
+ 'git'
18
+ end
19
+
20
+ def initialize(dir)
21
+ @dir = dir
22
+ end
23
+
24
+ def repo_url
25
+ first_remote = `(cd #{@dir}; git remote -v) | grep fetch`.lines.first
26
+ return nil unless first_remote
27
+
28
+ first_remote.split(' ', 2)[1].gsub('(fetch)', '').strip
29
+ end
30
+
31
+ def current_revision
32
+ `(cd #{@dir}; git rev-parse HEAD)`.strip
33
+ end
34
+
35
+ def write_patch(patch_fn)
36
+ `(cd #{@dir}; git diff HEAD >#{patch_fn})`.strip
37
+ end
38
+ end
39
+
40
+ REPOS << Git
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ module Circus
2
+ module Repos
3
+ class Mercurial
4
+ # Checks if the current directory (or a parent) are Hg working trees. Uses
5
+ # a call to hg status to test (which will fail with a non-zero exit if the
6
+ # tree isn't a valid git tree)
7
+ def self.accepts_dir? dir_name
8
+ `hg st >/dev/null 2>/dev/null`
9
+ $? == 0
10
+ end
11
+
12
+ def self.accepts_id?(key)
13
+ key == 'hg' || key == 'mercurial'
14
+ end
15
+
16
+ def self.type_id
17
+ 'hg'
18
+ end
19
+
20
+ def initialize(dir)
21
+ @dir = dir
22
+ end
23
+
24
+ def repo_url
25
+ first_path = `(cd #{@dir}; hg paths)`.lines.first
26
+ return nil unless first_path
27
+
28
+ first_path.split('=', 2)[1].strip
29
+ end
30
+
31
+ def current_revision
32
+ `(cd #{@dir}; hg id -i)`[0..11]
33
+ end
34
+
35
+ def write_patch(patch_fn)
36
+ `(cd #{@dir}; hg diff >#{patch_fn})`.strip
37
+ end
38
+ end
39
+
40
+ REPOS << Mercurial
41
+ end
42
+ end