stackfu 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/CHANGELOG +24 -0
  2. data/Manifest +118 -0
  3. data/README +0 -0
  4. data/README.md +218 -0
  5. data/Rakefile +73 -0
  6. data/bin/stackfu +10 -0
  7. data/lib/stackfu/api_hooks.rb +17 -0
  8. data/lib/stackfu/app.rb +69 -0
  9. data/lib/stackfu/commands/command.rb +127 -0
  10. data/lib/stackfu/commands/config_command.rb +43 -0
  11. data/lib/stackfu/commands/deploy_command.rb +144 -0
  12. data/lib/stackfu/commands/dump_command.rb +101 -0
  13. data/lib/stackfu/commands/generate_command.rb +107 -0
  14. data/lib/stackfu/commands/help_command.rb +28 -0
  15. data/lib/stackfu/commands/list_command.rb +26 -0
  16. data/lib/stackfu/commands/publish_command.rb +108 -0
  17. data/lib/stackfu/commands/server_command.rb +124 -0
  18. data/lib/stackfu/helpers/providers_credentials.rb +82 -0
  19. data/lib/stackfu/helpers/rendering.rb +201 -0
  20. data/lib/stackfu/operating_systems.rb +30 -0
  21. data/lib/stackfu.rb +88 -0
  22. data/stackfu-installer/config/01-controls.yml +17 -0
  23. data/stackfu-installer/config/02-requirements.yml +3 -0
  24. data/stackfu-installer/config/03-scripts.yml +16 -0
  25. data/stackfu-installer/config/04-validations.yml +3 -0
  26. data/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
  27. data/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
  28. data/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
  29. data/stackfu-installer/script/redis_installation.sh.erb +33 -0
  30. data/stackfu-installer/script/resque_installation.sh.erb +7 -0
  31. data/stackfu-installer/script/ruby_environment.sh.erb +20 -0
  32. data/stackfu-installer/script/stackfu.sh.erb +114 -0
  33. data/stackfu-installer/stack.yml +5 -0
  34. data/stackfu.gemspec +60 -0
  35. data/templates/01-controls.yml.erb +31 -0
  36. data/templates/02-requirements.yml.erb +26 -0
  37. data/templates/03-scripts.yml.erb +34 -0
  38. data/templates/04-validations.yml.erb +17 -0
  39. data/templates/script.sh.erb +7 -0
  40. data/templates/stack.yml.erb +17 -0
  41. data/test/fixtures/add_server_error +7 -0
  42. data/test/fixtures/deployment_add +7 -0
  43. data/test/fixtures/deployment_add_error +8 -0
  44. data/test/fixtures/deployments +7 -0
  45. data/test/fixtures/logs +7 -0
  46. data/test/fixtures/logs_partial +7 -0
  47. data/test/fixtures/plugin_add +6 -0
  48. data/test/fixtures/plugin_add_error +8 -0
  49. data/test/fixtures/plugin_deployment_add +7 -0
  50. data/test/fixtures/plugin_not_found +7 -0
  51. data/test/fixtures/plugin_unauthorized +8 -0
  52. data/test/fixtures/plugins +7 -0
  53. data/test/fixtures/plugins_by_name +7 -0
  54. data/test/fixtures/plugins_by_name_other +7 -0
  55. data/test/fixtures/plugins_empty +7 -0
  56. data/test/fixtures/plugins_multiple +7 -0
  57. data/test/fixtures/providers +7 -0
  58. data/test/fixtures/providers_servers +7 -0
  59. data/test/fixtures/server_add +6 -0
  60. data/test/fixtures/server_add_dupe +7 -0
  61. data/test/fixtures/server_add_error +7 -0
  62. data/test/fixtures/server_delete +7 -0
  63. data/test/fixtures/server_delete_error +7 -0
  64. data/test/fixtures/servers +7 -0
  65. data/test/fixtures/servers_by_name +7 -0
  66. data/test/fixtures/servers_empty +8 -0
  67. data/test/fixtures/servers_not_found +26 -0
  68. data/test/fixtures/servers_unauthorized +8 -0
  69. data/test/fixtures/servers_webbynode +7 -0
  70. data/test/fixtures/stack/stackfu-installer/config/01-controls.yml +22 -0
  71. data/test/fixtures/stack/stackfu-installer/config/02-requirements.yml +1 -0
  72. data/test/fixtures/stack/stackfu-installer/config/03-scripts.yml +23 -0
  73. data/test/fixtures/stack/stackfu-installer/config/04-validations.yml +1 -0
  74. data/test/fixtures/stack/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
  75. data/test/fixtures/stack/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
  76. data/test/fixtures/stack/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
  77. data/test/fixtures/stack/stackfu-installer/script/redis_installation.sh.erb +33 -0
  78. data/test/fixtures/stack/stackfu-installer/script/resque_installation.sh.erb +7 -0
  79. data/test/fixtures/stack/stackfu-installer/script/ruby_environment.sh.erb +20 -0
  80. data/test/fixtures/stack/stackfu-installer/script/stackfu.sh.erb +76 -0
  81. data/test/fixtures/stack/stackfu-installer/stack.yml +5 -0
  82. data/test/fixtures/stack_add +6 -0
  83. data/test/fixtures/stack_add_error +8 -0
  84. data/test/fixtures/stack_add_error_dupe +8 -0
  85. data/test/fixtures/stack_adds_by_name +7 -0
  86. data/test/fixtures/stack_delete_not_found +7 -0
  87. data/test/fixtures/stacks +7 -0
  88. data/test/fixtures/stacks_by_name +7 -0
  89. data/test/fixtures/stacks_by_name_other +7 -0
  90. data/test/fixtures/stacks_empty +7 -0
  91. data/test/fixtures/stacks_multiple +7 -0
  92. data/test/fixtures/stacks_not_found +7 -0
  93. data/test/fixtures/stacks_realworld +7 -0
  94. data/test/fixtures/stacks_stackfu-installer +7 -0
  95. data/test/fixtures/stacks_unauthorized +8 -0
  96. data/test/fixtures/stacks_with_controls +0 -0
  97. data/test/fixtures/users +7 -0
  98. data/test/fixtures/users_no_credentials +7 -0
  99. data/test/fixtures/users_update +6 -0
  100. data/test/stack.yml +26 -0
  101. data/test/support/custom_matchers.rb +69 -0
  102. data/test/support/fixtures.rb +98 -0
  103. data/test/support/io_stub.rb +10 -0
  104. data/test/support/web_fixtures.rb +91 -0
  105. data/test/test_helper.rb +186 -0
  106. data/test/unit/commands/test_command.rb +112 -0
  107. data/test/unit/commands/test_config_command.rb +92 -0
  108. data/test/unit/commands/test_deploy_command.rb +303 -0
  109. data/test/unit/commands/test_dump_command.rb +155 -0
  110. data/test/unit/commands/test_generate_command.rb +112 -0
  111. data/test/unit/commands/test_help_command.rb +33 -0
  112. data/test/unit/commands/test_list_command.rb +63 -0
  113. data/test/unit/commands/test_publish_command.rb +265 -0
  114. data/test/unit/commands/test_server_command.rb +259 -0
  115. data/test/unit/helpers/test_rendering.rb +141 -0
  116. data/test/unit/test_array.rb +26 -0
  117. data/test/unit/test_provider.rb +14 -0
  118. data/test/unit/test_stackfu.rb +27 -0
  119. metadata +311 -0
