designshell 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +18 -0
  2. data/.idea/.name +1 -0
  3. data/.idea/.rakeTasks +7 -0
  4. data/.idea/codeStyleSettings.xml +13 -0
  5. data/.idea/compiler.xml +25 -0
  6. data/.idea/copyright/profiles_settings.xml +5 -0
  7. data/.idea/encodings.xml +5 -0
  8. data/.idea/misc.xml +11 -0
  9. data/.idea/modules.xml +11 -0
  10. data/.idea/scopes/scope_settings.xml +5 -0
  11. data/.idea/vcs.xml +9 -0
  12. data/Gemfile +2 -0
  13. data/Gemfile.lock +196 -0
  14. data/LICENSE +22 -0
  15. data/README.md +35 -0
  16. data/README.rdoc +6 -0
  17. data/Rakefile +46 -0
  18. data/bin/designshelld.example.sh +5 -0
  19. data/bin/designshelld.example2.sh +3 -0
  20. data/bin/designshellserver +22 -0
  21. data/bin/ds +177 -0
  22. data/designshell.gemspec +40 -0
  23. data/designshell.iml +84 -0
  24. data/designshell.rdoc +5 -0
  25. data/features/designshell.feature +8 -0
  26. data/features/step_definitions/designshell_steps.rb +6 -0
  27. data/features/support/env.rb +15 -0
  28. data/lib/buzzcore_mods.rb +19 -0
  29. data/lib/designshell/context.rb +48 -0
  30. data/lib/designshell/core.rb +78 -0
  31. data/lib/designshell/deploy_plan.rb +40 -0
  32. data/lib/designshell/key_chain.rb +40 -0
  33. data/lib/designshell/repo.rb +112 -0
  34. data/lib/designshell/repo_server.rb +25 -0
  35. data/lib/designshell/site_client.rb +141 -0
  36. data/lib/designshell/utils.rb +18 -0
  37. data/lib/designshell/version.rb +3 -0
  38. data/lib/designshell.rb +19 -0
  39. data/lib/designshellserver/command.rb +180 -0
  40. data/lib/designshellserver/core.rb +41 -0
  41. data/lib/designshellserver.rb +17 -0
  42. data/spec/KeyChain_spec.rb +94 -0
  43. data/spec/RepoServer_spec.rb +54 -0
  44. data/spec/Repo_spec.rb +105 -0
  45. data/spec/build_spec.rb +29 -0
  46. data/spec/client_to_server_spec.rb +111 -0
  47. data/spec/designshell_context_spec.rb +18 -0
  48. data/spec/designshell_core_spec.rb +45 -0
  49. data/spec/rspec_helper.rb +8 -0
  50. data/spec/server/deploy_spec.rb +210 -0
  51. data/spec/server/dummy_spec.rb +52 -0
  52. data/spec/site_client_spec.rb +90 -0
  53. data/test/default_test.rb +14 -0
  54. data/test/test_helper.rb +9 -0
  55. data/testmart.iml +9 -0
  56. metadata +390 -0
