Class: Origen::Utility::DesignSync
- Defined in:
- lib/origen/utility/design_sync.rb
Overview
Ruby API to interface with Design Sync
Instance Method Summary collapse
-
#cancel(_target, options = {}) ⇒ Object
Cancel a checkout of a specific target which should be an absolute path to the target file, or wildcard expression.
-
#changed_objects(target, previous_tag, options = {}) ⇒ Object
Returns a hash containing files that have changed vs.
-
#changed_objects?(*args) ⇒ Boolean
Check if the supplied directory has any changed objects vs the previous tag See DesignSync#changed_objects for available options.
-
#check_in(target, options = {}) ⇒ Object
Check in a specific target which should be an absolute path to the target file, or wildcard expression.
-
#check_out(target, options = {}) ⇒ Object
Check out a specific target which should be an absolute path to the target file, or wildcard expression.
-
#container_directory(pathname) ⇒ Object
Will recursively move back up the directory tree from the given directory and return the first one that is not part of a Design Sync workspace.
- #diff_cmd(options = {}) ⇒ Object
- #full_path_prefix ⇒ Object
-
#import(file, vault, version, destination = false) ⇒ Object
Import a file to the local workspace from another vault, where the vault argument must include the full path to the requested file.
-
#initialize_dir(dir, vault) ⇒ Object
Initializes the given directory with the given vault reference.
-
#managed_by_design_sync?(path, _options = {}) ⇒ Boolean
Returns true if the given file is known to Design Sync.
-
#modified_objects(target, options = {}) ⇒ Object
Returns an array of paths to modified files, caches result for performance, set :refresh => true to clear cache.
-
#modified_objects?(*args) ⇒ Boolean
Check if the supplied directory has any modified objects, will reflect the result from the last call unless :refresh => true.
-
#populate(target, options = {}) ⇒ Object
Almost the same as DesignSync#check_out but accepts some different options.
-
#remote_check_in(dir, options = {}) ⇒ Object
Check in the contents of the given directory to a remote vault location, that is a vault location that is not associated with the workspace that the given files are in.
-
#remove_dot_syncs!(dir, _options = {}) ⇒ Object
Recursively remove all .SYNC directories from the given directory.
-
#selector(target) ⇒ Object
Returns the selector for the given object, which should be an absolute path to a file or directory.
-
#tag(target, tag, options = {}) ⇒ Object
Tag the target which is an absolute path to a file or directory.
-
#vault(file_or_dir) ⇒ Object
Returns the vault reference to give local file or directory.
Instance Method Details
#cancel(_target, options = {}) ⇒ Object
Cancel a checkout of a specific target which should be an absolute path to the target file, or wildcard expression
Options:
-
:rec # Do a recursive cancel, false by default
-
:force # Force cancel (overwrite local edits), false by default
-
:exclude # Supply filenames to exclude or wildcard, e.g. “.lst,.S19”
-
:keep # Keep editable copy of the files post cancel, false by default
Example
# Cancel every checkout in Origen.root
cancel("#{Origen.root}/*", :rec => true, :force => true)
172 173 174 175 176 |
# File 'lib/origen/utility/design_sync.rb', line 172 def cancel(_target, = {}) # Note "-verbose" is not a valid option for dssc cancel cmd = "dssc cancel #{keep()} #{rec()} #{force()} #{exclude()}" launch(cmd) end |
#changed_objects(target, previous_tag, options = {}) ⇒ Object
Returns a hash containing files that have changed vs. the previous tag, this is organized as follows:
{
:added => [], # Paths to files that have been added since the previous tag
:removed => [], # Paths to files that have been removed since the previous tag
:changed => [], # Paths to files that have changed since the previous tag
}
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/origen/utility/design_sync.rb', line 318 def changed_objects(target, previous_tag, = {}) = { }.merge() # We need to parse the following data from the output, ignore everything else # which will mostly refer to un-managed files. # # Added since previous version... # 1.12 First only source_setup # Removed since previous version... # 1.13 Second only lib/history # Modified since previous version... # 1.32 1.31 Different versions lib/origen/application.rb # Modified since previous version including a local edit... # 1.7 (Locally Modified) 1.7 Different states lib/origen/commands/rc.rb objects = { added: [], removed: [], changed: [] } sys("dssc compare -rec -path -report silent -selector #{previous_tag} #{target}").each do |line| unless line =~ /Unmanaged/ # http://www.rubular.com/r/GoNYB75upB if line =~ /\s*(\S+)\s+First only\s+(\S+)\s*/ objects[:added] << Regexp.last_match[2] # http://www.rubular.com/r/Xvh32Lm4hS elsif line =~ /\s*(\S+)\s+Second only\s+(\S+)\s*/ objects[:removed] << Regexp.last_match[2] # http://www.rubular.com/r/tvTHod9Mye elsif line =~ /\s*\S+\s+(\(Locally Modified\))?\s*(\S+)\s+Different (versions|states)\s+(\S+)\s*/ objects[:changed] << Regexp.last_match[4] end end end objects end |
#changed_objects?(*args) ⇒ Boolean
Check if the supplied directory has any changed objects vs the previous tag See DesignSync#changed_objects for available options.
305 306 307 308 |
# File 'lib/origen/utility/design_sync.rb', line 305 def changed_objects?(*args) objects = changed_objects(*args) objects[:added].size > 0 || objects[:removed].size > 0 || objects[:changed].size > 0 end |
#check_in(target, options = {}) ⇒ Object
Check in a specific target which should be an absolute path to the target file, or wildcard expression.
Options:
-
:rec # Do a recursive check-in, false by default
-
:comment # Supply a comment to go with the check-in
-
:new # Allow check in of new files (i.e. add the file to revision control)
-
:verbose # Display output to terminal, false by default
-
:skip # Allow check in to skip over a newer version of the file if it exists
-
:keep # Keep editable copy of the files post check-in, false by default
Example
# Check-in everything in Origen.root
check_in("#{Origen.root}/*", :rec => true, :com => "Periodic checkin, still in development")
98 99 100 101 102 103 104 105 |
# File 'lib/origen/utility/design_sync.rb', line 98 def check_in(target, = {}) = { keep: true }.merge() # FYI: for debug use '-dryrun' option to 'dssc ci' command cmd = "dssc ci #{keep()} #{rec()} #{new()} #{com()} #{branch()} #{[:skip] ? '-skip' : ''} #{target}" launch(cmd, [:verbose]) end |
#check_out(target, options = {}) ⇒ Object
Check out a specific target which should be an absolute path to the target file, or wildcard expression.
Options:
-
:rec # Do a recursive checkout, false by default
-
:lock # Check out with a lock (overrides get option due to DesignSync get/lock incompatibility)
-
:version # Specific tag or version number, will get latest by default
-
:force # Force check out, false by default
-
:verbose # Display output to terminal, false by default
-
:get # Fetch locally editable copies, true by default (unless lock is set)
Example
# Checkout everything in Origen.root
check_out("#{Origen.root}/*", :rec => true)
74 75 76 77 78 79 80 |
# File 'lib/origen/utility/design_sync.rb', line 74 def check_out(target, = {}) = { get: true }.merge() cmd = "dssc co #{rec()} #{get()} #{loc()} #{ver()} #{force()} -nocomment #{target}" launch(cmd, [:verbose]) end |
#container_directory(pathname) ⇒ Object
Will recursively move back up the directory tree from the given directory and return the first one that is not part of a Design Sync workspace.
The supplied pathname should be an absolute Pathname instance.
383 384 385 386 387 388 389 |
# File 'lib/origen/utility/design_sync.rb', line 383 def container_directory(pathname) if managed_by_design_sync?(pathname) container_directory(pathname.parent) else pathname end end |
#diff_cmd(options = {}) ⇒ Object
352 353 354 355 356 357 358 |
# File 'lib/origen/utility/design_sync.rb', line 352 def diff_cmd( = {}) if [:version] "dssc diff -gui -ver #{[:version]}" else 'dssc diff -gui' end end |
#full_path_prefix ⇒ Object
293 294 295 296 297 298 299 300 301 |
# File 'lib/origen/utility/design_sync.rb', line 293 def full_path_prefix @full_path_prefix ||= begin if Origen.running_on_windows? 'file:///' else 'file://' end end end |
#import(file, vault, version, destination = false) ⇒ Object
Import a file to the local workspace from another vault, where the vault argument must include the full path to the requested file. You can optionally supply a destination for where you want the file to end up, if no destination is supplied the file will end up in the PWD.
Example
# Import this file and save it in Origen.root
file = "design_sync.rb"
vault = "sync://sync-15088:15088/Projects/common_tester_blocks/origen/lib/sys"
version = "v0.1.0" # Version can be any valid DS identifier, e.g. a version number or tag
import(file, vault, version, Origen.root)
45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/origen/utility/design_sync.rb', line 45 def import(file, vault, version, destination = false) puts 'Importing from DesignSync...' puts "#{vault}/#{file} #{version}" unless sys("dssc import -version #{version} -force #{vault} #{file}")[0] =~ /Success/ fail "Error importing #{file} from Design Sync" end if Origen.running_on_windows? sys("move /Y #{file} #{destination}/.") if destination else sys("mv -f #{file} #{destination}/.") if destination end end |
#initialize_dir(dir, vault) ⇒ Object
Initializes the given directory with the given vault reference
392 393 394 395 396 |
# File 'lib/origen/utility/design_sync.rb', line 392 def initialize_dir(dir, vault) Dir.chdir dir do sys "dssc setvault #{vault} ." end end |
#managed_by_design_sync?(path, _options = {}) ⇒ Boolean
365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/origen/utility/design_sync.rb', line 365 def managed_by_design_sync?(path, = {}) res = sys "dssc url vault #{path}" if res.empty? false else if res.first =~ /^file:/ || res.first =~ /There is no object with that name/ false else true end end end |
#modified_objects(target, options = {}) ⇒ Object
Returns an array of paths to modified files, caches result for performance, set :refresh => true to clear cache. The target should be an absolute path to the directory you want to query.
Options:
-
:rec # Do a recursive search, false by default
-
:exclude # Supply filenames to exclude or wildcard, e.g. “.lst,.S19”
-
:refresh # Force a new search, false by default
Example
# Get all modified files in my project workspace
files = modified_objects(Origen.root, :rec => true)
NOTE: -unmanaged and -managed are mutually exclusive, specifying both does neither!
-unmanaged : show only objects not under revision control
-managed : show only objects under revision control
-modified : show locally modified files in workspace (includes unmanaged objects)
-changed : shows not up-to-date files. Includes both locally modified and newer verions in vault.
Overrides -modified.
246 247 248 249 250 251 252 253 254 255 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 288 289 290 291 |
# File 'lib/origen/utility/design_sync.rb', line 246 def modified_objects(target, = {}) = { managed: true, # by default handle managed (to permit for unmanaged case) remote: false, # includes files possibly modified by others in repository }.merge() # The result of this method is cached for future calls (method called twice actually) @objects = nil if [:refresh] @needs_update_objects = nil if [:refresh] if [:remote] return @needs_update_objects if @needs_update_objects else return @objects if @objects end # Since DesignSync does not supply an option to only list files that need update (!), have to run with # -changed option then again without and difference the 2 arrays! if [:remote] all_objects = sys("dssc ls #{rec()} #{exclude()} #{managed()} #{dssc_path()} -report N -modified #{unmanaged()} -changed -format text #{target}").reject do |item| # removes extraneous lines item =~ /^(Name|Directory|---)/ end all_objects.map! do |object| object.strip! # Strip off any whitespace from all objects object.sub!(/^#{full_path_prefix}/, '') object.sub('|', ':') end end @objects = sys("dssc ls #{rec()} #{exclude()} #{managed()} #{dssc_path()} -report N -modified #{unmanaged()} -format text #{target}").reject do |item| # removes extraneous lines item =~ /^(Name|Directory|---)/ end @objects.map! do |object| object.strip! # Strip off any whitespace from all objects object.sub!(/^#{full_path_prefix}/, '') object.sub('|', ':') end # Now difference the lists if remote desired if [:remote] return @needs_update_objects = all_objects - @objects else return @objects end end |
#modified_objects?(*args) ⇒ Boolean
Check if the supplied directory has any modified objects, will reflect the result from the last call unless :refresh => true. Returns true or false. See DesignSync#modified_objects for available options.
Example
modified_objects? # Takes a while to run while the workspace is queried
modified_objects? # Runs very quickly and returns the cached answer
modified_objects?(:refresh => true) # Takes a while to run while the workspace is queried
215 216 217 |
# File 'lib/origen/utility/design_sync.rb', line 215 def modified_objects?(*args) modified_objects(*args).size > 0 end |
#populate(target, options = {}) ⇒ Object
Almost the same as DesignSync#check_out but accepts some different options.
Options:
-
:rec # Do a recursive populate, false by default
-
:version # Specific tag or version number, will get latest by default
-
:force # Force populate (overwrite local edits), false by default
-
:unify # Unify the workspace (remove any retired files you currently have checked out)
-
:exclude # Supply filenames to exclude or wildcard, e.g. “.lst,.S19”
-
:verbose # Display output to terminal, false by default
-
:get # Fetch locally editable copies, true by default
-
:merge # Merge local edits into latest files, false by default
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/origen/utility/design_sync.rb', line 190 def populate(target, = {}) = { unify: true, incremental: false, replace: false, get: true, merge: false }.merge() inc = [:incremental] ? '-inc' : '' replace = [:replace] ? '-replace' : '' cmd = "dssc pop #{inc} #{replace} #{rec()} #{force()} #{merge()} #{get()} #{ver()} #{uni()} #{exclude()} #{target}" successful = launch(cmd, [:verbose]) unless successful fail "Something went wrong when populating #{target} from DesignSync!" end end |
#remote_check_in(dir, options = {}) ⇒ Object
Check in the contents of the given directory to a remote vault location, that is a vault location that is not associated with the workspace that the given files are in.
Anything found in the given directory will be checked in, even files which are not currently under revision control.
No attempt will be made to merge the current vault contents with the local data, the local data will always be checked in as lastest.
A tag can be optionally supplied and if present will be applied to the files post check in.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/origen/utility/design_sync.rb', line 121 def remote_check_in(dir, = {}) Origen.deprecate 'Use Origen::RevisionControl::DesignSync.remote_check_in instead' = { verbose: true, rec: true, keep: true, new: true, skip: true, replace: true }.merge() dir = Pathname.new(dir) fail "Directory does not exist: #{dir}" unless dir.exist? fail "Only directories are supported by remote_check_in, this is not a directory: #{dir}" unless dir.directory? fail 'No vault option supplied to remote_check_in!' unless [:vault] scratch = Pathname.new("#{Origen.app.workspace_manager.imports_directory}/design_sync/scratch") FileUtils.rm_rf(scratch) if scratch.exist? FileUtils.mkdir_p(scratch) FileUtils.cp_r("#{dir}/.", scratch) remove_dot_syncs!(scratch) launch("dssc setvault #{[:vault]} #{scratch}", [:verbose]) check_in(scratch, ) tag(scratch, [:tag], ) if [:tag] FileUtils.rm_rf(scratch) end |
#remove_dot_syncs!(dir, _options = {}) ⇒ Object
Recursively remove all .SYNC directories from the given directory
148 149 150 151 152 153 154 155 156 |
# File 'lib/origen/utility/design_sync.rb', line 148 def remove_dot_syncs!(dir, = {}) Origen.deprecate 'Use Origen::RevisionControl::DesignSync.remove_dot_syncs! instead' dir = Pathname.new(dir) fail "Directory does not exist: #{dir}" unless dir.exist? fail "Only directories are supported by remove_dot_syncs, this is not a directory: #{dir}" unless dir.directory? Dir.glob("#{dir}/**/.SYNC").sort.each do |dot_sync| FileUtils.rm_rf(dot_sync) end end |
#selector(target) ⇒ Object
Returns the selector for the given object, which should be an absolute path to a file or directory
221 222 223 |
# File 'lib/origen/utility/design_sync.rb', line 221 def selector(target) sys("dssc url selector #{target}")[0] end |
#tag(target, tag, options = {}) ⇒ Object
Tag the target which is an absolute path to a file or directory.
Options
-
:rec # Recursive, false by default
-
:delete # Delete the given tag from the target, false by default
-
:replace # Replace any existing version of the given tag, false by default
-
:exclude # Supply filenames to exclude or wildcard, e.g. “.lst,.S19”
Example
tag(Origen.root, "my_release_001", :rec => true)
tag("#{Origen.root}/top/top_block.rb", "my_release_001")
18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/origen/utility/design_sync.rb', line 18 def tag(target, tag, = {}) = { rec: false, # Set true to tag recursively delete: false, replace: false }.merge() cmd = "dssc tag #{tag} #{exclude()} #{[:replace] ? '-replace' : ''} #{rec()} #{[:delete] ? '-delete' : ''} #{target}" if [:debug] puts '**** DesignSync Debug ****' puts cmd else system(cmd) end end |
#vault(file_or_dir) ⇒ Object
Returns the vault reference to give local file or directory
399 400 401 |
# File 'lib/origen/utility/design_sync.rb', line 399 def vault(file_or_dir) (sys "dssc url vault #{file_or_dir}").first end |