Module: MrMurano::SyncUpDown
- Included in:
- ProductResources, SolutionBase
- Defined in:
- lib/MrMurano/SyncUpDown.rb
Instance Method Summary collapse
-
#docmp(itemA, itemB) ⇒ Object
True if itemA and itemB are different.
-
#dodiff(item) ⇒ Object
Call external diff tool on item WARNING: This will download the remote item to do the diff.
-
#download(local, item) ⇒ Object
Download an item into local.
-
#ignoring ⇒ Object
Returns array of globs of files to ignore.
-
#list ⇒ Object
Get a list of remote items.
-
#localitems(from) ⇒ Object
Get a list of local items rooted at #from.
-
#locallist ⇒ Object
Get a list of local items.
-
#remove(itemkey) ⇒ Object
Remove remote item.
-
#removelocal(dest, item) ⇒ Object
Remove local reference of item.
-
#searchFor ⇒ Object
Returns array of globs to search for files.
-
#status(options = {}) ⇒ Object
Get status of things here verses there.
- #syncdown(options = {}) ⇒ Object
-
#synckey(item) ⇒ Object
Get the key used to quickly compare two items.
- #syncup(options = {}) ⇒ Object
-
#tolocalname(item, itemkey) ⇒ Object
Compute the local name from remote item details.
-
#tolocalpath(into, item) ⇒ Object
Compute the local path from the listing details.
-
#toRemoteItem(root, path) ⇒ Object
Compute a remote item hash from the local path.
-
#upload(src, item, modify) ⇒ Object
Upload local item to remote.
Instance Method Details
#docmp(itemA, itemB) ⇒ Object
True if itemA and itemB are different
Children objects must override this
133 134 135 |
# File 'lib/MrMurano/SyncUpDown.rb', line 133 def docmp(itemA, itemB) true end |
#dodiff(item) ⇒ Object
Call external diff tool on item WARNING: This will download the remote item to do the diff.
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/MrMurano/SyncUpDown.rb', line 424 def dodiff(item) trmt = Tempfile.new([tolocalname(item, @itemkey)+'_remote_', '.lua']) tlcl = Tempfile.new([tolocalname(item, @itemkey)+'_local_', '.lua']) if item.has_key? :script then Pathname.new(tlcl.path).open('wb') do |io| io << item[:script] end else Pathname.new(tlcl.path).open('wb') do |io| io << item[:local_path].read end end df = "" begin download(Pathname.new(trmt.path), item) cmd = $cfg['diff.cmd'].shellsplit cmd << trmt.path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || ::File::SEPARATOR) cmd << tlcl.path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || ::File::SEPARATOR) df, _ = Open3.capture2e(*cmd) ensure trmt.close trmt.unlink tlcl.close tlcl.unlink end df end |
#download(local, item) ⇒ Object
Download an item into local
Children objects should override this or implement #fetch()
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/MrMurano/SyncUpDown.rb', line 206 def download(local, item) if item[:bundled] then warning "Not downloading into bundled item #{synckey(item)}" return end local.dirname.mkpath id = item[@itemkey.to_sym] if id.nil? then debug "!!! Missing '#{@itemkey}', using :id instead!" debug ":id => #{item[:id]}" id = item[:id] raise "Both #{@itemkey} and id in item are nil!" if id.nil? end local.open('wb') do |io| fetch(id) do |chunk| io.write chunk end end end |
#ignoring ⇒ Object
Returns array of globs of files to ignore
296 297 298 |
# File 'lib/MrMurano/SyncUpDown.rb', line 296 def ignoring %w{*_test.lua *_spec.lua .*} end |
#list ⇒ Object
Get a list of remote items.
Children objects Must override this
100 101 102 |
# File 'lib/MrMurano/SyncUpDown.rb', line 100 def list() [] end |
#localitems(from) ⇒ Object
Get a list of local items rooted at #from
Children rarely need to override this. Only when the locallist is not a set of files in a directory will they need to override it.
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/MrMurano/SyncUpDown.rb', line 308 def localitems(from) debug "#{self.class.to_s}: Getting local items from: #{from}" searchIn = from.to_s sf = searchFor.map{|i| ::File.join(searchIn, i)} Dir[*sf].flatten.compact.reject do |p| ::File.directory?(p) or ignoring.any? do |i| ::File.fnmatch(i,p) end end.map do |path| path = Pathname.new(path).realpath item = toRemoteItem(from, path) if item.kind_of?(Array) then item.compact.map{|i| i[:local_path] = path; i} elsif not item.nil? then item[:local_path] = path item end end.flatten.compact end |
#locallist ⇒ Object
Get a list of local items.
Children should never need to override this. Instead they should override #localitems
This collects items in the project and all bundles.
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/MrMurano/SyncUpDown.rb', line 256 def locallist() # so. if @locationbase/bundles exists # gather and merge: @locationbase/bundles/*/@location # then merge @locationbase/@location # bundleDir = $cfg['location.bundles'] or 'bundles' bundleDir = 'bundles' if bundleDir.nil? items = {} if (@locationbase + bundleDir).directory? then (@locationbase + bundleDir).children.sort.each do |bndl| if (bndl + @location).exist? then verbose("Loading from bundle #{bndl.basename}") bitems = localitems(bndl + @location) bitems.map!{|b| b[:bundled] = true; b} # mark items from bundles. # use synckey for quicker merging. bitems.each { |b| items[synckey(b)] = b } end end end if (@locationbase + @location).exist? then bitems = localitems(@locationbase + @location) # use synckey for quicker merging. bitems.each { |b| items[synckey(b)] = b } else warning "Skipping missing location #{@locationbase + @location}" end items.values end |
#remove(itemkey) ⇒ Object
Remove remote item
Children objects Must override this
109 110 111 112 113 |
# File 'lib/MrMurano/SyncUpDown.rb', line 109 def remove(itemkey) # :nocov: raise "Forgotten implementation" # :nocov: end |
#removelocal(dest, item) ⇒ Object
Remove local reference of item
Children objects should override this if move than just unlinking the local item.
233 234 235 |
# File 'lib/MrMurano/SyncUpDown.rb', line 233 def removelocal(dest, item) dest.unlink end |
#searchFor ⇒ Object
Returns array of globs to search for files
291 292 293 |
# File 'lib/MrMurano/SyncUpDown.rb', line 291 def searchFor %w{*.lua */*.lua} end |
#status(options = {}) ⇒ Object
Get status of things here verses there
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'lib/MrMurano/SyncUpDown.rb', line 455 def status(={}) = elevate_hash() there = list() here = locallist() itemkey = @itemkey.to_sym therebox = {} there.each do |item| item = Hash.transform_keys_to_symbols(item) item[:synckey] = synckey(item) therebox[ item[:synckey] ] = item end herebox = {} here.each do |item| item = Hash.transform_keys_to_symbols(item) item[:synckey] = synckey(item) herebox[ item[:synckey] ] = item end toadd = [] todel = [] tomod = [] unchg = [] if [:asdown] then todel = (herebox.keys - therebox.keys).map{|key| herebox[key] } toadd = (therebox.keys - herebox.keys).map{|key| therebox[key] } else toadd = (herebox.keys - therebox.keys).map{|key| herebox[key] } todel = (therebox.keys - herebox.keys).map{|key| therebox[key] } end (herebox.keys & therebox.keys).each do |key| # Want here to override there except for itemkey. mrg = herebox[key].reject{|k,v| k==itemkey} mrg = therebox[key].merge(mrg) if docmp(herebox[key], therebox[key]) then mrg[:diff] = dodiff(mrg) if [:diff] tomod << mrg else unchg << mrg end end { :toadd=>toadd, :todel=>todel, :tomod=>tomod, :unchg=>unchg } end |
#syncdown(options = {}) ⇒ Object
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'lib/MrMurano/SyncUpDown.rb', line 382 def syncdown(={}) = elevate_hash() [:asdown] = true dt = status() into = @locationbase + @location ### toadd = dt[:toadd] todel = dt[:todel] tomod = dt[:tomod] if [:delete] then todel.each do |item| verbose "Removing item #{item[:synckey]}" unless $cfg['tool.dry'] then dest = tolocalpath(into, item) removelocal(dest, item) end end end if [:create] then toadd.each do |item| verbose "Adding item #{item[:synckey]}" unless $cfg['tool.dry'] then dest = tolocalpath(into, item) download(dest, item) end end end if [:update] then tomod.each do |item| verbose "Updating item #{item[:synckey]}" unless $cfg['tool.dry'] then dest = tolocalpath(into, item) download(dest, item) end end end end |
#synckey(item) ⇒ Object
Get the key used to quickly compare two items
Children objects should override this if synckey is not @itemkey
195 196 197 198 |
# File 'lib/MrMurano/SyncUpDown.rb', line 195 def synckey(item) key = @itemkey.to_sym item[key] end |
#syncup(options = {}) ⇒ Object
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/MrMurano/SyncUpDown.rb', line 347 def syncup(={}) = elevate_hash() itemkey = @itemkey.to_sym [:asdown] = false dt = status() toadd = dt[:toadd] todel = dt[:todel] tomod = dt[:tomod] if [:delete] then todel.each do |item| verbose "Removing item #{item[:synckey]}" unless $cfg['tool.dry'] then remove(item[itemkey]) end end end if [:create] then toadd.each do |item| verbose "Adding item #{item[:synckey]}" unless $cfg['tool.dry'] then upload(item[:local_path], item.reject{|k,v| k==:local_path}, false) end end end if [:update] then tomod.each do |item| verbose "Updating item #{item[:synckey]}" unless $cfg['tool.dry'] then upload(item[:local_path], item.reject{|k,v| k==:local_path}, true) end end end end |
#tolocalname(item, itemkey) ⇒ Object
Compute the local name from remote item details
Children objects should override this or #tolocalpath
164 165 166 |
# File 'lib/MrMurano/SyncUpDown.rb', line 164 def tolocalname(item, itemkey) item[itemkey].to_s end |
#tolocalpath(into, item) ⇒ Object
Compute the local path from the listing details
If there is already a matching local item, some of its details are also in the item hash.
Children objects should override this or #tolocalname
179 180 181 182 183 184 185 186 187 |
# File 'lib/MrMurano/SyncUpDown.rb', line 179 def tolocalpath(into, item) return item[:local_path] if item.has_key? :local_path itemkey = @itemkey.to_sym name = tolocalname(item, itemkey) raise "Bad key(#{itemkey}) for #{item}" if name.nil? name = Pathname.new(name) unless name.kind_of? Pathname name = name.relative_path_from(Pathname.new('/')) if name.absolute? into + name end |
#toRemoteItem(root, path) ⇒ Object
Compute a remote item hash from the local path
Children objects should override this.
151 152 153 154 155 |
# File 'lib/MrMurano/SyncUpDown.rb', line 151 def toRemoteItem(root, path) path = Pathname.new(path) unless path.kind_of? Pathname root = Pathname.new(root) unless root.kind_of? Pathname {:name => path.realpath.relative_path_from(root.realpath).to_s} end |
#upload(src, item, modify) ⇒ Object
Upload local item to remote
Children objects Must override this
122 123 124 125 126 |
# File 'lib/MrMurano/SyncUpDown.rb', line 122 def upload(src, item, modify) # :nocov: raise "Forgotten implementation" # :nocov: end |