@@ -0,0 +1,45 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ describe "DesignShell" do
5
+
6
+ it "deploy_items_values should work" do
7
+
8
+ key_chain = DesignShell::KeyChain.new('DesignShellTest')
9
+ context = DesignShell::Context.new(
10
+ :argv=>[],
11
+ :env=>{},
12
+ :stdout=>$stdout,
13
+ :stdin=>$stdin,
14
+ :stderr=>$stderr,
15
+ :key_chain=>key_chain,
16
+ :credentials=>Credentials.new('designshell')
17
+ )
18
+
19
+ deployNodeString = <<EOS
20
+ <deployPlan site="testmart.com">
21
+ <plan name="main" branch="master"> <!-- This plan will only work on master branch. Remove branch attribute to apply to any branch -->
22
+ <deploy>
23
+ <kind>BigCommerce</kind>
24
+ <method>WebDav</method>
25
+ <fromPath>/build/bigcommerce</fromPath>
26
+ <toPath>/content/deploy_spec</toPath>
27
+ <item name="site_url">#{context.credentials[:bigcommerce_sandbox_url]}</item> <!-- get this from user creds -->
28
+ <item name="site_username" key="site_user"/>
29
+ <item name="site_password" key="site_password"/>
30
+ </deploy>
31
+ </plan>
32
+ </deployPlan>
33
+ EOS
34
+
35
+ core = DesignShell::Core.new(:context=>context)
36
+ core.deploy_plan(deployNodeString)
37
+ core.deploy_plan.deploy_items_values.should == {
38
+ "site_url" => context.credentials[:bigcommerce_sandbox_url],
39
+ "site_username" => context.key_chain["site_user"],
40
+ "site_password" => context.key_chain["site_password"]
41
+ }
42
+ end
43
+
44
+
45
+ end
@@ -0,0 +1,8 @@
1
+ require 'designshell'
2
+ require 'designshellserver'
3
+ require 'gli'
4
+ require 'git'
5
+ #require 'buzzcore'
6
+ require 'termios'
7
+ require 'highline/import'
8
+ require 'json'
@@ -0,0 +1,210 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ RSpec.configure do |c|
5
+ # declare an exclusion filter
6
+ c.filter_run_excluding :broken => true
7
+ end
8
+
9
+ describe "DEPLOY command" do
10
+
11
+ before do
12
+
13
+ @key_chain = DesignShell::KeyChain.new('DesignShellTest')
14
+ @credentials = Credentials.new('designshell')
15
+ #key_chain.set('site_user',creds[:site_user])
16
+ #key_chain.set('site_password',creds[:site_password])
17
+
18
+ @context = DesignShell::Context.new(
19
+ :argv=>[],
20
+ :env=>{},
21
+ :stdout=>$stdout,
22
+ :stdin=>$stdin,
23
+ :stderr=>$stderr,
24
+ :key_chain=>@key_chain,
25
+ :credentials=>@credentials
26
+ )
27
+ #$stdout.sync=true # no buffer delay
28
+ end
29
+
30
+ it "should prepare_cache not pre-existing" do
31
+ core = DesignShellServer::Core.new(@context)
32
+ site = "happy.com.au"
33
+ repo_url = "git@github.com:buzzware/underscore_plus.git"
34
+ wd = core.working_dir_from_site(site)
35
+ FileUtils.rm_rf wd
36
+ command = DesignShellServer::Command.new(core,"DEPLOY "+JSON.generate({:repo_url=>repo_url,:site=>site}))
37
+ command.prepare_cache
38
+ repo = DesignShell::Repo.new
39
+ repo.open wd
40
+ repo.origin.url==repo_url
41
+ end
42
+
43
+ it "should prepare_cache pre-existing, to given commit" do
44
+ core = DesignShellServer::Core.new(@context)
45
+ site = "happy.com.au"
46
+ repo_url = "git@github.com:buzzware/underscore_plus.git"
47
+ wd = core.working_dir_from_site(site)
48
+ commit1 = '4b133ff8825bbd488ba61fa3e3b82a5fa746ac6a'
49
+ FileUtils.rm_rf wd
50
+ command = DesignShellServer::Command.new(core,"DEPLOY "+JSON.generate({
51
+ :repo_url=>repo_url,
52
+ :site=>site,
53
+ :commit=>commit1
54
+ }))
55
+ command.prepare_cache
56
+ head_commit = command.repo.head.to_s
57
+ head_commit.should_not==commit1
58
+ command.checkout_branch_commit
59
+ command.repo.head.to_s.should==commit1
60
+
61
+ # now try checkout_branch_commit with no specified branch or commit - should checkout head
62
+ command = DesignShellServer::Command.new(core,"DEPLOY "+JSON.generate({
63
+ :repo_url=>repo_url,
64
+ :site=>site
65
+ }))
66
+ command.repo = DesignShell::Repo.new
67
+ command.repo.open wd
68
+ command.checkout_branch_commit
69
+ command.repo.head.to_s.should==head_commit
70
+ end
71
+
72
+ it "should put file when folder doesn't exist" do
73
+ site_client = DesignShell::SiteClient.new({
74
+ :site_url => @context.credentials[:bigcommerce_sandbox_url],
75
+ :site_username => @context.credentials[:bigcommerce_sandbox_username],
76
+ :site_password => @context.credentials[:bigcommerce_sandbox_password]
77
+ })
78
+ site_client.delete '/content/deploy_spec'
79
+ site_client.deploy_status = nil
80
+
81
+ content1 = StringUtils.random_word(8,8)
82
+ source = MiscUtils.make_temp_file(nil,nil,content1)
83
+ dest = "/content/deploy_spec/content/content1.txt"
84
+ site_client.put_file(source,dest)
85
+
86
+ content2 = site_client.get_string(dest)
87
+ content2.should == content1
88
+ end
89
+
90
+
91
+ it "should deploy, no existing cache" do
92
+
93
+ # set up scratch repo with basic site
94
+ @context.pwd = MiscUtils.append_slash(MiscUtils.real_path(MiscUtils.make_temp_dir('deploy_spec')))
95
+ Dir.chdir @context.pwd
96
+
97
+ repo = DesignShell::Repo.new
98
+ repo.clone @context.credentials[:scratch_repo_url],@context.pwd
99
+ files_to_rm = Dir.glob(@context.pwd+'*').filter_exclude(@context.pwd+'.git')
100
+ if !files_to_rm.empty?
101
+ files_to_rm.each {|fp| FileUtils.rm_rf fp}
102
+ repo.commit_all "cleared"
103
+ end
104
+ FileUtils.mkdir_p 'build'
105
+ FileUtils.mkdir_p 'build/bigcommerce'
106
+ FileUtils.mkdir_p 'build/bigcommerce/template'
107
+ MiscUtils.string_to_file "<html><body>a bigcommerce template</body></html>",'build/bigcommerce/template/template.html'
108
+ FileUtils.mkdir_p 'build/bigcommerce/content'
109
+ MiscUtils.string_to_file "first content file",'build/bigcommerce/content/content1.txt'
110
+ MiscUtils.string_to_file "second content file",'build/bigcommerce/content/content2.txt'
111
+ FileUtils.mkdir_p 'build/tumblr'
112
+ MiscUtils.string_to_file "<html><body>a tumblr template</body></html>",'build/tumblr/template.html'
113
+
114
+ deploy_plan = <<EOS
115
+ <?xml version="1.0" encoding="UTF-8"?>
116
+ <deployPlan site="testmart.com">
117
+ <plan name="main">
118
+ <deploy>
119
+ <kind>BigCommerce</kind>
120
+ <method>WebDav</method>
121
+ <fromPath>/build/bigcommerce</fromPath>
122
+ <toPath>/content/deploy_spec</toPath>
123
+ <item name="site_url">#{@context.credentials[:bigcommerce_sandbox_url]}</item> <!-- get this from user creds -->
124
+ <item name="site_username" key="site_user"/>
125
+ <item name="site_password" key="site_password"/>
126
+ </deploy>
127
+ </plan>
128
+ </deployPlan>
129
+ EOS
130
+ MiscUtils.string_to_file deploy_plan,'.deploy_plan.xml'
131
+ FileUtils.cp_r 'build','source'
132
+ repo.add '.'
133
+ repo.commit_all "first test files"
134
+ repo.push
135
+
136
+ # clear deploy destination
137
+ site_client = DesignShell::SiteClient.new({
138
+ :site_url => @context.credentials[:bigcommerce_sandbox_url],
139
+ :site_username => @context.credentials[:bigcommerce_sandbox_username],
140
+ :site_password => @context.credentials[:bigcommerce_sandbox_password]
141
+ })
142
+ site_client.delete '/content/deploy_spec'
143
+ site_client.deploy_status = nil
144
+
145
+ # setup client to deploy
146
+ dash = DesignShell::Core.new(
147
+ :context => @context,
148
+ :repo => repo
149
+ )
150
+
151
+ # stub out call_server_command and get line
152
+ line_for_server = nil
153
+ params_for_server = nil
154
+ dash.stub!(:call_server_command) do |aCommand, aParams|
155
+ line_for_server = aCommand
156
+ params_for_server = aParams
157
+ line_for_server += " " + JSON.generate(aParams) if aParams
158
+ end
159
+ dash.deploy
160
+
161
+ # server receives line from client
162
+ serverContext = DesignShell::Context.new(
163
+ :argv=>[],
164
+ :env=>{},
165
+ :stdout=>$stdout,
166
+ :stdin=>$stdin,
167
+ :stderr=>$stderr,
168
+ :key_chain=>@key_chain,
169
+ :credentials=>@credentials
170
+ )
171
+ server = DesignShellServer::Core.new(serverContext)
172
+ FileUtils.rm_rf server.working_dir_from_site(params_for_server['site']) if params_for_server['site']
173
+ command = server.make_command(line_for_server)
174
+ command.execute
175
+
176
+ # check deployed files
177
+ deployed_files = site_client.list_files('/content/deploy_spec',true)
178
+ deployed_files.sort.should==[
179
+ "content/content1.txt",
180
+ "content/content2.txt",
181
+ "template/template.html"
182
+ ]
183
+ site_client.deploy_status.should == {
184
+ 'repo_url' => repo.url,
185
+ 'branch' => repo.branch,
186
+ 'commit' => repo.head.to_s,
187
+ 'fromPath' => 'build/bigcommerce/',
188
+ 'toPath' => 'content/deploy_spec/'
189
+ }
190
+
191
+ MiscUtils.string_to_file "third content file",'build/bigcommerce/content/content3.txt'
192
+ FileUtils.rm 'build/bigcommerce/content/content2.txt'
193
+ repo.add '.'
194
+ repo.commit_all "added content3, removed content2"
195
+ repo.push
196
+
197
+ command = server.make_command(line_for_server)
198
+ command.execute
199
+
200
+ # check deployed changes
201
+ deployed_files = site_client.list_files('/content/deploy_spec',true).sort
202
+ deployed_files.should==[
203
+ "content/content1.txt",
204
+ "content/content3.txt",
205
+ "template/template.html"
206
+ ]
207
+
208
+ end
209
+
210
+ end
@@ -0,0 +1,52 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ describe "DUMMY command" do
5
+
6
+ before do
7
+ @context = DesignShell::Context.new(
8
+ :argv=>[],
9
+ :env=>{},
10
+ :stdout=>$stdout,
11
+ :stdin=>$stdin,
12
+ :stderr=>$stderr,
13
+ :credentials=>Credentials.new('designshell')
14
+ )
15
+ @core = DesignShellServer::Core.new(@context)
16
+ #$stdout.sync=true # no buffer delay
17
+ end
18
+
19
+ it "should crack correctly" do
20
+ command = DesignShellServer::Command.new(@core,'DUMMY')
21
+ command.command.should=='DUMMY'
22
+ command.id.should==nil
23
+ command.params.should==nil
24
+
25
+ command = DesignShellServer::Command.new(@core,'DUMMY sadf567as756df')
26
+ command.command.should=='DUMMY'
27
+ command.id.should=='sadf567as756df'
28
+ command.params.should==nil
29
+
30
+ command = DesignShellServer::Command.new(@core,'DUMMY sadf567as756df {"this": 345345, "that": true}')
31
+ command.command.should=='DUMMY'
32
+ command.id.should=='sadf567as756df'
33
+ command.params.should=={"this"=>345345, "that"=>true}
34
+ end
35
+
36
+ it "should call dummy command" do
37
+ command = DesignShellServer::Command.new(@core,'DUMMY','DUMMY')
38
+ command.command.should=='DUMMY'
39
+ command.id.should==nil
40
+ command.params.should==nil
41
+ output = @context.capture_stdout do
42
+ command.execute
43
+ end
44
+ lines = output.split("\n")
45
+ lines[0].should match /^RECEIVED [a-z0-9]+$/
46
+ lines[1].should match /^PROGRESS [a-z0-9]+ \{.*\}$/
47
+ lines[2].should match /^COMPLETE [a-z0-9]+ \{.*\}$/
48
+ end
49
+
50
+
51
+
52
+ end
@@ -0,0 +1,90 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+ require 'securerandom'
4
+
5
+ describe "SiteClient" do
6
+
7
+ before do
8
+ creds = Credentials.new('designshell')
9
+ key_chain = DesignShell::KeyChain.new('DesignShellTest')
10
+ #key_chain.set('site_user',creds[:site_user])
11
+ #key_chain.set('site_password',creds[:site_password])
12
+
13
+ @context = DesignShell::Context.new(:key_chain=>key_chain, :credentials=>creds)
14
+ @client = DesignShell::SiteClient.new({
15
+ :site_url => creds[:bigcommerce_sandbox_url],
16
+ :site_username => creds[:bigcommerce_sandbox_username],
17
+ :site_password => creds[:bigcommerce_sandbox_password]
18
+ })
19
+ end
20
+
21
+ it "should connect and list" do
22
+ result = @client.ls
23
+ result.include?('content/').should==true
24
+ result.include?('template/').should==true
25
+ result = @client.ls('/')
26
+ result.include?('content/').should==true
27
+ result.include?('template/').should==true
28
+ result = @client.ls('template')
29
+ result.include?('Panels/').should==true
30
+ result.include?('Snippets/').should==true
31
+ end
32
+
33
+ it "should put a string to a file, then get and check" do
34
+ content = StringUtils.random_word(8,8)
35
+ path = '/content/testfile.txt'
36
+ @client.put_string(path,content)
37
+ content2 = @client.get_string(path)
38
+ content2.should == content
39
+ @client.delete(path)
40
+ end
41
+
42
+ it "should delete files" do
43
+ content = StringUtils.random_word(8,8)
44
+ path = '/content/testfile.txt'
45
+
46
+ @client.put_string(path,content)
47
+ @client.get_string(path).should == content
48
+ @client.delete(path)
49
+ @client.get_string(path).should==nil
50
+ @client.delete(path) # shouldn't blow up
51
+ end
52
+
53
+ it "should read and write the deploy_status" do
54
+ @client.deploy_status_file = '/content/.fake_deploy_status.txt'
55
+
56
+ @client.delete @client.deploy_status_file
57
+ @client.deploy_status == {}
58
+ content1 = {"commit" => "deadbeef"}
59
+ @client.deploy_status = content1
60
+ @client.deploy_status.should == content1
61
+ @client.delete @client.deploy_status_file
62
+ end
63
+
64
+ it "should upload and download a file and check" do
65
+ content = SecureRandom.random_bytes(8000)
66
+ tempfile = MiscUtils.make_temp_file(nil,nil,content)
67
+ remote_path = '/content/testfile.bin'
68
+ @client.put_file(tempfile,remote_path)
69
+ tempfile2 = MiscUtils.temp_file
70
+ @client.get_file(remote_path,tempfile2)
71
+ `cmp #{tempfile} #{tempfile2}`.should==''
72
+ @client.delete remote_path
73
+ end
74
+
75
+ it "should put file even when folder doesn't exist" do
76
+ content = StringUtils.random_word(8,8)
77
+ path = '/content/some/testfile.txt'
78
+ @client.delete('/content/some')
79
+ @client.exists?('/content/some').should==false
80
+ @client.get_string(path).should==nil
81
+ @client.ensure_folder_path(File.dirname(path))
82
+ @client.put_string(path,content)
83
+ content2 = @client.get_string(path)
84
+ content2.should == content
85
+ @client.delete('/content/some')
86
+ @client.exists?('/content/some').should==false
87
+ @client.exists?(path).should==false
88
+ end
89
+
90
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class DefaultTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def teardown
9
+ end
10
+
11
+ def test_the_truth
12
+ assert true
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+
3
+ # Add test libraries you want to use here, e.g. mocha
4
+
5
+ class Test::Unit::TestCase
6
+
7
+ # Add global extensions to the test case class here
8
+
9
+ end
data/testmart.iml ADDED
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$REPOS$/testmart" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
9
+