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,18 @@
1
+ module DesignShell
2
+ module Utils
3
+ def self.lookupItems(aDeployNode, aKeyChain)
4
+ result = {}
5
+ REXML::XPath.each(aDeployNode,'item') do |n|
6
+ name = n.attribute('name').to_s.to_nil
7
+ key = n.attribute('key').to_s.to_nil || name
8
+ next unless name
9
+ if text = n.text.to_nil # value in node
10
+ result[name] = text
11
+ else # value in @params['deploy_creds']
12
+ result[key] = aKeyChain.get(key.to_sym) if key
13
+ end
14
+ end
15
+ result
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module DesignShell
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'designshell/version'
2
+ require 'osx_keychain'
3
+ require 'gli'
4
+ require 'git'
5
+ require 'buzzcore'
6
+ require 'buzzcore_mods'
7
+ require 'termios'
8
+ require 'highline/import'
9
+ require 'fileutils'
10
+ require 'net/ssh'
11
+ require 'uri'
12
+
13
+ require 'designshell/utils'
14
+ require 'designshell/context'
15
+ require 'designshell/key_chain'
16
+ require 'designshell/repo'
17
+ require 'designshell/repo_server'
18
+ require 'designshell/deploy_plan'
19
+ require 'designshell/core'
@@ -0,0 +1,180 @@
1
+ module DesignShellServer
2
+ class Command
3
+
4
+ attr_accessor :core,:context,:line,:command,:id,:params,:repo
5
+
6
+ def initialize(aCore,aLine,aCommandName=nil)
7
+ @core = aCore
8
+ @context = aCore && aCore.context
9
+ @line = aLine
10
+ tl = aLine.dup
11
+ cmd = tl.extract!(/^[A-Z0-9_]+/)
12
+ @command = aCommandName || cmd
13
+ tl.bite! ' '
14
+ @id = tl.extract!(/^[a-z0-9]+/)
15
+ tl.bite! ' '
16
+ @params = ::JSON.parse(tl) if @params = tl.to_nil
17
+ end
18
+
19
+ def execute
20
+ self.send @command.to_sym
21
+ end
22
+
23
+ def writeline(aString)
24
+ @context.stdout.puts aString
25
+ end
26
+
27
+ # Prepares repo in cache dir for site
28
+ # requires params: repo_url,site
29
+ def prepare_cache # {:url=>'git://github.com/ddssda', :branch=>'master', :commit=>'ad452bcd'}
30
+ url = @params['repo_url']
31
+ site = @params['site']
32
+ wd = @core.working_dir_from_site(site)
33
+
34
+ @repo = DesignShell::Repo.new
35
+ suitable = if File.exists?(wd)
36
+ @repo.open wd
37
+ @repo.origin.url==url
38
+ else
39
+ false
40
+ end
41
+
42
+ if suitable
43
+ @repo.fetch
44
+ else
45
+ if File.exists? wd
46
+ raise RuntimeError.new('almost did bad delete') if !@core.cache_dir || @core.cache_dir.length<3 || !wd.begins_with?(@core.cache_dir)
47
+ FileUtils.rm_rf wd
48
+ end
49
+ @repo.clone(url, wd)
50
+ end
51
+ end
52
+
53
+ # Switches @repo to given branch and/or commit
54
+ # Should call prepare_cache first to create @repo
55
+ # requires params: branch and/or commit
56
+ def checkout_branch_commit
57
+ #url = @params['repo_url']
58
+ #site = @params['site']
59
+ #wd = @core.working_dir_from_site(site)
60
+ branch = @params['branch'] || 'master'
61
+ commit = @params['commit']
62
+ @repo.checkout(commit,branch)
63
+ #perhaps use reset --hard here
64
+ if (commit)
65
+ @repo.merge(commit,['--ff-only'])
66
+ else
67
+ @repo.merge('origin/'+branch,['--ff-only'])
68
+ end
69
+ end
70
+
71
+ # Determines whether to do an incremental or complete deploy and deploys current files in repo working dir to repo_url
72
+ # requires :
73
+ # uses: site_client.deploy_status
74
+ # params: deploy_cred
75
+ def deploy
76
+ deployPlanString = @repo.get_file_content('.deploy_plan.xml',@params['commit']||@params['branch'])
77
+ xmlRoot = XmlUtils.get_xml_root(deployPlanString)
78
+ # select plan
79
+ planNode = XmlUtils.single_node(xmlRoot,'plan')
80
+ # for each deploy
81
+ deployNode = XmlUtils.single_node(planNode,'deploy')
82
+ # create client for kind/method
83
+ @site_client = DesignShell::SiteClient.new({
84
+ :site_url => @params['site_url'],
85
+ :site_username => @params['site_username'],
86
+ :site_password => @params['site_password'],
87
+ })
88
+ ds = @site_client.deploy_status
89
+ site_repo_url = ds && ds['repo_url'].to_nil
90
+ site_branch = ds && ds['branch'].to_nil
91
+ site_commit = ds && ds['commit'].to_nil
92
+ repo_url = @repo.url
93
+ # @todo must limit uploads to build folder
94
+ fromPath = MiscUtils.ensure_slashes(XmlUtils.peek_node_value(deployNode,'fromPath','/'),false,true) # eg. /build/bigcommerce effectively selects a subfolder that should be debased
95
+ toPath = MiscUtils.ensure_slashes(XmlUtils.peek_node_value(deployNode,'toPath','/'),false,true) # eg. / effectively the new base for these files
96
+ if site_repo_url && site_repo_url==repo_url && site_branch && site_commit
97
+ # incremental
98
+ changes = @repo.changesBetweenCommits(site_commit,@repo.head.to_s)
99
+ uploads,deletes = convertChangesToUploadsDeletes(changes)
100
+ uploads.delete_if { |fp| !fp.begins_with?(fromPath) }
101
+ deletes.delete_if { |fp| !fp.begins_with?(fromPath) }
102
+ @site_client.delete_files(deletes,fromPath,toPath)
103
+ @site_client.upload_files(@repo.path,uploads,fromPath,toPath)
104
+ @site_client.deploy_status = {
105
+ :repo_url => @repo.url,
106
+ :branch => @repo.branch,
107
+ :commit => @repo.head.to_s,
108
+ :fromPath => fromPath,
109
+ :toPath => toPath
110
+ }
111
+ else
112
+ # complete
113
+ # for now, just deploy all files in wd, creating folders as necessary
114
+ # later, delete remote files not in wd except for eg. .deploy-status.xml and perhaps upload folders
115
+ uploads = MiscUtils.recursive_file_list(@repo.path,false)
116
+ uploads.delete_if do |fp|
117
+ !fp.begins_with?(fromPath) || fp.begins_with?('.git/')
118
+ end
119
+ @site_client.upload_files(@repo.path,uploads,fromPath,toPath)
120
+ @site_client.deploy_status = {
121
+ :repo_url => @repo.url,
122
+ :branch => @repo.branch,
123
+ :commit => @repo.head.to_s,
124
+ :fromPath => fromPath,
125
+ :toPath => toPath
126
+ }
127
+ end
128
+ end
129
+
130
+ # Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T)
131
+ def convertChangesToUploadsDeletes(changes)
132
+ uploads = []
133
+ deletes = []
134
+ changes.each do |line|
135
+ continue if line==""
136
+ tabi = line.index("\t")
137
+ status = line[0,tabi]
138
+ path = line[tabi+1..-1]
139
+ if status.index('D')
140
+ deletes << path
141
+ else
142
+ uploads << path
143
+ end
144
+ end
145
+ return uploads,deletes
146
+ end
147
+
148
+ def DUMMY
149
+ id = StringUtils.random_word(8,8)
150
+ writeline "RECEIVED "+id
151
+ sleep 1
152
+ detail = ::JSON.generate({:this=>5, :that=>'ABC'}) #JSON.parse(document) or JSON.generate(data)
153
+ writeline ['PROGRESS',id,detail].join(' ')
154
+ sleep 1
155
+ detail = ::JSON.generate({:result=>123}) #JSON.parse(document) or JSON.generate(data)
156
+ writeline ['COMPLETE',id,detail].join(' ')
157
+ end
158
+
159
+ def QUICK
160
+ id = StringUtils.random_word(8,8)
161
+ writeline "RECEIVED "+id
162
+ writeline "COMPLETE "+id
163
+ end
164
+
165
+ def DEPLOY # {}
166
+ id = StringUtils.random_word(8,8)
167
+ writeline "RECEIVED "+id
168
+ detail =
169
+ writeline ['PROGRESS',id,::JSON.generate({:message => 'preparing cache'})].join(' ')
170
+ prepare_cache
171
+ writeline ['PROGRESS',id,::JSON.generate({:message => 'checkout'})].join(' ')
172
+ checkout_branch_commit
173
+ writeline ['PROGRESS',id,::JSON.generate({:message => 'deploying'})].join(' ')
174
+ deploy
175
+ writeline "COMPLETE "+id
176
+ end
177
+
178
+
179
+ end
180
+ end
@@ -0,0 +1,41 @@
1
+ module DesignShellServer
2
+ class Core
3
+
4
+ attr_reader :context
5
+
6
+ def initialize(aContext)
7
+ @context = aContext
8
+ end
9
+
10
+ def make_command(aLine)
11
+ command_name = aLine.scan(/^[A-Z0-9_]+/).pop.to_nil
12
+ return nil unless command_name && DesignShellServer::Command.instance_methods.include?(command_name)
13
+ return DesignShellServer::Command.new(self,aLine,command_name)
14
+ end
15
+
16
+ def run
17
+ if line = ENV['SSH_ORIGINAL_COMMAND']
18
+ command = make_command(line)
19
+ command.execute
20
+ else
21
+ @context.stdout.print "\n>"
22
+ @context.stdin.each_line do |line| line.chomp! "\n"
23
+ command = make_command(line)
24
+ command.execute
25
+ @context.stdout.print "\n>"
26
+ end
27
+ end
28
+ end
29
+
30
+ def cache_dir
31
+ @cache_dir ||= MiscUtils.append_slash(@context.credentials[:cache_dir] || MiscUtils.make_temp_dir('DesignShellServer'))
32
+ end
33
+
34
+ def working_dir_from_site(aSite)
35
+ return nil unless aSite
36
+ aSite.gsub!(/[^a-zA-Z0-9.\-_]/,'_')
37
+ File.join(cache_dir,aSite)
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ require 'git'
2
+ require 'buzzcore'
3
+ require 'buzzcore_mods'
4
+ require 'net/dav'
5
+ require 'json'
6
+ require 'fileutils'
7
+ require 'uri'
8
+
9
+ #require 'termios'
10
+ #require 'highline/import'
11
+
12
+ require 'designshell/context'
13
+ require 'designshell/site_client'
14
+ require 'designshell/deploy_plan'
15
+ require 'designshell/repo'
16
+ require 'designshellserver/core'
17
+ require 'designshellserver/command'
@@ -0,0 +1,94 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ describe "KeyChain" do
5
+
6
+ keyChain = nil
7
+
8
+ before do
9
+ keyChain = DesignShell::KeyChain.new('DesignShellTest')
10
+ end
11
+
12
+ it "should write,read,check value" do
13
+ value = StringUtils.random_word(8,8)
14
+ keyChain.set('testKey',value)
15
+ readValue = keyChain.get('testKey')
16
+ readValue.should == value
17
+ end
18
+
19
+ it "should support get and set with a prefix" do
20
+ value1 = StringUtils.random_word(8,8)
21
+ value2 = StringUtils.random_word(8,8)
22
+ keyChain.set('testKey',value1)
23
+ keyChain.set('testKey',value2,'blah')
24
+ keyChain.get('testKey').should==value1
25
+ keyChain.get('testKey','blah').should==value2
26
+ end
27
+
28
+ it "should support multiple get" do
29
+ value1 = StringUtils.random_word(8,8)
30
+ value2 = StringUtils.random_word(8,8)
31
+ keyChain.set('testKey1',value1)
32
+ keyChain.set('testKey2',value2)
33
+ keyChain.get('testKey1').should==value1
34
+ keyChain.get('testKey2').should==value2
35
+ keyChain.get(['testKey1']).should=={'testKey1' => value1}
36
+ keyChain.get(['testKey2']).should=={'testKey2' => value2}
37
+ keyChain.get(['testKey1','testKey2']).should=={'testKey1' => value1,'testKey2' => value2}
38
+ keyChain.get(%w(testKey1 testKey2)).should=={'testKey1' => value1,'testKey2' => value2}
39
+ end
40
+
41
+ it "should support multiple get with a prefix" do
42
+ value1 = StringUtils.random_word(8,8)
43
+ value2 = StringUtils.random_word(8,8)
44
+ keyChain.set('testKey1','')
45
+ keyChain.set('testKey2','')
46
+ keyChain.set('testKey1',value1,'prefix1.')
47
+ keyChain.set('testKey2',value2,'prefix1.')
48
+ keyChain.get(%w(testKey1 testKey2)).should == {'testKey1' => '', 'testKey2' => ''}
49
+ keyChain.get(%w(testKey1 testKey2),'prefix1.').should == {'testKey1' => value1, 'testKey2' => value2}
50
+ keyChain.get(%w(testKey1 testKey2),'prefix1.',true).should == {'prefix1.testKey1' => value1, 'prefix1.testKey2' => value2}
51
+ end
52
+
53
+ it "should support multiple set" do
54
+ value1 = StringUtils.random_word(8,8)
55
+ value2 = StringUtils.random_word(8,8)
56
+ keyChain.set({
57
+ 'testKey1' => value1,
58
+ 'testKey2' => value2
59
+ })
60
+ keyChain.get('testKey1').should==value1
61
+ keyChain.get('testKey2').should==value2
62
+ end
63
+
64
+ DEPLOY_XML = <<EOS
65
+ <deploy>
66
+ <kind>BigCommerce</kind>
67
+ <method>WebDav</method>
68
+ <fromPath>/build/bigcommerce</fromPath>
69
+ <toPath>/</toPath>
70
+ <item name="itemX">some item x</item>
71
+ <item name="itemY" key="itemYYY">YYY</item>
72
+ <item name="itemZ"></item>
73
+ <item name="itemZZ"/>
74
+ </deploy>
75
+ EOS
76
+
77
+ it "should support DesignShell::Utils.lookupItems" do
78
+ values = {
79
+ 'itemX' => 'never read this',
80
+ 'itemY' => 'never read this',
81
+ 'itemYYY' => 'YYYYY',
82
+ 'itemZ' => 'ZZZ',
83
+ 'itemZZ' => 'ZZZZZ',
84
+ }
85
+ keyChain.set(values)
86
+ deployXml = XmlUtils.get_xml_root(DEPLOY_XML)
87
+ result = DesignShell::Utils.lookupItems(deployXml,keyChain)
88
+ result['itemX'].should=='some item x'
89
+ result['itemY'].should=='YYY' # text value overrides keychain
90
+ result['itemZ'].should==values['itemZ']
91
+ result['itemZZ'].should==values['itemZZ']
92
+ end
93
+
94
+ end
@@ -0,0 +1,54 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+ require "fileutils"
4
+
5
+ describe "RepoServer" do
6
+
7
+ testFolder = nil
8
+ before do
9
+ testFolder = Dir.mktmpdir('Repo_spec-')
10
+
11
+ cred = Credentials.new(:designshell)
12
+
13
+ end
14
+
15
+ after do
16
+ FileUtils.rm_rf testFolder if testFolder
17
+ end
18
+
19
+ it "should list repos" do
20
+ keyChain = DesignShell::KeyChain.new('DesignShell')
21
+ #keyChain.set({
22
+ # :oauth_token => 'OAuth consumer Key',
23
+ # :oauth_secret => 'OAuth consumer Secret',
24
+ # :login => 'username, not email address',
25
+ # :password => 'user password'
26
+ #},'RepoServer.')
27
+ repoServer = DesignShell::RepoServer.new
28
+ # should move values to credentials that looks up keyChain
29
+ values = keyChain.get([:oauth_token,:oauth_secret,:login,:password],'RepoServer.').symbolize_keys
30
+ repoServer.setup(values)
31
+
32
+ result = repoServer.repos #"[#<Hashie::Mash is_private=true name="test1" owner="buzzware" scm="git" slug="test1">]"
33
+ result.class.should==Array
34
+ result.length.should > 0
35
+ result.first.scm.should=='git'
36
+ end
37
+
38
+ it "should clone the first repo" do
39
+ keyChain = DesignShell::KeyChain.new('DesignShell')
40
+ repoServer = DesignShell::RepoServer.new
41
+ values = keyChain.get([:oauth_token,:oauth_secret,:login,:password],'RepoServer.').symbolize_keys
42
+ repoServer.setup(values)
43
+ repos = repoServer.repos
44
+ repos.length.should > 0
45
+ repo = repos && repos.first
46
+
47
+ url = "git@bitbucket.org:#{repo.owner}/#{repo.slug}.git"
48
+ repo = DesignShell::Repo.new
49
+ result = repo.clone(url, testFolder)
50
+ repo.path.should == testFolder
51
+ repo.branches.class.should == Git::Branches
52
+ end
53
+
54
+ end
data/spec/Repo_spec.rb ADDED
@@ -0,0 +1,105 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+ require "fileutils"
4
+
5
+ describe "Repo" do
6
+
7
+ testFolder = nil
8
+ before do
9
+ testFolder = MiscUtils.real_path(Dir.mktmpdir('Repo_spec-'))
10
+ end
11
+
12
+ after do
13
+ FileUtils.rm_rf testFolder if testFolder
14
+ end
15
+
16
+
17
+ COMMIT_RESULT1 = "[master (root-commit) 6bdd9e1] first commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file1.txt"
18
+
19
+ it "commit should create commit object or string message" do
20
+ repo = DesignShell::Repo.new
21
+ repo.init testFolder
22
+
23
+ file1 = File.join(testFolder,'file1.txt')
24
+ content11 = '11111'
25
+ MiscUtils.string_to_file(content11,file1)
26
+ repo.add 'file1.txt'
27
+ commit1 = repo.commit_all('first commit')
28
+ commit1.class.should == Git::Object::Commit
29
+
30
+ commit2 = repo.commit_all('second commit without changes')
31
+ commit2.should == nil
32
+ end
33
+
34
+ it "create a repo, add file, commit, change, commit, reset, check" do
35
+ repo = DesignShell::Repo.new
36
+ repo.init testFolder
37
+ repo.path.should == MiscUtils.real_path(testFolder)
38
+
39
+ file1 = File.join(testFolder,'file1.txt')
40
+ content11 = '11111'
41
+ MiscUtils.string_to_file(content11,file1)
42
+ repo.git.add 'file1.txt'
43
+ commit1 = repo.commit_all('first commit')
44
+
45
+ content12 = '11111-some more text'
46
+ MiscUtils.string_to_file(content12,file1)
47
+ commit2 = repo.commit_all('second commit')
48
+
49
+ read_content = MiscUtils.string_from_file(file1)
50
+ read_content.should == content12
51
+
52
+ repo.reset_hard(commit1)
53
+
54
+ read_content = MiscUtils.string_from_file(file1)
55
+ read_content.should == content11
56
+ end
57
+
58
+ it "should download a remote repo and check log, then re-open it and check log again" do
59
+ repo = DesignShell::Repo.new
60
+ url = "git@github.com:buzzware/underscore_plus.git"
61
+ repo.clone(url, testFolder)
62
+ repo.path.should == testFolder
63
+ repo.log.first.class.should == Git::Object::Commit
64
+
65
+ repo = DesignShell::Repo.new
66
+ repo.open testFolder
67
+ repo.path.should == testFolder
68
+ repo.log.first.class.should == Git::Object::Commit
69
+ repo.origin.url==url
70
+ end
71
+
72
+ it "should download a remote repo and get diffs between commits" do
73
+ repo = DesignShell::Repo.new
74
+ url = "git@github.com:buzzware/underscore_plus.git"
75
+ repo.clone(url, testFolder)
76
+
77
+ commit1 = "4b133ff8825bbd488ba61fa3e3b82a5fa746ac6a"
78
+ commit2 = "d1b8440dc730ceb4471fbe7c42ccfac94ea12799"
79
+ changes = repo.changesBetweenCommits(commit1,commit2)
80
+ changes.should==["A\tunderscore_plus.js"]
81
+ changes = repo.changesBetweenCommits(commit2,commit1)
82
+ changes.should==["D\tunderscore_plus.js"]
83
+ end
84
+
85
+ it "should get contents of a given file from a given commit" do
86
+ repo = DesignShell::Repo.new
87
+ url = "git@github.com:buzzware/underscore_plus.git"
88
+ repo.clone(url, testFolder)
89
+
90
+ commit1 = "4b133ff8825bbd488ba61fa3e3b82a5fa746ac6a"
91
+ commit2 = "d1b8440dc730ceb4471fbe7c42ccfac94ea12799"
92
+ file1 = "README.md"
93
+ file2 = "underscore_plus.js"
94
+
95
+ readme = repo.get_file_content(file1,commit1)
96
+ readme.is_a?(String).should==true
97
+ readme.size.should > 0
98
+ code = repo.get_file_content(file2,commit1)
99
+ code.should==nil
100
+ code = repo.get_file_content(file2,commit2)
101
+ code.is_a?(String).should==true
102
+ code.size.should > 0
103
+ end
104
+
105
+ end
@@ -0,0 +1,29 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ describe "build" do
5
+
6
+ testFolder = nil
7
+ before do
8
+ testFolder = Dir.mktmpdir('Repo_spec-')
9
+ end
10
+
11
+ after do
12
+ FileUtils.rm_rf testFolder if testFolder
13
+ end
14
+
15
+ #it "should build source folder into build folder" do
16
+ # context = DesignShell::Context.new()
17
+ # ds = DesignShell::Core.new(:context => context)
18
+ # ds.build
19
+ #end
20
+
21
+ #it "should commit the repository" do
22
+ # context = DesignShell::Context.new()
23
+ # repo = DesignShell::Repo.new
24
+ # repo.configure()
25
+ # repo.clone("git@github.com:buzzware/underscore_plus.git", testFolder)
26
+ # ds = DesignShell::Core.new(:context => context, :repo => repo)
27
+ # ds.ensure_repo_open.commit_all(context)
28
+ #end
29
+ end
@@ -0,0 +1,111 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ describe "client to server interaction" do
5
+
6
+ before do
7
+ @key_chain = DesignShell::KeyChain.new('DesignShellTest')
8
+ @credentials = Credentials.new('designshell')
9
+ Dir.chdir @credentials[:deploy_repo_path]
10
+ @context = DesignShell::Context.new(
11
+ :argv=>[],
12
+ :env=>{},
13
+ :stdout=>$stdout,
14
+ :stdin=>$stdin,
15
+ :stderr=>$stderr,
16
+ :key_chain=>@key_chain,
17
+ :credentials=>@credentials
18
+ )
19
+ end
20
+
21
+ it "should call QUICK and get results" do
22
+ dash = DesignShell::Core.new(
23
+ :context => @context
24
+ )
25
+ result = dash.call_server_command('QUICK')
26
+ puts result
27
+ result.begins_with?('RECEIVED').should == true
28
+ result.index('COMPLETE').should >= 0
29
+ end
30
+
31
+ it "should call deploy" do
32
+ dash = DesignShell::Core.new(
33
+ :context => @context
34
+ )
35
+ result = dash.deploy
36
+ puts result
37
+ result.begins_with?('RECEIVED').should == true
38
+ result.index('COMPLETE').should >= 0
39
+ end
40
+
41
+
42
+
43
+ #it "should connect to SSH server" do
44
+ # Net::SSH.start( @context.credentials[:deploy_host],nil) do |ssh|
45
+ #
46
+ # #result = ssh.exec!("ls")
47
+ # #puts result
48
+ #
49
+ #
50
+ # #ssh.open_channel{|channel| #get root privelages
51
+ # ##configure behavior of channel
52
+ # #channel.on_data{|channel, data|
53
+ # # puts "#{data}"
54
+ # # if data =~ /^Password:/
55
+ # # channel.send_data("#{PASSWORD}\n")
56
+ # # elsif data =~ /root@/
57
+ # # channel.exec("tail /some/log/file.txt")
58
+ # # channel.on_data{"STOP LOOPING, DAMN YOU!"}
59
+ # # end
60
+ # #channel.on_close... (etc.)
61
+ # #
62
+ # #channel.request_pty do |ch,success|
63
+ # # if success
64
+ # # puts "pty successfully obtained"
65
+ # # else
66
+ # # puts "could not obtain pty"
67
+ # # end end
68
+ # #
69
+ # #channel.exec("sudoshell"){|channel, win| #custom sudo script.
70
+ # # if win
71
+ # # puts "ss command sent"
72
+ # # else puts "ss command FAIL"
73
+ # # end
74
+ # #}
75
+ # #
76
+ #
77
+ # ssh.open_channel do |channel|
78
+ # channel.on_data do |ch, data|
79
+ # puts "got stdout: #{data}"
80
+ # #channel.send_data "something for stdin\n"
81
+ # end
82
+ #
83
+ # channel.on_extended_data do |ch, type, data|
84
+ # puts "got stderr: #{data}"
85
+ # end
86
+ #
87
+ # channel.on_close do |ch|
88
+ # puts "channel is closing!"
89
+ # end
90
+ #
91
+ # channel.request_pty do |ch,success|
92
+ # if success
93
+ # puts "pty successfully obtained"
94
+ # else
95
+ # puts "could not obtain pty"
96
+ # end
97
+ # end
98
+ # #sleep 1
99
+ # result = channel.exec("DEPLOY") do |ch, success|
100
+ # abort "could not execute command" unless success
101
+ # end
102
+ # channel.wait
103
+ # puts result
104
+ # end
105
+ #
106
+ # ssh.loop
107
+ #
108
+ # end
109
+ #end
110
+
111
+ end
@@ -0,0 +1,18 @@
1
+ require "rspec"
2
+ require "rspec_helper"
3
+
4
+ describe "DesignShell::Context" do
5
+
6
+ it "should find repo path upward" do
7
+ tempdir = MiscUtils.real_path(MiscUtils.make_temp_dir('designshell_context_spec'))
8
+ Dir.mkdir(git_dir = File.join(tempdir,'.git'))
9
+ Dir.mkdir(File.join(tempdir,'one'))
10
+ orange = File.join(tempdir,'one/apple/orange')
11
+ FileUtils.mkpath(orange)
12
+ Dir.mkdir(File.join(tempdir,'two'))
13
+ Dir.chdir(orange)
14
+ context = DesignShell::Context.new({})
15
+ context.pwd.should==orange
16
+ context.find_git_root.should==tempdir
17
+ end
18
+ end