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