Class: Origen::RevisionControl::DesignSync
- Defined in:
- lib/origen/revision_control/design_sync.rb
Instance Attribute Summary
Attributes inherited from Base
#local, #remote, #remotes_method
Class Method Summary collapse
-
.import(path_to_file_in_vault, options = {}) ⇒ Object
Import a file to the local workspace from another vault, where the first argument must include the full path to the requested file in the vault.
-
.remote_check_in(dir, options = {}) ⇒ Object
Check in the contents of the given directory to a remote vault location, meaning a vault location that is not necessarily associated with the current workspace that the given files are in.
-
.remove_dot_syncs!(dir, options = {}) ⇒ Object
Recursively remove all .SYNC directories from the given directory.
Instance Method Summary collapse
- #build(options = {}) ⇒ Object
- #changes(dir = nil, options = {}) ⇒ Object
- #checkin(path = nil, options = {}) ⇒ Object
- #checkout(path = nil, options = {}) ⇒ Object
- #current_branch ⇒ Object
- #diff_cmd(file, version) ⇒ Object
- #local_modifications(dir = nil, options = {}) ⇒ Object
- #root ⇒ Object
- #tag(id, options = {}) ⇒ Object
- #unmanaged(dir = nil, options = {}) ⇒ Object
Methods inherited from Base
#dssc?, #git?, #initialize, #p4?, #svn?
Constructor Details
This class inherits a constructor from Origen::RevisionControl::Base
Class Method Details
.import(path_to_file_in_vault, options = {}) ⇒ Object
Import a file to the local workspace from another vault, where the first argument must include the full path to the requested file in the vault. You can optionally supply a destination for where you want the file to end up via the :local option, if no destination is supplied the file will end up in the PWD.
This is a DesignSync only API and can be used in cases where you would to fetch a file directly from a vault without setting up an association between a local directory and the vault. i.e. it will not create or modify an existing .SYNC in the local destination directory.
Example
# Import this file and save it in RGen.root
file = "sync://sync-15088:15088/Projects/common_tester_blocks/rgen/lib/sys/design_sync.rb"
version = "v0.1.0" # Version can be any valid DS identifier, e.g. a version number or tag
import(file, version: version, local: RGen.root)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/origen/revision_control/design_sync.rb', line 55 def self.import(path_to_file_in_vault, = {}) = { verbose: true, version: 'Latest' }.merge() if [:verbose] puts 'Importing from DesignSync...' puts "#{path_to_file_in_vault} #{[:version]}" end dir = path_to_file_in_vault.split('/') file = dir.pop dir = dir.join('/') cmd = "import -version #{[:version]} -force #{dir} #{file}" dssc(cmd, verbose: false) if Origen.os.windows? system("move /Y #{file} #{[:local]}/.") if [:local] else system("mv -f #{file} #{[:local]}/.") if [:local] end end |
.remote_check_in(dir, options = {}) ⇒ Object
Check in the contents of the given directory to a remote vault location, meaning a vault location that is not necessarily associated with the current 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 latest.
A tag can be optionally supplied and if present will be applied to the files post check in.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/origen/revision_control/design_sync.rb', line 18 def self.remote_check_in(dir, = {}) = { force: 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) ds = new(remote: [:vault], local: scratch) ds.checkin() ds.tag([:tag], ) if [:tag] FileUtils.rm_rf(scratch) end |
.remove_dot_syncs!(dir, options = {}) ⇒ Object
Recursively remove all .SYNC directories from the given directory
77 78 79 80 81 82 83 84 85 |
# File 'lib/origen/revision_control/design_sync.rb', line 77 def self.remove_dot_syncs!(dir, = {}) 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 |
Instance Method Details
#build(options = {}) ⇒ Object
87 88 89 |
# File 'lib/origen/revision_control/design_sync.rb', line 87 def build( = {}) checkout() end |
#changes(dir = nil, options = {}) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/origen/revision_control/design_sync.rb', line 127 def changes(dir = nil, = {}) paths, = clean_path(dir, ) = { verbose: false }.merge() cmd = 'compare -rec -path -report silent' if [:version] cmd += " -selector #{prefix_tag([:version])}" end cmd += " #{paths.first}" objects = { added: [], removed: [], changed: [] } dssc(cmd, ).each do |line| # 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 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[:present] = !objects[:added].empty? || !objects[:removed].empty? || !objects[:changed].empty? objects[:added].map! { |i| "#{paths.first}/" + i } objects[:removed].map! { |i| "#{paths.first}/" + i } objects[:changed].map! { |i| "#{paths.first}/" + i } objects end |
#checkin(path = nil, options = {}) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/origen/revision_control/design_sync.rb', line 108 def checkin(path = nil, = {}) paths, = clean_path(path, ) cmd = 'ci' cmd += ' -rec -keep' cmd += ' -skip' if [:force] cmd += ' -new' if [:unmanaged] || [:force] if [:comment] && ![:comment].strip.empty? cmd += " -com \"#{[:comment].strip}\"" else # cmd += ' -nocom' # DO NOT USE nocom option with DesignSync, doesn't always work cmd += ' -com None' end paths = paths.join(' ') dssc("#{cmd} #{paths}", ) # Make sure the file is still writable `chmod a+w -R #{paths}` paths end |
#checkout(path = nil, options = {}) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/origen/revision_control/design_sync.rb', line 91 def checkout(path = nil, = {}) paths, = clean_path(path, ) cmd = 'pop' cmd += ' -rec -get -uni' cmd += ' -force' if [:force] if [:version] cmd += " -version #{prefix_tag([:version])}" else cmd += ' -merge' unless [:force] end paths = paths.join(' ') dssc("#{cmd} #{paths}", ) # Design sync can be funny and even with -get it can leave unwritable files, so let's fix that `chmod a+w -R #{paths}` paths end |
#current_branch ⇒ Object
274 275 276 |
# File 'lib/origen/revision_control/design_sync.rb', line 274 def current_branch dssc("url selector #{local}", verbose: false).first end |
#diff_cmd(file, version) ⇒ Object
213 214 215 |
# File 'lib/origen/revision_control/design_sync.rb', line 213 def diff_cmd(file, version) "dssc diff -gui -ver #{prefix_tag(version)} #{file}" end |
#local_modifications(dir = nil, options = {}) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/origen/revision_control/design_sync.rb', line 174 def local_modifications(dir = nil, = {}) paths, = clean_path(dir, ) = { verbose: false }.merge() cmd = 'ls -rec -managed -path -report N -modified -format text' cmd += " #{paths.first}" files = dssc(cmd, ).reject do |item| item.strip.empty? || item =~ /^(Name|Directory|---)/ end files.map! do |file| file.strip! # Strip off any whitespace from all objects file.sub!(/^#{full_path_prefix}/, '') file.sub('|', ':') file.sub!(/^/, "#{paths.first}/") end end |
#root ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 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 |
# File 'lib/origen/revision_control/design_sync.rb', line 228 def root # This is an expensive operation the way it is currently implemented, so # cache the result for future calls Origen.app.session.dssc["root-#{local}"] ||= begin root = local # Create two arrays, one to store the parents and the other to corresponding vaults. temp_parent_array = Array.new(0) temp_parent_vault_array = Array.new(0) resolved = false vault = dssc("url vault #{root}").first until resolved || root.root? parent = root.parent # push the current parent into the parent array temp_parent_array.push(parent.to_s) if File.exist?("#{parent}/.SYNC") parent_vault = dssc("url vault #{parent}").first # push the current parent_vault into the vault array. temp_parent_vault_array.push(parent_vault.to_s) if vault.to_s =~ /^#{parent_vault}/ && vault.to_s != parent_vault.to_s root = parent else # Now, check if the parent array has unique values, it should if the DesignSync directory structure is correct. if temp_parent_vault_array.uniq.length == temp_parent_vault_array.length resolved = true else # To display the file/directory that the user needs to correct the conflict in, pick up the second last element from the parent array. fault_dir = temp_parent_array[-2] fault_dir_name = fault_dir.split('/')[-1] Origen.log.error 'DesignSync returns same vault locations for two directories.' Origen.log.error 'Please resolve the workspace conflicts before continuing' # Un-cache the result so that there is no error in future calls. Origen.app.session.dssc["root-#{local}"] = nil # Remove the .ref symlink from the local directory so that there are no issues in the future call scratch = Pathname.new("#{local}/.ref") FileUtils.rm_rf(scratch) if scratch.exist? abort end end else resolved = true end end root end end |
#tag(id, options = {}) ⇒ Object
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/origen/revision_control/design_sync.rb', line 217 def tag(id, = {}) id = VersionString.new(id) id = id.prefixed if id.semantic? replace = [:force] ? '-replace' : '' dssc "tag #{id} -rec #{replace} *" # Applying this rule recursively seems to cause havoc, so running on its own. # This hits any dot files in the root directory, any dot files in sub directories # already get hit by the above tag job. dssc "tag #{id} #{replace} .*" end |
#unmanaged(dir = nil, options = {}) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/origen/revision_control/design_sync.rb', line 195 def unmanaged(dir = nil, = {}) paths, = clean_path(dir, ) = { verbose: false }.merge() cmd = 'ls -rec -unmanaged -fullpath -report N -modified -format text' cmd += " #{paths.first}" files = dssc(cmd, ).reject do |item| # removes extraneous lines item =~ /^(Name|Directory|---)/ || item.strip.empty? end files.map! do |file| file.strip! # Strip off any whitespace from all objects file.sub!(/^#{full_path_prefix}/, '') file.sub('|', ':') end end |