Class: DesignShellServer::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/designshellserver/command.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(aCore, aLine, aCommandName = nil) ⇒ Command

Returns a new instance of Command.



6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/designshellserver/command.rb', line 6

def initialize(aCore,aLine,aCommandName=nil)
	@core = aCore
	@context = aCore && aCore.context
	@line = aLine
	tl = aLine.dup
	cmd = tl.extract!(/^[A-Z0-9_]+/)
	@command = aCommandName || cmd
	tl.bite! ' '
	@id = tl.extract!(/^[a-z0-9]+/)
	tl.bite! ' '
	@params = ::JSON.parse(tl) if @params = tl.to_nil
end

Instance Attribute Details

#commandObject

Returns the value of attribute command.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def command
  @command
end

#contextObject

Returns the value of attribute context.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def context
  @context
end

#coreObject

Returns the value of attribute core.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def core
  @core
end

#idObject

Returns the value of attribute id.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def id
  @id
end

#lineObject

Returns the value of attribute line.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def line
  @line
end

#paramsObject

Returns the value of attribute params.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def params
  @params
end

#repoObject

Returns the value of attribute repo.



4
5
6
# File 'lib/designshellserver/command.rb', line 4

def repo
  @repo
end

Instance Method Details

#checkout_branch_commitObject

Switches @repo to given branch and/or commit Should call prepare_cache first to create @repo requires params: branch and/or commit



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/designshellserver/command.rb', line 56

def checkout_branch_commit
	#url = @params['repo_url']
	#site = @params['site']
	#wd = @core.working_dir_from_site(site)
	branch = @params['branch'] || 'master'
	commit = @params['commit']
	@repo.checkout(commit,branch)
	#perhaps use reset --hard here
	if (commit)
		@repo.merge(commit,['--ff-only'])
	else
		@repo.merge('origin/'+branch,['--ff-only'])
	end
end

#convertChangesToUploadsDeletes(changes) ⇒ Object

Added (A), Copied ©, Deleted (D), Modified (M), Renamed ®, have their type (i.e. regular file, symlink, submodule, …) changed (T)



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/designshellserver/command.rb', line 131

def convertChangesToUploadsDeletes(changes)
	uploads = []
	deletes = []
	changes.each do |line|
		continue if line==""
		tabi = line.index("\t")
		status = line[0,tabi]
		path = line[tabi+1..-1]
		if status.index('D')
			deletes << path
		else
			uploads << path
		end
	end
	return uploads,deletes
end

#deployObject

Determines whether to do an incremental or complete deploy and deploys current files in repo working dir to repo_url requires :

uses: site_client.deploy_status
params: deploy_cred


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/designshellserver/command.rb', line 75