data/CHANGELOG ADDED
@@ -0,0 +1,24 @@
1
+ [fd98c98 | Tue Nov 17 02:55:13 UTC 2009] Felipe Coury <felipe.coury@gmail.com>
2
+
3
+ * GenerateCommand now accepts controls
4
+
5
+ [28109d5 | Mon Nov 16 21:35:14 UTC 2009] Felipe Coury <felipe.coury@gmail.com>
6
+
7
+ * Command `stackfu generate stack' creates manifest and scripts for a stack
8
+
9
+ [3a48d41 | Sun Nov 15 05:27:02 UTC 2009] Felipe Coury <felipe.coury@gmail.com>
10
+
11
+ * Added config command and made initial configuration and server adding/removing to/from Slicehost work with the API backend.
12
+
13
+ [476f5d7 | Sun Nov 15 05:26:15 UTC 2009] Felipe Coury <felipe.coury@gmail.com>
14
+
15
+ * Improved command parsing
16
+
17
+ [548b1e9 | Sat Nov 14 04:17:15 UTC 2009] Felipe Coury <felipe.coury@gmail.com>
18
+
19
+ * First steps towards a running app. Created test helpers to automate testing of the CLI app.
20
+
21
+ [74d38e3 | Fri Nov 13 13:19:47 UTC 2009] Felipe Coury <felipe.coury@gmail.com>
22
+
23
+ * Initial commit
24
+
data/Manifest ADDED
@@ -0,0 +1,118 @@
1
+ CHANGELOG
2
+ Manifest
3
+ README
4
+ README.md
5
+ Rakefile
6
+ bin/stackfu
7
+ lib/stackfu.rb
8
+ lib/stackfu/api_hooks.rb
9
+ lib/stackfu/app.rb
10
+ lib/stackfu/commands/command.rb
11
+ lib/stackfu/commands/config_command.rb
12
+ lib/stackfu/commands/deploy_command.rb
13
+ lib/stackfu/commands/dump_command.rb
14
+ lib/stackfu/commands/generate_command.rb
15
+ lib/stackfu/commands/help_command.rb
16
+ lib/stackfu/commands/list_command.rb
17
+ lib/stackfu/commands/publish_command.rb
18
+ lib/stackfu/commands/server_command.rb
19
+ lib/stackfu/helpers/providers_credentials.rb
20
+ lib/stackfu/helpers/rendering.rb
21
+ lib/stackfu/operating_systems.rb
22
+ stackfu-installer/config/01-controls.yml
23
+ stackfu-installer/config/02-requirements.yml
24
+ stackfu-installer/config/03-scripts.yml
25
+ stackfu-installer/config/04-validations.yml
26
+ stackfu-installer/script/dotfiles_installation.sh.erb
27
+ stackfu-installer/script/github_credentials_setup.sh.erb
28
+ stackfu-installer/script/nginx_and_passenger.sh.erb
29
+ stackfu-installer/script/redis_installation.sh.erb
30
+ stackfu-installer/script/resque_installation.sh.erb
31
+ stackfu-installer/script/ruby_environment.sh.erb
32
+ stackfu-installer/script/stackfu.sh.erb
33
+ stackfu-installer/stack.yml
34
+ stackfu.gemspec
35
+ templates/01-controls.yml.erb
36
+ templates/02-requirements.yml.erb
37
+ templates/03-scripts.yml.erb
38
+ templates/04-validations.yml.erb
39
+ templates/script.sh.erb
40
+ templates/stack.yml.erb
41
+ test/fixtures/add_server_error
42
+ test/fixtures/deployment_add
43
+ test/fixtures/deployment_add_error
44
+ test/fixtures/deployments
45
+ test/fixtures/logs
46
+ test/fixtures/logs_partial
47
+ test/fixtures/plugin_add
48
+ test/fixtures/plugin_add_error
49
+ test/fixtures/plugin_deployment_add
50
+ test/fixtures/plugin_not_found
51
+ test/fixtures/plugin_unauthorized
52
+ test/fixtures/plugins
53
+ test/fixtures/plugins_by_name
54
+ test/fixtures/plugins_by_name_other
55
+ test/fixtures/plugins_empty
56
+ test/fixtures/plugins_multiple
57
+ test/fixtures/providers
58
+ test/fixtures/providers_servers
59
+ test/fixtures/server_add
60
+ test/fixtures/server_add_dupe
61
+ test/fixtures/server_add_error
62
+ test/fixtures/server_delete
63
+ test/fixtures/server_delete_error
64
+ test/fixtures/servers
65
+ test/fixtures/servers_by_name
66
+ test/fixtures/servers_empty
67
+ test/fixtures/servers_not_found
68
+ test/fixtures/servers_unauthorized
69
+ test/fixtures/servers_webbynode
70
+ test/fixtures/stack/stackfu-installer/config/01-controls.yml
71
+ test/fixtures/stack/stackfu-installer/config/02-requirements.yml
72
+ test/fixtures/stack/stackfu-installer/config/03-scripts.yml
73
+ test/fixtures/stack/stackfu-installer/config/04-validations.yml
74
+ test/fixtures/stack/stackfu-installer/script/dotfiles_installation.sh.erb
75
+ test/fixtures/stack/stackfu-installer/script/github_credentials_setup.sh.erb
76
+ test/fixtures/stack/stackfu-installer/script/nginx_and_passenger.sh.erb
77
+ test/fixtures/stack/stackfu-installer/script/redis_installation.sh.erb
78
+ test/fixtures/stack/stackfu-installer/script/resque_installation.sh.erb
79
+ test/fixtures/stack/stackfu-installer/script/ruby_environment.sh.erb
80
+ test/fixtures/stack/stackfu-installer/script/stackfu.sh.erb
81
+ test/fixtures/stack/stackfu-installer/stack.yml
82
+ test/fixtures/stack_add
83
+ test/fixtures/stack_add_error
84
+ test/fixtures/stack_add_error_dupe
85
+ test/fixtures/stack_adds_by_name
86
+ test/fixtures/stack_delete_not_found
87
+ test/fixtures/stacks
88
+ test/fixtures/stacks_by_name
89
+ test/fixtures/stacks_by_name_other
90
+ test/fixtures/stacks_empty
91
+ test/fixtures/stacks_multiple
92
+ test/fixtures/stacks_not_found
93
+ test/fixtures/stacks_realworld
94
+ test/fixtures/stacks_stackfu-installer
95
+ test/fixtures/stacks_unauthorized
96
+ test/fixtures/stacks_with_controls
97
+ test/fixtures/users
98
+ test/fixtures/users_no_credentials
99
+ test/fixtures/users_update
100
+ test/stack.yml
101
+ test/support/custom_matchers.rb
102
+ test/support/fixtures.rb
103
+ test/support/io_stub.rb
104
+ test/support/web_fixtures.rb
105
+ test/test_helper.rb
106
+ test/unit/commands/test_command.rb
107
+ test/unit/commands/test_config_command.rb
108
+ test/unit/commands/test_deploy_command.rb
109
+ test/unit/commands/test_dump_command.rb
110
+ test/unit/commands/test_generate_command.rb
111
+ test/unit/commands/test_help_command.rb
112
+ test/unit/commands/test_list_command.rb
113
+ test/unit/commands/test_publish_command.rb
114
+ test/unit/commands/test_server_command.rb
115
+ test/unit/helpers/test_rendering.rb
116
+ test/unit/test_array.rb
117
+ test/unit/test_provider.rb
118
+ test/unit/test_stackfu.rb
data/README ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # stackfu
2
+
3
+ * http://github.com/fcoury/stackfu
4
+
5
+ ## DESCRIPTION:
6
+
7
+ ## Future ideas
8
+
9
+ $ sudo gem install stackfu
10
+ Password:
11
+ Successfully installed stackfu-0.3.2
12
+ 1 gem installed
13
+
14
+ $ cd ~/Hosting
15
+ $ stackfu generate stack lamp install_apache:script install_mysql:script install_php:script
16
+ $ cd lamp
17
+
18
+ Would generate
19
+
20
+ lamp/
21
+ stack.rb
22
+ scripts/
23
+ install_apache.sh.erb
24
+ install_mysql.sh.erb
25
+ install_php.sh.erb
26
+
27
+ stack.rb
28
+
29
+ stack "lamp" do
30
+ requirements do
31
+ check_folder "/var", :error => "You need /var folder before installing"
32
+ end
33
+
34
+ script "Install Apache", "install_apache"
35
+ script "Install MySQL", "install_mysql"
36
+ script "Install PHP", "install_php"
37
+
38
+ verifications do
39
+ check_folder "/etc/apache2", :error => "Apache was not installed properly"
40
+ check_file "/etc/init.d/mysql", :error => "MySQL start script was not found"
41
+ end
42
+ end
43
+
44
+ Then
45
+
46
+ $ cat ~/.stackfu
47
+ cat: /Users/fcoury/.stackfu: No such file or directory
48
+
49
+ $ stackfu add lamp
50
+ Sending stack lamp to StackFu...
51
+ Enter your login: fcoury
52
+ Enter your password:
53
+ Stack lamp successfully saved
54
+
55
+ $ cat ~/.stackfu
56
+ login: fcoury
57
+ password: abcdef
58
+
59
+ $ stackfu list
60
+ Listing 1 stack and 1 plugin:
61
+
62
+ type name version
63
+ --------- ---------- ---------
64
+ stack lamp 1.0
65
+ plugin firewall 1.2.2
66
+
67
+ $ stackfu remove lamp
68
+ Are you sure (y/n)? y
69
+ Stack lamp removed
70
+
71
+ $ stackfu list
72
+ Nothing to show
73
+
74
+ $ stackfu --help
75
+ StackFu Commander 0.1.1, a stackfu command line client.
76
+ (c) 2009-2020 StackFu - http://stackfu.com
77
+
78
+ Usage:
79
+ stackfu -h/--help
80
+ stackfu command [arguments] [options]
81
+
82
+ Commands:
83
+ add [stack/plugin] sends the stack or plugin described in the current
84
+ folder
85
+ list lists all the stacks and plugins currently hosted
86
+ under your account
87
+
88
+ $ stackfu servers
89
+ You current have 2 servers under your account:
90
+
91
+ name host ip
92
+ ------------ ------------- -------------------
93
+ webby2847 Webbynode 208.88.103.25
94
+ slippery Slicehost 75.125.67.12
95
+
96
+ $ stackfu deploy stack lamp to slippery
97
+ WARNING: All data in this server will be destroyed.
98
+ Confirm deployment of stack "lamp" to your server "slippery"
99
+ at Slicehost? (y/n)
100
+
101
+ Redeploying slippery with Ubuntu 8.10... Done.
102
+
103
+ Installing lamp stack...
104
+ - Installing Apache2... Done.
105
+ - Installing MySQL... Done.
106
+ - Installing PHP... Done.
107
+
108
+ Verifying installation...
109
+ - Checking Apache... OK!
110
+ - Checking MySQL... OK!
111
+
112
+ Done.
113
+
114
+ $ stackfu add plugin firewall to slippery
115
+ Open port 80 (http) (y/n)? y
116
+ Open port 22 (ssh) (y/n)? y
117
+ Enter other ports you want to open, separated by a comma:
118
+
119
+ OK, we'll install the Firewall plugin with Open port 80 and
120
+ Open port 22.
121
+ Confirm (y/n)? y
122
+
123
+ Installing ufw... Done.
124
+ Configuring ufw... Done.
125
+ Do
126
+
127
+ $ ssh root@75.125.67.12
128
+ root@75.125.67.12's password:
129
+ [slippery] $ ufw status
130
+ Status: loaded
131
+
132
+ To Action From
133
+ -- ------ ----
134
+ 80/tcp ALLOW Anywhere
135
+ 80/udp ALLOW Anywhere
136
+ 21/tcp DENY Anywhere
137
+ 21/udp DENY Anywhere
138
+ 22/tcp ALLOW Anywhere
139
+ 22/udp ALLOW Anywhere
140
+
141
+ [slippery] $ exit
142
+ Connection to 75.125.67.12 closed.
143
+
144
+ $ stackfu search plugin rails mongodb
145
+ 1 plugin found:
146
+
147
+ Ruby on Rails with MongoDB's MongoMapper
148
+ Key: rails-mongomapper
149
+ Author: ctaborda
150
+ Description: deploys a full Ruby on Rails stack
151
+ with support to MongoDB's MongoMapper.
152
+
153
+ $ stackfu clone ctaborda rails-mongomapper
154
+ You have successfully cloned rails-mongomapper from fcoury
155
+
156
+ $ stackfu list
157
+ stack lamp (1.0)
158
+ plugin firewall (1.2.2)
159
+ plugin rails-mongomapper (2.1)
160
+
161
+ $ stackfu import rails-mongomapper
162
+ Import stack rails-mongomapper to the current folder (y/n)? y
163
+ Done.
164
+
165
+ $ cd rails-mongomapper
166
+ $ ls -la
167
+ drwx------ 3 fcoury staff 102 Jun 29 15:02 rails-mongomapper
168
+
169
+ $ cd rails-mongomapper
170
+ $ ls -la
171
+ -rw-r--r--@ 1 fcoury staff 743 Aug 11 13:21 plugin.rb
172
+ drwxr-xr-x 3 fcoury staff 102 Apr 6 2009 scripts
173
+
174
+ (...)
175
+
176
+ $ stackfu add rails-mongomapper
177
+ Plugin rails-mongomapper successfully saved
178
+
179
+ ## FEATURES/PROBLEMS:
180
+
181
+ * FIX (list of features or problems)
182
+
183
+ ## SYNOPSIS:
184
+
185
+ FIX (code sample of usage)
186
+
187
+ ## REQUIREMENTS:
188
+
189
+ * FIX (list of requirements)
190
+
191
+ ## INSTALL:
192
+
193
+ * FIX (sudo gem install, anything else)
194
+
195
+ ## LICENSE:
196
+
197
+ (The MIT License)
198
+
199
+ Copyright (c) 2009 FIXME full name
200
+
201
+ Permission is hereby granted, free of charge, to any person obtaining
202
+ a copy of this software and associated documentation files (the
203
+ 'Software'), to deal in the Software without restriction, including
204
+ without limitation the rights to use, copy, modify, merge, publish,
205
+ distribute, sublicense, and/or sell copies of the Software, and to
206
+ permit persons to whom the Software is furnished to do so, subject to
207
+ the following conditions:
208
+
209
+ The above copyright notice and this permission notice shall be
210
+ included in all copies or substantial portions of the Software.
211
+
212
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
213
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
214
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
215
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
216
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
217
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
218
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,73 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ require 'echoe'
6
+
7
+ Echoe.new('stackfu', '0.1.0') do |p|
8
+ p.description = "StackFu Backend"
9
+ p.url = "http://stackfu.com/cli"
10
+ p.author = "Felipe Coury"
11
+ p.email = "felipe@stackfu.com"
12
+ p.ignore_pattern = ["tmp/*", "script/*"]
13
+ p.dependencies = [
14
+ ['activeresource','>= 2.3.4'],
15
+ ['activesupport','>= 2.3.4'],
16
+ ['rainbow', '>=1.0.4'],
17
+ ['highline', '>=1.5.1'],
18
+ ['httparty', '>=0.4.5']
19
+ ]
20
+ p.install_message = <<EOS
21
+
22
+ --==-- StackFu - Server Deployment Engine --==--
23
+
24
+ To get started:
25
+ stackfu
26
+
27
+ To get more help:
28
+ stackfu help
29
+
30
+ And now: Deploy it, grasshopper!
31
+
32
+ EOS
33
+ end
34
+
35
+ Rake::TestTask.new(:test_new) do |test|
36
+ test.libs << 'test'
37
+ test.ruby_opts << '-rubygems'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ end
41
+
42
+ require 'rcov/rcovtask'
43
+ desc 'Measures test coverage using rcov'
44
+ namespace :rcov do
45
+ desc 'Output unit test coverage of plugin.'
46
+ Rcov::RcovTask.new(:unit) do |rcov|
47
+ rcov.libs << 'test'
48
+ rcov.ruby_opts << '-rubygems'
49
+ rcov.pattern = 'test/unit/**/test_*.rb'
50
+ rcov.output_dir = 'rcov'
51
+ rcov.verbose = true
52
+ rcov.rcov_opts << '--exclude "gems/*"'
53
+ end
54
+ end
55
+
56
+ desc 'update changelog'
57
+ task :changelog do
58
+ File.open('CHANGELOG', 'w+') do |changelog|
59
+ `git log -z --abbrev-commit`.split("\0").each do |commit|
60
+ next if commit =~ /^Merge: \d*/
61
+ ref, author, time, _, title, _, message = commit.split("\n", 7)
62
+ ref = ref[/commit ([0-9a-f]+)/, 1]
63
+ author = author[/Author: (.*)/, 1].strip
64
+ time = Time.parse(time[/Date: (.*)/, 1]).utc
65
+ title.strip!
66
+
67
+ changelog.puts "[#{ref} | #{time}] #{author}"
68
+ changelog.puts '', " * #{title}"
69
+ changelog.puts '', message.rstrip if message
70
+ changelog.puts
71
+ end
72
+ end
73
+ end
data/bin/stackfu ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.dirname(__FILE__)+"/../lib"
3
+ require 'rubygems'
4
+ require 'stackfu'
5
+
6
+ HighLine.track_eof = false
7
+ $dev = (ENV['STACKFU_ENV'] || "production") == "development"
8
+
9
+ app = StackFu::App.new(ARGV)
10
+ app.start
@@ -0,0 +1,17 @@
1
+ module StackFu
2
+ module ApiHooks
3
+ class Server < ActiveResource::Base; end
4
+ class User < ActiveResource::Base; end
5
+ class Stack < ActiveResource::Base; end
6
+ class Plugin < ActiveResource::Base; end
7
+ class Provider < ActiveResource::Base; end
8
+ class Deployment < ActiveResource::Base; end
9
+
10
+ def initialize_api(config)
11
+ [Server, User, Stack, Plugin, Provider, Deployment].each do |model_class|
12
+ model_class.format = :json
13
+ model_class.site = StackFu::API.gsub(/api/, "#{config[:login]}:#{$config[:token]}@api") + "/"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,69 @@
1
+ module StackFu
2
+ class App
3
+ include StackFu::Rendering
4
+ include StackFu::ApiHooks
5
+ attr_accessor :args
6
+
7
+ def initialize(args)
8
+ @args = args
9
+ end
10
+
11
+ def start
12
+ welcome and return unless App.settings?
13
+ $config = load_config
14
+ initialize_api($config)
15
+
16
+ execute
17
+ end
18
+
19
+ def execute
20
+ begin
21
+ command = @args.delete_at(0)
22
+ cmd = Command.create(command, @args)
23
+ cmd.run
24
+ rescue Errno::ECONNREFUSED
25
+ error "Could not connect to StackFu server.",
26
+ "Please check if your internet connection is active. If you think this problem is not in your end, please report it by emailing support@stackfu.com or try again in a few minutes."
27
+ raise if $dev
28
+
29
+ rescue ActiveResource::UnauthorizedAccess
30
+ error "Access denied for user '#{$config[:login]}'",
31
+ "Please check the credentials provided on file #{ENV['HOME']}/.stackfu and run 'stackfu config' for changing it."
32
+ raise if $dev
33
+
34
+ rescue ActiveResource::ResourceNotFound
35
+ error "There was an internal error contacting StackFu backend.",
36
+ "Please report this problem at support@stackfu.com or try again in a few minutes."
37
+ raise if $dev
38
+
39
+ rescue Exceptions::UnknownCommand
40
+ error "Command #{command} does not exist", "Try using 'stackfu help' for a summary of available commands."
41
+
42
+ rescue Exceptions::InvalidCommand
43
+ error "Command #{command} is invalid", $!.message
44
+
45
+ rescue Exceptions::InvalidSubcommand
46
+ error "Invalid usage for command #{command}", $!.message
47
+ end
48
+ end
49
+
50
+ def welcome
51
+ puts "== StackFu Initial Configuration ==".bright.color(:green)
52
+ puts ""
53
+ puts "It seems this is the first time you use #{"StackFu".foreground(:yellow)} from the command line."
54
+ puts ""
55
+ puts "To get you up to speed, we need you to provide us a couple of configuration settings that will follow."
56
+ puts
57
+ ConfigCommand.new.run
58
+ true
59
+ end
60
+
61
+ def load_config
62
+ YAML.load(File.read(StackFu::CONFIG_FILE))
63
+ end
64
+
65
+ def self.settings?
66
+ File.exists?(StackFu::CONFIG_FILE)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,127 @@
1
+ module StackFu
2
+ class Command
3
+ include StackFu::OperatingSystems
4
+ include StackFu::Rendering
5
+
6
+ attr_accessor :subcommand, :parameters, :options, :errors
7
+
8
+ class << self
9
+ attr_accessor :aliases
10
+
11
+ def create(command, args=[])
12
+ command ||= "help"
13
+ klass = aliases[command.to_sym]||command_for(command)
14
+ klass.new(args)
15
+ end
16
+
17
+ def command_for(command)
18
+ StackFu.const_get("#{command.camelize}Command")
19
+ rescue NameError
20
+ raise Exceptions::UnknownCommand
21
+ end
22
+
23
+ def inherited(kls)
24
+ def kls.aliases(*aliases)
25
+ aliases.each do |a|
26
+ (Command.aliases||={})[a.to_sym] = self
27
+ end
28
+ end
29
+
30
+ def kls.alias_subcommand(spec)
31
+ (@subcommand_aliases ||= {}).merge!(spec)
32
+ end
33
+
34
+ def kls.resolve(subcommand)
35
+ (@subcommand_aliases ||= {})[subcommand.to_sym] or subcommand.to_sym
36
+ end
37
+
38
+ def kls.subcommand(name, options)
39
+ (@subcommand_options ||= {})[name.to_sym] = options
40
+ end
41
+
42
+ def kls.subcommand_options
43
+ @subcommand_options || {}
44
+ end
45
+
46
+ def kls.error_messages(spec)
47
+ (@error_messages ||= {}).merge!(spec)
48
+ end
49
+
50
+ def kls.error_for(type)
51
+ (@error_messages ||= {})[type]
52
+ end
53
+ end
54
+ end
55
+
56
+ def command
57
+ self.class.name.demodulize.underscore.gsub /_command/, ""
58
+ end
59
+
60
+ def initialize(args=[])
61
+ @errors = []
62
+ parse_options(args.reverse)
63
+ validate(self.class.subcommand_options[subcommand.to_sym])
64
+ end
65
+
66
+ def params?
67
+ parameters.any?
68
+ end
69
+
70
+ def run
71
+ unless self.respond_to?(subcommand)
72
+ error = self.class.error_for(:missing_subcommand)
73
+ error ||= "Command #{command} doesn't have a subcommand \"#{subcommand}\". Try \"stackfu #{command} help\" for more information."
74
+ raise Exceptions::InvalidSubcommand, error % [subcommand]
75
+ end
76
+ send subcommand, parameters, options
77
+ end
78
+
79
+ def valid?
80
+ validate(self.class.subcommand_options[subcommand.to_sym])
81
+ end
82
+
83
+ private
84
+
85
+ def validate(rules)
86
+ return true unless rules
87
+
88
+ if (req = rules[:required_parameters])
89
+ if parameters.size < req.size
90
+ error = self.class.error_for(:missing_params)
91
+ error ||= "The command #{command.to_s.foreground(:yellow)} #{subcommand.to_s.foreground(:yellow)} requires #{req.size} parameter#{req.size > 1 ? "s" : ""}.\nUsage: stackfu #{command} #{subcommand} #{req.to_params}"
92
+ @errors << error
93
+ end
94
+ end
95
+
96
+ raise Exceptions::InvalidCommand, @errors.to_phrase unless @errors.empty?
97
+ end
98
+
99
+ def parse_options(args)
100
+ @subcommand = args.pop unless args.last =~ /^-(.*)/
101
+ @subcommand ||= "default"
102
+ @parameters = []
103
+ @options = {}
104
+
105
+ while args.any?
106
+ item = args.pop
107
+
108
+ if item =~ /^--(.*)/
109
+ parts = $1.split("=")
110
+ name = parts.delete_at(0)
111
+ if parts.any?
112
+ value = parts.first
113
+ elsif item.strip =~ /=$/
114
+ value = ""
115
+ else
116
+ value = true
117
+ end
118
+ @options[name.to_sym] = value
119
+ else
120
+ @parameters << item
121
+ end
122
+ end
123
+
124
+ @subcommand = self.class.send(:resolve, @subcommand)
125
+ end
126
+ end
127
+ end