openstudio-extension 0.1.6 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +35 -1
- data/Gemfile +0 -2
- data/Jenkinsfile +1 -1
- data/README.md +21 -16
- data/Rakefile +1 -1
- data/lib/change_log.rb +157 -0
- data/lib/measures/openstudio_extension_test_measure/measure.xml +20 -19
- data/lib/openstudio/extension.rb +27 -10
- data/lib/openstudio/extension/core/os_lib_constructions.rb +6 -1
- data/lib/openstudio/extension/core/os_lib_model_generation.rb +30 -32
- data/lib/openstudio/extension/rake_task.rb +232 -18
- data/lib/openstudio/extension/runner.rb +9 -8
- data/lib/openstudio/extension/version.rb +1 -1
- data/openstudio-extension.gemspec +23 -17
- metadata +38 -35
- data/lib/measures/openstudio_extension_test_measure/tests/openstudio_extension_test_measure_test.rb +0 -74
@@ -283,7 +283,12 @@ module OsLib_Constructions
|
|
283
283
|
# create info message
|
284
284
|
if !runner.nil? # todo - need to look for bad visible transmittance here
|
285
285
|
uFactorSiToIpConversion = OpenStudio.convert(material.uFactor, 'W/m^2*K', 'Btu/ft^2*h*R').get
|
286
|
-
|
286
|
+
# version check to support 2.x and 3.x
|
287
|
+
if Gem::Version.new(OpenStudio::openStudioVersion) > Gem::Version.new("2.9.1")
|
288
|
+
runner.registerInfo("Created #{construction.name} construction. U-factor: #{OpenStudio.toNeatString(uFactorSiToIpConversion, 2, true)}(Btu/ft^2*h*R), SHGC: #{material.solarHeatGainCoefficient}, VT: #{material.getVisibleTransmittance.get}.")
|
289
|
+
else
|
290
|
+
runner.registerInfo("Created #{construction.name} construction. U-factor: #{OpenStudio.toNeatString(uFactorSiToIpConversion, 2, true)}(Btu/ft^2*h*R), SHGC: #{material.getSolarHeatGainCoefficient}, VT: #{material.getVisibleTransmittance.get}.")
|
291
|
+
end
|
287
292
|
end
|
288
293
|
|
289
294
|
result = construction
|
@@ -606,7 +606,7 @@ module OsLib_ModelGeneration
|
|
606
606
|
hash['ER_Trauma'] = { ratio: 0.0025, space_type_gen: true, default: false }
|
607
607
|
hash['ER_Triage'] = { ratio: 0.0050, space_type_gen: true, default: false }
|
608
608
|
hash['ICU_NurseStn'] = { ratio: 0.0298, space_type_gen: true, default: false }
|
609
|
-
hash['
|
609
|
+
hash['ICU_Open'] = { ratio: 0.0275, space_type_gen: true, default: false }
|
610
610
|
hash['ICU_PatRm'] = { ratio: 0.0115, space_type_gen: true, default: false }
|
611
611
|
hash['Kitchen'] = { ratio: 0.0414, space_type_gen: true, default: false }
|
612
612
|
hash['Lab'] = { ratio: 0.0236, space_type_gen: true, default: false }
|
@@ -1641,9 +1641,6 @@ module OsLib_ModelGeneration
|
|
1641
1641
|
end
|
1642
1642
|
if ! args.has_key?("perim_mult")
|
1643
1643
|
args["perim_mult"] = 1.0 # will not make two bars for extended perimeter
|
1644
|
-
puts "asdf, doesn't have it I'm adding it"
|
1645
|
-
else
|
1646
|
-
puts "asdf, already had it"
|
1647
1644
|
end
|
1648
1645
|
|
1649
1646
|
# lookup and replace argument values from upstream measures
|
@@ -2563,6 +2560,19 @@ module OsLib_ModelGeneration
|
|
2563
2560
|
# Make the standard applier
|
2564
2561
|
standard = Standard.build((args['template']).to_s)
|
2565
2562
|
|
2563
|
+
# validate climate zone
|
2564
|
+
if !args.has_key?('climate_zone') || args['climate_zone'] == 'Lookup From Model'
|
2565
|
+
climate_zone = standard.model_get_building_climate_zone_and_building_type(model)['climate_zone']
|
2566
|
+
runner.registerInfo("Using climate zone #{climate_zone} from model")
|
2567
|
+
else
|
2568
|
+
climate_zone = args['climate_zone']
|
2569
|
+
runner.registerInfo("Using climate zone #{climate_zone} from user arguments")
|
2570
|
+
end
|
2571
|
+
if climate_zone == ''
|
2572
|
+
runner.registerError("Could not determine climate zone from measure arguments or model.")
|
2573
|
+
return false
|
2574
|
+
end
|
2575
|
+
|
2566
2576
|
# make sure daylight savings is turned on up prior to any sizing runs being done.
|
2567
2577
|
if args['enable_dst']
|
2568
2578
|
start_date = '2nd Sunday in March'
|
@@ -2649,13 +2659,6 @@ module OsLib_ModelGeneration
|
|
2649
2659
|
else
|
2650
2660
|
is_residential = 'No'
|
2651
2661
|
end
|
2652
|
-
if !args.has_key?('climate_zone') || args['climate_zone'] == 'Lookup From Model'
|
2653
|
-
climate_zone = standard.model_get_building_climate_zone_and_building_type(model)['climate_zone']
|
2654
|
-
runner.registerInfo("Using climate zone #{climate_zone} from model")
|
2655
|
-
else
|
2656
|
-
climate_zone = args['climate_zone']
|
2657
|
-
runner.registerInfo("Using climate zone #{climate_zone} from user arguments")
|
2658
|
-
end
|
2659
2662
|
bldg_def_const_set = standard.model_add_construction_set(model, climate_zone, lookup_building_type, nil, is_residential)
|
2660
2663
|
if bldg_def_const_set.is_initialized
|
2661
2664
|
bldg_def_const_set = bldg_def_const_set.get
|
@@ -2800,16 +2803,25 @@ module OsLib_ModelGeneration
|
|
2800
2803
|
end
|
2801
2804
|
end
|
2802
2805
|
|
2803
|
-
#
|
2806
|
+
# add_daylighting_controls (since outdated measure don't have this default to true if arg not found)
|
2807
|
+
if !args.has_key?('add_daylighting_controls')
|
2808
|
+
args['add_daylighting_controls'] = true
|
2809
|
+
end
|
2810
|
+
if args['add_daylighting_controls']
|
2811
|
+
# remove add_daylighting_controls objects
|
2812
|
+
if args['remove_objects']
|
2813
|
+
model.getDaylightingControls.each(&:remove)
|
2814
|
+
end
|
2804
2815
|
|
2805
|
-
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
|
2816
|
+
# add daylight controls, need to perform a sizing run for 2010
|
2817
|
+
if args['template'] == '90.1-2010'
|
2818
|
+
if standard.model_run_sizing_run(model, "#{Dir.pwd}/SRvt") == false
|
2819
|
+
log_messages_to_runner(runner, debug = true)
|
2820
|
+
return false
|
2821
|
+
end
|
2810
2822
|
end
|
2811
|
-
end
|
2812
2823
|
standard.model_add_daylighting_controls(model)
|
2824
|
+
end
|
2813
2825
|
|
2814
2826
|
# add refrigeration
|
2815
2827
|
if args['add_refrigeration']
|
@@ -3037,20 +3049,6 @@ module OsLib_ModelGeneration
|
|
3037
3049
|
end
|
3038
3050
|
end
|
3039
3051
|
|
3040
|
-
# add internal mass
|
3041
|
-
if args['add_internal_mass']
|
3042
|
-
|
3043
|
-
if args['remove_objects']
|
3044
|
-
model.getSpaceLoads.each do |instance|
|
3045
|
-
next unless instance.to_InternalMass.is_initialized
|
3046
|
-
instance.remove
|
3047
|
-
end
|
3048
|
-
end
|
3049
|
-
|
3050
|
-
# add internal mass to conditioned spaces; needs to happen after thermostats are applied
|
3051
|
-
standard.model_add_internal_mass(model, primary_bldg_type)
|
3052
|
-
end
|
3053
|
-
|
3054
3052
|
# set unmet hours tolerance
|
3055
3053
|
unmet_hrs_tol_r = args['unmet_hours_tolerance']
|
3056
3054
|
unmet_hrs_tol_k = OpenStudio.convert(unmet_hrs_tol_r, 'R', 'K').get
|
@@ -49,14 +49,17 @@ module OpenStudio
|
|
49
49
|
setup_subtasks(@name)
|
50
50
|
end
|
51
51
|
|
52
|
-
def set_extension_class(extension_class)
|
52
|
+
def set_extension_class(extension_class, github_repo = '')
|
53
53
|
@extension_class = extension_class
|
54
54
|
@extension = extension_class.new
|
55
55
|
@root_dir = @extension.root_dir
|
56
|
-
|
56
|
+
# Catch if measures_dir is nil, then just make it an empty string
|
57
|
+
@measures_dir = @extension.measures_dir || ''
|
58
|
+
@staged_path = @measures_dir + '/staged'
|
57
59
|
@core_dir = @extension.core_dir
|
58
60
|
@doc_templates_dir = @extension.doc_templates_dir
|
59
61
|
@files_dir = @extension.files_dir
|
62
|
+
@github_repo = github_repo
|
60
63
|
end
|
61
64
|
|
62
65
|
private
|
@@ -65,22 +68,20 @@ module OpenStudio
|
|
65
68
|
namespace name do
|
66
69
|
desc 'Run the CLI task to check for measure updates'
|
67
70
|
task update_measures: ['measures:add_license', 'measures:add_readme', 'measures:copy_resources', 'update_copyright'] do
|
68
|
-
puts 'updating measures
|
71
|
+
puts 'updating measures'
|
69
72
|
runner = OpenStudio::Extension::Runner.new(Dir.pwd)
|
70
73
|
runner.update_measures(@measures_dir)
|
71
74
|
end
|
72
75
|
|
73
76
|
desc 'List measures'
|
74
77
|
task :list_measures do
|
75
|
-
puts 'Listing measures
|
78
|
+
puts 'Listing measures'
|
76
79
|
runner = OpenStudio::Extension::Runner.new(Dir.pwd)
|
77
80
|
runner.list_measures(@measures_dir)
|
78
81
|
end
|
79
82
|
|
80
83
|
desc 'Use openstudio system ruby to run tests'
|
81
84
|
task :test_with_openstudio do
|
82
|
-
# puts Dir.pwd
|
83
|
-
# puts Rake.original_dir
|
84
85
|
puts 'testing with openstudio'
|
85
86
|
runner = OpenStudio::Extension::Runner.new(Dir.pwd)
|
86
87
|
result = runner.test_measures_with_cli(@measures_dir)
|
@@ -90,12 +91,6 @@ module OpenStudio
|
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
93
|
-
# TODO: Implement this eventually... comment out for now.
|
94
|
-
# desc 'Use openstudio docker image to run tests'
|
95
|
-
# task :test_with_docker do
|
96
|
-
# puts 'testing with docker'
|
97
|
-
# end
|
98
|
-
|
99
94
|
# namespace for measure operations
|
100
95
|
namespace 'measures' do
|
101
96
|
desc 'Copy the resources files to individual measures'
|
@@ -143,14 +138,233 @@ module OpenStudio
|
|
143
138
|
runner.update_copyright(@root_dir, @doc_templates_dir)
|
144
139
|
end
|
145
140
|
|
146
|
-
desc '
|
147
|
-
task :
|
148
|
-
|
141
|
+
desc 'Print the change log from GitHub. Date format: yyyy-mm-dd'
|
142
|
+
task :change_log, [:start_date, :end_date, :apikey] do |t, args|
|
143
|
+
require 'change_log'
|
144
|
+
cl = ChangeLog.new(@github_repo, *args)
|
145
|
+
cl.process
|
146
|
+
cl.print_issues
|
149
147
|
end
|
150
148
|
|
151
|
-
|
152
|
-
|
153
|
-
|
149
|
+
namespace 'bcl' do
|
150
|
+
desc 'Test BCL login'
|
151
|
+
task :test_login do
|
152
|
+
puts 'test BCL login'
|
153
|
+
bcl = ::BCL::ComponentMethods.new
|
154
|
+
bcl.login
|
155
|
+
end
|
156
|
+
|
157
|
+
# for custom search, populate env var: bcl_search_keyword
|
158
|
+
desc 'Search BCL'
|
159
|
+
task :search_measures do
|
160
|
+
puts 'test search BCL'
|
161
|
+
bcl = ::BCL::ComponentMethods.new
|
162
|
+
bcl.login
|
163
|
+
|
164
|
+
# check for env var specifying keyword first
|
165
|
+
if ENV['bcl_search_keyword']
|
166
|
+
keyword = ENV['bcl_search_keyword']
|
167
|
+
else
|
168
|
+
keyword = 'Space'
|
169
|
+
end
|
170
|
+
num_results = 10
|
171
|
+
# bcl.search params: search_string, filter_string, return_all_results?
|
172
|
+
puts "searching BCL measures for keyword: #{keyword}"
|
173
|
+
results = bcl.search(keyword, "fq[]=bundle:nrel_measure&show_rows=#{num_results}", false)
|
174
|
+
puts "there are #{results[:result].count} results"
|
175
|
+
results[:result].each do |res|
|
176
|
+
puts(res[:measure][:name]).to_s
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# to call with argument: "openstudio:bcl:stage[true]" (true = remove existing staged content)
|
181
|
+
desc 'Copy the measures/components to a location that can be uploaded to BCL'
|
182
|
+
task :stage, [:reset] do |t, args|
|
183
|
+
puts 'Staging measures for BCL'
|
184
|
+
# initialize BCL and login
|
185
|
+
bcl = ::BCL::ComponentMethods.new
|
186
|
+
bcl.login
|
187
|
+
|
188
|
+
# process reset options: true to clear out old staged content
|
189
|
+
options = { reset: false }
|
190
|
+
if args[:reset].to_s == 'true'
|
191
|
+
options[:reset] = true
|
192
|
+
end
|
193
|
+
|
194
|
+
# ensure staged dir exists
|
195
|
+
FileUtils.mkdir_p(@staged_path)
|
196
|
+
|
197
|
+
# delete existing tarballs if reset is true
|
198
|
+
if options[:reset]
|
199
|
+
puts 'Deleting existing staged content'
|
200
|
+
FileUtils.rm_rf(Dir.glob("#{@staged_path}/*"))
|
201
|
+
end
|
202
|
+
|
203
|
+
# create new and existing directories
|
204
|
+
FileUtils.mkdir_p(@staged_path.to_s + '/update')
|
205
|
+
FileUtils.mkdir_p(@staged_path.to_s + '/push/component')
|
206
|
+
FileUtils.mkdir_p(@staged_path.to_s + '/push/measure')
|
207
|
+
|
208
|
+
# keep track of noop, update, push
|
209
|
+
noops = 0
|
210
|
+
new_ones = 0
|
211
|
+
updates = 0
|
212
|
+
|
213
|
+
# get all content directories to process
|
214
|
+
dirs = Dir.glob("#{@measures_dir}/*")
|
215
|
+
|
216
|
+
dirs.each do |dir|
|
217
|
+
next if dir.include?('Rakefile') || File.basename(dir) == 'staged'
|
218
|
+
current_d = Dir.pwd
|
219
|
+
content_name = File.basename(dir)
|
220
|
+
puts '', '---'
|
221
|
+
puts "Generating #{content_name}"
|
222
|
+
|
223
|
+
Dir.chdir(dir)
|
224
|
+
|
225
|
+
# figure out whether to upload new or update existing
|
226
|
+
files = Pathname.glob('**/*')
|
227
|
+
uuid = nil
|
228
|
+
vid = nil
|
229
|
+
content_type = 'measure'
|
230
|
+
|
231
|
+
paths = []
|
232
|
+
files.each do |file|
|
233
|
+
# don't tar tests/outputs directory
|
234
|
+
next if file.to_s.start_with?('tests/output') # From measure testing process
|
235
|
+
next if file.to_s.start_with?('tests/test') # From openstudio-measure-tester-gem
|
236
|
+
next if file.to_s.start_with?('tests/coverage') # From openstudio-measure-tester-gem
|
237
|
+
next if file.to_s.start_with?('test_results') # From openstudio-measure-tester-gem
|
238
|
+
paths << file.to_s
|
239
|
+
if file.to_s =~ /^.{0,2}component.xml$/ || file.to_s =~ /^.{0,2}measure.xml$/
|
240
|
+
if file.to_s.match?(/^.{0,2}component.xml$/)
|
241
|
+
content_type = 'component'
|
242
|
+
end
|
243
|
+
# extract uuid and vid
|
244
|
+
uuid, vid = bcl.uuid_vid_from_xml(file)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
puts "UUID: #{uuid}, VID: #{vid}"
|
248
|
+
|
249
|
+
# note: if uuid is missing, will assume new content
|
250
|
+
action = bcl.search_by_uuid(uuid, vid)
|
251
|
+
puts "#{content_name} ACTION TO TAKE: #{action}"
|
252
|
+
# new content functionality needs to know if measure or component. update is agnostic.
|
253
|
+
if action == 'noop' # ignore up-to-date content
|
254
|
+
puts " - WARNING: local #{content_name} uuid and vid match BCL... no update will be performed"
|
255
|
+
noops += 1
|
256
|
+
next
|
257
|
+
elsif action == 'update'
|
258
|
+
# puts "#{content_name} labeled as update for BCL"
|
259
|
+
destination = @staged_path + '/' + action + '/' + "#{content_name}.tar.gz"
|
260
|
+
updates += 1
|
261
|
+
elsif action == 'push'
|
262
|
+
# puts "#{content_name} labeled as new content for BCL"
|
263
|
+
destination = @staged_path + '/' + action + '/' + content_type + "/#{content_name}.tar.gz"
|
264
|
+
new_ones += 1
|
265
|
+
end
|
266
|
+
|
267
|
+
puts "destination: #{destination}"
|
268
|
+
|
269
|
+
# copy over only if 'reset_receipts' is set to TRUE. otherwise ignore if file exists already
|
270
|
+
if File.exist?(destination)
|
271
|
+
if reset
|
272
|
+
FileUtils.rm(destination)
|
273
|
+
::BCL.tarball(destination, paths)
|
274
|
+
else
|
275
|
+
puts "*** WARNING: File #{content_name}.tar.gz already exists in staged directory... keeping existing file. To overwrite, set reset_receipts arg to true ***"
|
276
|
+
end
|
277
|
+
else
|
278
|
+
::BCL.tarball(destination, paths)
|
279
|
+
end
|
280
|
+
Dir.chdir(current_d)
|
281
|
+
end
|
282
|
+
puts '', "****STAGING DONE**** #{new_ones} new content, #{updates} updates, #{noops} skipped (already up-to-date on BCL)", ''
|
283
|
+
end
|
284
|
+
|
285
|
+
desc 'Upload measures from the specified location.'
|
286
|
+
task :push do
|
287
|
+
puts 'Push measures to BCL'
|
288
|
+
|
289
|
+
# initialize BCL and login
|
290
|
+
bcl = ::BCL::ComponentMethods.new
|
291
|
+
bcl.login
|
292
|
+
reset = false
|
293
|
+
|
294
|
+
total_count = 0
|
295
|
+
successes = 0
|
296
|
+
errors = 0
|
297
|
+
skipped = 0
|
298
|
+
|
299
|
+
# grab all the new measure and component tar files and push to bcl
|
300
|
+
['measure', 'component'].each do |content_type|
|
301
|
+
items = []
|
302
|
+
paths = Pathname.glob(@staged_path.to_s + "/push/#{content_type}/*.tar.gz")
|
303
|
+
paths.each do |path|
|
304
|
+
# puts path
|
305
|
+
items << path.to_s
|
306
|
+
end
|
307
|
+
|
308
|
+
items.each do |item|
|
309
|
+
puts item.split('/').last
|
310
|
+
total_count += 1
|
311
|
+
|
312
|
+
receipt_file = File.dirname(item) + '/' + File.basename(item, '.tar.gz') + '.receipt'
|
313
|
+
if !reset && File.exist?(receipt_file)
|
314
|
+
skipped += 1
|
315
|
+
puts 'SKIP: receipt file found'
|
316
|
+
next
|
317
|
+
end
|
318
|
+
|
319
|
+
valid, res = bcl.push_content(item, true, "nrel_#{content_type}")
|
320
|
+
if valid
|
321
|
+
successes += 1
|
322
|
+
else
|
323
|
+
errors += 1
|
324
|
+
if res.key?(:error)
|
325
|
+
puts " ERROR MESSAGE: #{res[:error]}"
|
326
|
+
else
|
327
|
+
puts "ERROR: #{res.inspect.chomp}"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
puts '', '---'
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# grab all the updated content (measures and components) tar files and push to bcl
|
335
|
+
items = []
|
336
|
+
paths = Pathname.glob(@staged_path.to_s + '/update/*.tar.gz')
|
337
|
+
paths.each do |path|
|
338
|
+
# puts path
|
339
|
+
items << path.to_s
|
340
|
+
end
|
341
|
+
items.each do |item|
|
342
|
+
puts item.split('/').last
|
343
|
+
total_count += 1
|
344
|
+
|
345
|
+
receipt_file = File.dirname(item) + '/' + File.basename(item, '.tar.gz') + '.receipt'
|
346
|
+
if !reset && File.exist?(receipt_file)
|
347
|
+
skipped += 1
|
348
|
+
puts 'SKIP: receipt file found'
|
349
|
+
next
|
350
|
+
end
|
351
|
+
|
352
|
+
valid, res = bcl.update_content(item, true)
|
353
|
+
if valid
|
354
|
+
successes += 1
|
355
|
+
else
|
356
|
+
errors += 1
|
357
|
+
if res.key?(:error)
|
358
|
+
puts " ERROR MESSAGE: #{res[:error]}"
|
359
|
+
else
|
360
|
+
puts "ERROR MESSAGE: #{res.inspect.chomp}"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
puts '', '---'
|
364
|
+
end
|
365
|
+
|
366
|
+
puts "****UPLOAD DONE**** #{total_count} total, #{successes} success, #{errors} failures, #{skipped} skipped"
|
367
|
+
end
|
154
368
|
end
|
155
369
|
end
|
156
370
|
end
|
@@ -41,6 +41,7 @@ require 'openstudio'
|
|
41
41
|
require 'yaml'
|
42
42
|
require 'fileutils'
|
43
43
|
require 'parallel'
|
44
|
+
require 'bcl'
|
44
45
|
|
45
46
|
module OpenStudio
|
46
47
|
module Extension
|
@@ -55,7 +56,7 @@ module OpenStudio
|
|
55
56
|
# compatible with the OpenStudio CLI.
|
56
57
|
##
|
57
58
|
# @param [String] dirname Directory to run commands in, defaults to Dir.pwd. If directory includes a Gemfile then create a local bundle.
|
58
|
-
# @param bundle_without [
|
59
|
+
# @param bundle_without [Array] List of strings of the groups to exclude when running the bundle command
|
59
60
|
# @param options [Hash] Hash describing options for running the simulation. These are the defaults for all runs unless overriden within the run_* methods. Note if options is used, then a local runner.conf file will not be loaded.
|
60
61
|
# @option options [String] :max_datapoints Max number of datapoints to run
|
61
62
|
# @option options [String] :num_parallel Number of simulations to run in parallel at a time
|
@@ -560,21 +561,21 @@ module OpenStudio
|
|
560
561
|
puts "Encoding.default_internal = #{Encoding.default_internal}"
|
561
562
|
|
562
563
|
paths.each do |path|
|
563
|
-
Dir[path[:glob]].each do |
|
564
|
-
puts "Updating license in file #{
|
565
|
-
f = File.read(
|
566
|
-
if f
|
564
|
+
Dir[path[:glob]].each do |dir_file|
|
565
|
+
puts "Updating license in file #{dir_file}"
|
566
|
+
f = File.read(dir_file)
|
567
|
+
if f.match?(path[:regex])
|
567
568
|
puts ' License found -- updating'
|
568
|
-
File.open(
|
569
|
+
File.open(dir_file, 'w') { |write| write << f.gsub(path[:regex], path[:license]) }
|
569
570
|
elsif f =~ /\(C\)/i || f =~ /\(Copyright\)/i
|
570
571
|
puts ' File already has copyright -- skipping'
|
571
572
|
else
|
572
573
|
puts ' No license found -- adding'
|
573
|
-
if f
|
574
|
+
if f.match?(/#!/)
|
574
575
|
puts ' CANNOT add license to file automatically, add it manually and it will update automatically in the future'
|
575
576
|
next
|
576
577
|
end
|
577
|
-
File.open(
|
578
|
+
File.open(dir_file, 'w') { |write| write << f.insert(0, path[:license] + "\n") }
|
578
579
|
end
|
579
580
|
end
|
580
581
|
end
|