def deploy
	deployPlanString = @repo.get_file_content('.deploy_plan.xml',@params['commit']||@params['branch'])
	xmlRoot = XmlUtils.get_xml_root(deployPlanString)
	# select plan
	planNode = XmlUtils.single_node(xmlRoot,'plan')
	# for each deploy
	deployNode = XmlUtils.single_node(planNode,'deploy')
	# create client for kind/method
	@site_client = DesignShell::SiteClient.new({
		:site_url => @params['site_url'],
		:site_username => @params['site_username'],
		:site_password => @params['site_password'],
	})
	ds = @site_client.deploy_status
	site_repo_url = ds && ds['repo_url'].to_nil
	site_branch = ds && ds['branch'].to_nil
	site_commit = ds && ds['commit'].to_nil
	repo_url = @repo.url
	# @todo must limit uploads to build folder
	fromPath = MiscUtils.ensure_slashes(XmlUtils.peek_node_value(deployNode,'fromPath','/'),false,true)    # eg. /build/bigcommerce effectively selects a subfolder that should be debased
	toPath = MiscUtils.ensure_slashes(XmlUtils.peek_node_value(deployNode,'toPath','/'),false,true)    # eg. / effectively the new base for these files
	if site_repo_url && site_repo_url==repo_url && site_branch && site_commit
		# incremental
		changes = @repo.changesBetweenCommits(site_commit,@repo.head.to_s)
		uploads,deletes = convertChangesToUploadsDeletes(changes)
		uploads.delete_if { |fp| !fp.begins_with?(fromPath) }
		deletes.delete_if { |fp| !fp.begins_with?(fromPath) }
		@site_client.delete_files(deletes,fromPath,toPath)
		@site_client.upload_files(@repo.path,uploads,fromPath,toPath)
		@site_client.deploy_status = {
			:repo_url => @repo.url,
			:branch => @repo.branch,
			:commit => @repo.head.to_s,
		  :fromPath => fromPath,
		  :toPath => toPath
		}
	else
		# complete
		# for now, just deploy all files in wd, creating folders as necessary
		# later, delete remote files not in wd except for eg. .deploy-status.xml and perhaps upload folders
		uploads = MiscUtils.recursive_file_list(@repo.path,false)
		uploads.delete_if do |fp|
			!fp.begins_with?(fromPath) || fp.begins_with?('.git/')
		end
		@site_client.upload_files(@repo.path,uploads,fromPath,toPath)
		@site_client.deploy_status = {
			:repo_url => @repo.url,
			:branch => @repo.branch,
			:commit => @repo.head.to_s,
			:fromPath => fromPath,
      :toPath => toPath
		}
	end
end

#DEPLOYObject

{}



165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/designshellserver/command.rb', line 165

def DEPLOY # {}
	id = StringUtils.random_word(8,8)
	writeline "RECEIVED "+id
	detail =
	writeline ['PROGRESS',id,::JSON.generate({:message => 'preparing cache'})].join(' ')
	prepare_cache
	writeline ['PROGRESS',id,::JSON.generate({:message => 'checkout'})].join(' ')
	checkout_branch_commit
	writeline ['PROGRESS',id,::JSON.generate({:message => 'deploying'})].join(' ')
	deploy
	writeline "COMPLETE "+id
end

#DUMMYObject



148
149
150
151
152
153
154
155
156
157
# File 'lib/designshellserver/command.rb', line 148

def DUMMY
	id = StringUtils.random_word(8,8)
	writeline "RECEIVED "+id
	sleep 1
	detail = ::JSON.generate({:this=>5, :that=>'ABC'}) #JSON.parse(document) or JSON.generate(data)
	writeline ['PROGRESS',id,detail].join(' ')
	sleep 1
	detail = ::JSON.generate({:result=>123}) #JSON.parse(document) or JSON.generate(data)
	writeline ['COMPLETE',id,detail].join(' ')
end

#executeObject



19
20
21
# File 'lib/designshellserver/command.rb', line 19

def execute
	self.send @command.to_sym
end

#prepare_cacheObject

Prepares repo in cache dir for site requires params: repo_url,site



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/designshellserver/command.rb', line 29

def prepare_cache # {:url=>'git://github.com/ddssda', :branch=>'master', :commit=>'ad452bcd'}
	url = @params['repo_url']
	site = @params['site']
	wd = @core.working_dir_from_site(site)

	@repo = DesignShell::Repo.new
	suitable = if File.exists?(wd)
		@repo.open wd
		@repo.origin.url==url
	else
		false
	end

	if suitable
		@repo.fetch
	else
		if File.exists? wd
			raise RuntimeError.new('almost did bad delete') if !@core.cache_dir || @core.cache_dir.length<3 || !wd.begins_with?(@core.cache_dir)
			FileUtils.rm_rf wd
		end
		@repo.clone(url, wd)
	end
end

#QUICKObject



159
160
161
162
163
# File 'lib/designshellserver/command.rb', line 159

def QUICK
	id = StringUtils.random_word(8,8)
	writeline "RECEIVED "+id
	writeline "COMPLETE "+id
end

#writeline(aString) ⇒ Object



23
24
25
# File 'lib/designshellserver/command.rb', line 23

def writeline(aString)
	@context.stdout.puts aString
end