Module: PbHelper

Includes:
ChannelManager, FileUtils
Defined in:
lib/ghelpers/pb_helper.rb

Instance Method Summary collapse

Instance Method Details

#addProduct(name) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ghelpers/pb_helper.rb', line 56

def addProduct(name)
  productDirectory = File.join(PRODUCTS_ROOT, name)
  # create the new product directory
  Dir.mkdir(productDirectory)
  # create the DSL folder
  productDSLDirectory = File.join(productDirectory, 'DSL')
  Dir.mkdir(productDSLDirectory)
  # copy the DSL template directory
  copyDirectoryWithoutHiddenRecursively(PRODUCT_DSL_TEMPLATE_ROOT, productDSLDirectory)
  # update product.oil to put in the produt name
  findAndReplaceInFile(File.join(productDirectory, 'DSL', 'product.oil'), /#\$PRODUCT_NAME\$/, name)
end

#addProductEntity(product, type, name) ⇒ Object



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
# File 'lib/ghelpers/pb_helper.rb', line 90

def addProductEntity(product, type, name)
  # add the coverage to product.oil
  # and ...
  # create the new coverage oil file
  if (type == :coverage) then
    findAndReplaceInFile(File.join(PRODUCTS_ROOT, product, 'DSL', 'product.oil'), /(\s+endcoverages)/, "\n   has_one :#{name}\\1")
    f = File.new(File.join(PRODUCTS_ROOT, product, 'DSL', 'coverages', name + '.oil'), 'w+')
    regex = /(\s+#\$COVERAGES\$)/
  else
    findAndReplaceInFile(File.join(PRODUCTS_ROOT, product, 'DSL', 'product.oil'), /(\s+endentities)/, "\n   has_one :#{name}\\1")
    f = File.new(File.join(PRODUCTS_ROOT, product, 'DSL', 'entities', name + '.oil'), 'w+')
    regex = /(\s+#\$ENTITIES\$)/
  end
  # some coverages and entities are essential, lets find them now
  recommendedSelections = getDefaultSelections(name, type, nil, nil)
  f.chmod(0644)
  oil = <<OIL
#{type} :#{name}
#{recommendedSelections}
end#{type}
OIL
  f.write(oil);
  f.close()
  # scan the layout oils and add this entity/coverage if required in the markup
  Dir.glob(File.join(PRODUCTS_ROOT, product, 'DSL', 'layouts', '*.oil')) do |lf|
    findAndReplaceInFile(lf, regex, "\n                #{type} :#{name}\\1")
  end
end

#cloneProduct(existingProductName, newProductName) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/ghelpers/pb_helper.rb', line 69

def cloneProduct(existingProductName, newProductName)
  existingProductDirectory = File.join(PRODUCTS_ROOT, existingProductName)
  newProductDirectory = File.join(PRODUCTS_ROOT, newProductName)
  # copy the product in its entirety
  copyDirectoryWithoutHiddenRecursively(existingProductDirectory, newProductDirectory)
  # update the main oil files
  findAndReplaceInFile(File.join(newProductDirectory, 'DSL', 'product.oil'), /(\s+:)#{existingProductName}/, "\\1#{newProductName}")
end

#copyDirectoryWithoutHiddenRecursively(src, dest) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/ghelpers/pb_helper.rb', line 307

def copyDirectoryWithoutHiddenRecursively(src, dest)
  # make the destination directory if it does not exist
  unless (File.directory?(dest)) then
    FileUtils.mkpath(dest)
  end
  # recursively copy files and folders without hidden files
  Dir.glob(File.join(src, '*'), File::FNM_PATHNAME) do |p|
    if (File.directory?(p))
      copyDirectoryWithoutHiddenRecursively(p, File.join(dest, File.basename(p)))
    else
      FileUtils.cp(p, dest)
    end
  end
end

#deleteProduct(name) ⇒ Object



78
79
80
# File 'lib/ghelpers/pb_helper.rb', line 78

def deleteProduct(name)
  FileUtils.mv(File.join(PRODUCTS_ROOT, name), File.join(PRODUCTS_ROOT, '.' + name))
end

#deleteProductEntity(product, entity) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/ghelpers/pb_helper.rb', line 162

def deleteProductEntity(product, entity)
  # remove the entry from product.oil
  productOilFile = File.join(PRODUCTS_ROOT, product, 'DSL', 'product.oil')
  cardinalityMatch = '((' + getCardinalities().join(')|(') + '))'
  findAndReplaceInFile(productOilFile, /^\s*#{cardinalityMatch}\s*:\s*#{entity}\s*\n/, '')
  # delete the specific oil file
  fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'coverages', "#{entity}.oil")
  unless (File.exists?(fileName)) then
    fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'entities', "#{entity}.oil")
  end
  FileUtils.rm(fileName, :force => true)
  # remove references from layout files
  Dir.glob(File.join(PRODUCTS_ROOT, product, 'DSL', 'layouts', '*.oil'), File::FNM_PATHNAME) do |c|
    # NOTE: entities and coverages can obviously have instructions bounded in {} after them
    # e.g. title, hide etc.etc. so we need to make sure our search is fuzzy enough
    # At this stage I have elected to just look for :Entity in any line and kill the line
    findAndReplaceInFile(c, /^.*?:#{entity}.*?\n/, '')
  end
end

#findAndReplaceInFile(fileName, findExpression, replaceExpression) ⇒ Object



342
343
344
345
346
347
348
349
350
351
# File 'lib/ghelpers/pb_helper.rb', line 342

def findAndReplaceInFile(fileName, findExpression, replaceExpression)
  open(fileName, 'r+') do |f|
    content = f.read()
    content.gsub!(findExpression, replaceExpression)
    f.truncate(0)
    f.rewind()
    f.write(content)
    f.close()
  end
end

#getBrandsObject



46
47
48
49
50
51
52
53
54
# File 'lib/ghelpers/pb_helper.rb', line 46

def getBrands
  brands = Array.new
  Dir.glob(File.join(BRANDS_ROOT, '*'), File::FNM_PATHNAME) do |p|
    if File.directory?(p)
      brands.push(File.basename(p))
    end
  end
  brands.sort
end

#getCardinalitiesObject



238
239
240
241
# File 'lib/ghelpers/pb_helper.rb', line 238

def getCardinalities()
  cardinalities = ['has_one', 'has_many']
  cardinalities
end

#getDefaultSelections(entity, type, recommendedSelections, path) ⇒ Object



119
120
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/ghelpers/pb_helper.rb', line 119

def getDefaultSelections(entity, type, recommendedSelections, path)
  if (recommendedSelections == nil) then
    recommendedSelections = ''
    loadLibraryEntity(entity, type)
    @hash = getPropertyHash(type, entity)
    path = Array.new
    path.push(entity)
  else
    path.push(entity.sub(/#{path.join()}/, ''))
  end
  c = eval(entity)
  associations = c.reflect_on_all_associations()
  associations.each do |a|
    className = a.name.id2name
    klass = eval(className)
    # see if this entity is defined as essential in the property hash
    sectionName = "#{className}MD"
    section = @hash[sectionName]
    if (section != nil) then
      value = @hash[sectionName]['usebydefault']
    end
    # puts "Entity [#{className}] value [#{value}]\n"
    if (value == 'true') then
      recommendedSelections << '     use '
      path.push(klass.nodeName)
      path.each do |t|
        unless t == path.first
          recommendedSelections << ':'
          recommendedSelections << t
          unless (t.object_id() == path.last.object_id())
            recommendedSelections << ','
          end
        end
      end
      path.pop()
      recommendedSelections << "\n"
    end
    getDefaultSelections(className, type, recommendedSelections, path)
    path.pop()
  end unless (associations.empty?())
  recommendedSelections
end

#getEntityDetails(product, entity) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/ghelpers/pb_helper.rb', line 218

def getEntityDetails(product, entity)
  # find the definition of this coverage in this product, could be entity or coverage
  fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'coverages', "#{entity}.oil")
  type = :coverage
  unless (File.exists?(fileName)) then
    fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'entities', "#{entity}.oil")
    type = :entity
  end
  # get the library definition of the coverage
  lcd = walkLibraryEntity(entity, type, nil)
  # go through all the items in the oil file that have been used and "check" them
  open(fileName) do |f|
    CoverageInterpreter2.execute(f.read).each do |s|
      lcd = lcd.gsub(/(\sname=\"#{s}\")/, '\1 checked="checked"')
    end
  end
  # puts lcd
  lcd
end

#getLanguagesObject



38
39
40
41
42
43
44
# File 'lib/ghelpers/pb_helper.rb', line 38

def getLanguages
  languages = Array.new
  Dir.glob(File.join(PRODUCTS_ROOT, 'dictionary_*.rb'), File::FNM_PATHNAME) do |p|
    languages.push(File.basename(p).sub(/dictionary_(.\w+)\.rb/, '\1'))
  end
  languages.sort
end

#getLibraryEntities(type) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/ghelpers/pb_helper.rb', line 205

def getLibraryEntities(type)
  if (type == :coverage) then
    root = COVERAGE_DEF_ROOT
  else
    root = ENTITY_DEF_ROOT
  end
  entities = Array.new
  Dir.glob(File.join(root, '*PropertyHash'), File::FNM_PATHNAME) do |c|
    entities.push(File.basename(c.to_s).gsub(/(.*)PropertyHash/, '\1'))
  end
  entities.sort
end

#getProductEntities(product, type) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/ghelpers/pb_helper.rb', line 82

def getProductEntities(product, type)
  open(File.join(PRODUCTS_ROOT, product, 'DSL','product.oil')) do |f|
    product = ProductInterpreter2.execute(f.read())
    f.close()
  end
  product.method(type).call().sort()
end

#getProductsObject



28
29
30
31
32
33
34
35
36
# File 'lib/ghelpers/pb_helper.rb', line 28

def getProducts
  products = Array.new
  Dir.glob(File.join(PRODUCTS_ROOT, '*'), File::FNM_PATHNAME) do |p|
    if File.directory?(p)
      products.push(File.basename(p))
    end
  end
  products.sort
end

#getPropertyHash(type, entity) ⇒ Object



333
334
335
336
337
338
339
340
# File 'lib/ghelpers/pb_helper.rb', line 333

def getPropertyHash(type, entity)
  if (type == :coverage) then
    libraryPath = COVERAGE_DEF_ROOT
  else
    libraryPath = ENTITY_DEF_ROOT
  end
  return YAML::load(open(File.join(libraryPath, entity + 'PropertyHash'), 'r'))
end

#loadLibraryEntity(entity, type) ⇒ Object



322
323
324
325
326
327
328
329
330
331
# File 'lib/ghelpers/pb_helper.rb', line 322

def loadLibraryEntity(entity, type)
  # now its time to dynamically load the the entity and its children from the library
  if (type == :coverage) then
    libraryPath = COVERAGE_DEF_ROOT
  else
    libraryPath = ENTITY_DEF_ROOT
  end
  require(File.join(libraryPath, entity + 'EntityModel.rb'))
  require(File.join(libraryPath, entity + 'NodeName.rb'))
end

#product?(name) ⇒ Boolean

Returns:

  • (Boolean)


15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/ghelpers/pb_helper.rb', line 15

def product?(name)
  if ((name != nil) && (!name.empty?()) && File.directory?(File.join(PRODUCTS_ROOT, name))) then
    # TODO: add code here to perform a validation of the product
    # Possible steps:
    # 1. Check there is a product.oil
    # 2. Check that each entity and coverage in product.oil has a valid entity/coverage oil file
    # 3. Ensure all items are in the library etc.
    # .... loads of other stuff
    return true
  end
  return false
end

#saveEntityDetails(product, entity, selections) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/ghelpers/pb_helper.rb', line 187

def saveEntityDetails(product, entity, selections)
  # assert type as coverage and if the file doesn't exist assume entity
  type = :coverage
  fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'coverages', "#{entity}.oil")
  unless (File.exists?(fileName)) then
    type = :entity
    fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'entities', "#{entity}.oil")
  end
  open(fileName, 'w') do |f|
    f << "#{type} :" << entity << "\n"
    selections.each do |s|
      f << '    use ' << s << "\n"
    end
    f << "end#{type}"
    f.close()
  end
end

#updateDictionary(lang, key, value) ⇒ Object



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/ghelpers/pb_helper.rb', line 243

def updateDictionary(lang, key, value)
  open(File.join(PRODUCTS_ROOT, "dictionary_#{lang}.rb"), 'r+') do |f|
    content = f.read()
    # is the string already in the dictionary?
    if (content.match(/^\s+\"#{key}\"\s+=>\s+\"[^\"]*\"\s*,/) != nil) then
      puts "Updating dictionary: Language[#{lang}] key [#{key}] value [#{value}]\n"
      content.gsub!(/(^\s+\"#{key}\"\s+=>\s+\")[^\"]*(\"\s*,)/, "\\1#{value}\\2")
    else
      puts "Adding to dictionary: Language[#{lang}] key [#{key}] value [#{value}]\n"
      newEntry = "\n      \"#{key}\" => \"#{value}\","
      # add the new lookup at the start of the dictionary
      content.gsub!(/(^\s*def\s+dictionary\s*\n\s*\{)/, "\\1#{newEntry}")
    end
    f.truncate(0)
    f.rewind()
    f.write(content)
    f.close()

  end
end

#updateEntityCardinality(product, entity, cardinality) ⇒ Object



182
183
184
185
# File 'lib/ghelpers/pb_helper.rb', line 182

def updateEntityCardinality(product, entity, cardinality)
  fileName = File.join(PRODUCTS_ROOT, product, 'DSL', 'product.oil')
  findAndReplaceInFile(fileName, /(^\s+)[^\s]+(\s*:#{entity})/, "\\1#{cardinality}\\2")
end

#walkLibraryEntity(entity, type, path) ⇒ Object



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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/ghelpers/pb_helper.rb', line 264

def walkLibraryEntity(entity, type, path)
  introduce_dictionary(PRODUCTS_ROOT, 'en')
  if (path == nil) then
    loadLibraryEntity(entity, type)
    path = Array.new
    path.push(entity)
  else
    path.push(entity.sub(/#{path.join()}/, ''))
  end
  result = ''
  associations = eval(entity).reflect_on_all_associations()
  #don't render markup if there's nothing there
  unless(associations.empty?) then
    result << '<ul>' << "\n"
    associations.each do |a|
      className = a.name.id2name
      result << '<li>' << '<input type="checkbox" name="'
      nodeName = eval(className).nodeName
      path.push(nodeName)
      path.each do |t|
        unless t == path.first
          result << ':' << t
          unless (t.object_id() == path.last.object_id())
            result << ','
          end
        end
      end
      path.pop()
      result << '"/>' << '<a>' << nodeName << '</a>'
      #  try and do a lookup on the dictionary
      dictionaryKey = (entity + '_' + nodeName).downcase()
      dictionaryTranslation = __(dictionaryKey)
      if (dictionaryTranslation != dictionaryKey) then
        result << '<p><small><i>' << dictionaryTranslation << '</i></small></p>'
      end
      result << walkLibraryEntity(className, type, path) << '</li>'
      path.pop()
    end
    result << '</ul>'
  end
  result
end