designshell 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/codeStyleSettings.xml +13 -0
- data/.idea/compiler.xml +25 -0
- data/.idea/copyright/profiles_settings.xml +5 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/misc.xml +11 -0
- data/.idea/modules.xml +11 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +9 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +196 -0
- data/LICENSE +22 -0
- data/README.md +35 -0
- data/README.rdoc +6 -0
- data/Rakefile +46 -0
- data/bin/designshelld.example.sh +5 -0
- data/bin/designshelld.example2.sh +3 -0
- data/bin/designshellserver +22 -0
- data/bin/ds +177 -0
- data/designshell.gemspec +40 -0
- data/designshell.iml +84 -0
- data/designshell.rdoc +5 -0
- data/features/designshell.feature +8 -0
- data/features/step_definitions/designshell_steps.rb +6 -0
- data/features/support/env.rb +15 -0
- data/lib/buzzcore_mods.rb +19 -0
- data/lib/designshell/context.rb +48 -0
- data/lib/designshell/core.rb +78 -0
- data/lib/designshell/deploy_plan.rb +40 -0
- data/lib/designshell/key_chain.rb +40 -0
- data/lib/designshell/repo.rb +112 -0
- data/lib/designshell/repo_server.rb +25 -0
- data/lib/designshell/site_client.rb +141 -0
- data/lib/designshell/utils.rb +18 -0
- data/lib/designshell/version.rb +3 -0
- data/lib/designshell.rb +19 -0
- data/lib/designshellserver/command.rb +180 -0
- data/lib/designshellserver/core.rb +41 -0
- data/lib/designshellserver.rb +17 -0
- data/spec/KeyChain_spec.rb +94 -0
- data/spec/RepoServer_spec.rb +54 -0
- data/spec/Repo_spec.rb +105 -0
- data/spec/build_spec.rb +29 -0
- data/spec/client_to_server_spec.rb +111 -0
- data/spec/designshell_context_spec.rb +18 -0
- data/spec/designshell_core_spec.rb +45 -0
- data/spec/rspec_helper.rb +8 -0
- data/spec/server/deploy_spec.rb +210 -0
- data/spec/server/dummy_spec.rb +52 -0
- data/spec/site_client_spec.rb +90 -0
- data/test/default_test.rb +14 -0
- data/test/test_helper.rb +9 -0
- data/testmart.iml +9 -0
- 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,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
|
data/test/test_helper.rb
ADDED
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
|
+
|