stackfu 0.1.0

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 (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