urbanopt-cli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTING.md +58 -0
- data/Gemfile +4 -0
- data/Jenkinsfile +10 -0
- data/LICENSE.md +29 -0
- data/README.md +71 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/uo +5 -0
- data/example_files/Gemfile +59 -0
- data/example_files/example_project.json +580 -0
- data/example_files/mappers/Baseline.rb +257 -0
- data/example_files/mappers/HighEfficiency.rb +62 -0
- data/example_files/mappers/base_workflow.osw +111 -0
- data/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.ddy +536 -0
- data/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.epw +8768 -0
- data/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.stat +553 -0
- data/lib/change_log.rb +147 -0
- data/lib/uo_cli/version.rb +5 -0
- data/lib/uo_cli.rb +253 -0
- data/uo_cli.gemspec +44 -0
- metadata +169 -0
data/lib/change_log.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'github_api'
|
4
|
+
require 'date'
|
5
|
+
require 'optparse'
|
6
|
+
require 'optparse/date'
|
7
|
+
|
8
|
+
# Instructions:
|
9
|
+
# Get a token from github's settings (https://github.com/settings/tokens)
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# ruby change_log.rb -t abcdefghijklmnopqrstuvwxyz -s 2017-09-06
|
13
|
+
#
|
14
|
+
|
15
|
+
options = {}
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: change_log.rb [options]\n" +
|
18
|
+
"Prints New, Open, Closed Issues, and number of accepted PRs"
|
19
|
+
opts.separator ""
|
20
|
+
|
21
|
+
# defaults, go back 90 days
|
22
|
+
options[:start_date] = Date.today - 90
|
23
|
+
options[:end_date] = Date.today
|
24
|
+
|
25
|
+
opts.on('-s', '--start-date [DATE]', Date, 'Start of data (e.g. 2017-09-06)') do |v|
|
26
|
+
options[:start_date] = v
|
27
|
+
end
|
28
|
+
opts.on('-e', '--end-date [DATE]', Date, 'End of data (e.g. 2017-09-13)') do |v|
|
29
|
+
options[:end_date] = v
|
30
|
+
end
|
31
|
+
opts.on('-t', '--token [String]', String, 'Github API Token') do |v|
|
32
|
+
options[:token] = v
|
33
|
+
end
|
34
|
+
end.parse!
|
35
|
+
|
36
|
+
# Convert dates to time objects
|
37
|
+
options[:start_date] = Time.parse(options[:start_date].to_s)
|
38
|
+
options[:end_date] = Time.parse(options[:end_date].to_s)
|
39
|
+
puts options
|
40
|
+
|
41
|
+
### Repository options
|
42
|
+
repo_owner = 'URBANopt'
|
43
|
+
repo = 'uo-cli'
|
44
|
+
|
45
|
+
github = Github.new
|
46
|
+
if options[:token]
|
47
|
+
puts 'Using github token'
|
48
|
+
github = Github.new oauth_token: options[:token]
|
49
|
+
end
|
50
|
+
|
51
|
+
total_open_issues = []
|
52
|
+
total_open_pull_requests = []
|
53
|
+
new_issues = []
|
54
|
+
closed_issues = []
|
55
|
+
accepted_pull_requests = []
|
56
|
+
|
57
|
+
def get_num(issue)
|
58
|
+
issue.html_url.split('/')[-1].to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_issue_num(issue)
|
62
|
+
"\##{get_num(issue)}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_html_url(issue)
|
66
|
+
issue.html_url
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_title(issue)
|
70
|
+
issue.title
|
71
|
+
end
|
72
|
+
|
73
|
+
def print_issue(issue)
|
74
|
+
is_feature = false
|
75
|
+
issue.labels.each { |label| is_feature = true if label.name == 'Feature Request' }
|
76
|
+
|
77
|
+
if is_feature
|
78
|
+
"- Improved [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
|
79
|
+
else
|
80
|
+
"- Fixed [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Process Open Issues
|
85
|
+
results = -1
|
86
|
+
page = 1
|
87
|
+
while results != 0
|
88
|
+
resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
|
89
|
+
state: 'open', per_page: 100, page: page
|
90
|
+
results = resp.length
|
91
|
+
resp.env[:body].each do |issue, _index|
|
92
|
+
created = Time.parse(issue.created_at)
|
93
|
+
if !issue.key?(:pull_request)
|
94
|
+
total_open_issues << issue
|
95
|
+
if created >= options[:start_date] && created <= options[:end_date]
|
96
|
+
new_issues << issue
|
97
|
+
end
|
98
|
+
else
|
99
|
+
total_open_pull_requests << issue
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
page += 1
|
104
|
+
end
|
105
|
+
|
106
|
+
# Process Closed Issues
|
107
|
+
results = -1
|
108
|
+
page = 1
|
109
|
+
while results != 0
|
110
|
+
resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
|
111
|
+
state: 'closed', per_page: 100, page: page
|
112
|
+
results = resp.length
|
113
|
+
resp.env[:body].each do |issue, _index|
|
114
|
+
created = Time.parse(issue.created_at)
|
115
|
+
closed = Time.parse(issue.closed_at)
|
116
|
+
if !issue.key?(:pull_request)
|
117
|
+
if created >= options[:start_date] && created <= options[:end_date]
|
118
|
+
new_issues << issue
|
119
|
+
end
|
120
|
+
if closed >= options[:start_date] && closed <= options[:end_date]
|
121
|
+
closed_issues << issue
|
122
|
+
end
|
123
|
+
elsif closed >= options[:start_date] && closed <= options[:end_date]
|
124
|
+
accepted_pull_requests << issue
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
page += 1
|
129
|
+
end
|
130
|
+
|
131
|
+
closed_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
|
132
|
+
new_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
|
133
|
+
accepted_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
|
134
|
+
total_open_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
|
135
|
+
|
136
|
+
puts "Total Open Issues: #{total_open_issues.length}"
|
137
|
+
puts "Total Open Pull Requests: #{total_open_pull_requests.length}"
|
138
|
+
puts "\nDate Range: #{options[:start_date].strftime('%m/%d/%y')} - #{options[:end_date].strftime('%m/%d/%y')}:"
|
139
|
+
puts "\nNew Issues: #{new_issues.length} (" + new_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
|
140
|
+
|
141
|
+
puts "\nClosed Issues: #{closed_issues.length}"
|
142
|
+
closed_issues.each { |issue| puts print_issue(issue) }
|
143
|
+
|
144
|
+
puts "\nAccepted Pull Requests: #{accepted_pull_requests.length}"
|
145
|
+
accepted_pull_requests.each { |issue| puts print_issue(issue) }
|
146
|
+
|
147
|
+
puts "\nAll Open Issues: #{total_open_issues.length} (" + total_open_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
|
data/lib/uo_cli.rb
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
#!/usr/bin/ ruby
|
2
|
+
|
3
|
+
#*********************************************************************************
|
4
|
+
# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
|
5
|
+
# contributors. All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
8
|
+
# are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# Redistributions of source code must retain the above copyright notice, this list
|
11
|
+
# of conditions and the following disclaimer.
|
12
|
+
#
|
13
|
+
# Redistributions in binary form must reproduce the above copyright notice, this
|
14
|
+
# list of conditions and the following disclaimer in the documentation and/or other
|
15
|
+
# materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# Neither the name of the copyright holder nor the names of its contributors may be
|
18
|
+
# used to endorse or promote products derived from this software without specific
|
19
|
+
# prior written permission.
|
20
|
+
#
|
21
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
22
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
23
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
24
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
25
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
26
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
28
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
29
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
30
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
#*********************************************************************************
|
32
|
+
|
33
|
+
require "uo_cli/version"
|
34
|
+
require "optparse"
|
35
|
+
require "urbanopt/geojson"
|
36
|
+
require "urbanopt/scenario"
|
37
|
+
require "csv"
|
38
|
+
require "json"
|
39
|
+
require "openssl"
|
40
|
+
|
41
|
+
|
42
|
+
module URBANopt
|
43
|
+
module CLI
|
44
|
+
|
45
|
+
# Set up user interface
|
46
|
+
@user_input = {}
|
47
|
+
the_parser = OptionParser.new do |opts|
|
48
|
+
opts.banner = "Usage: uo [-pmradsfv]\n" +
|
49
|
+
"\n" +
|
50
|
+
"URBANopt CLI. \n" +
|
51
|
+
"First create a project folder with -p, then run additional commands as desired \n"
|
52
|
+
opts.separator ""
|
53
|
+
|
54
|
+
opts.on("-p", "--project_folder <DIR>",String, "Create project directory named <DIR> in your current folder") do |folder|
|
55
|
+
@user_input[:project_folder] = folder
|
56
|
+
end
|
57
|
+
opts.on("-m", "--make_scenario", String, "Create ScenarioCSV files for each MapperFile using the Feature file path. Must specify -f argument\n" +
|
58
|
+
" Example: uo -m -f example_project.json\n" +
|
59
|
+
" You must be insde the project directory you just created for this to work") do
|
60
|
+
@user_input[:make_scenario_from] = "Create scenario files from FeatureFiles according to the MapperFiles in the 'mappers' directory" # This text does not get displayed to the user
|
61
|
+
end
|
62
|
+
opts.on("-r", "--run", String, "Run simulations. Must specify -s & -f arguments\n" +
|
63
|
+
" Example: uo -r -s baseline_scenario.csv -f example_project.json") do
|
64
|
+
@user_input[:run_scenario] = "Run simulations" # This text does not get displayed to the user
|
65
|
+
end
|
66
|
+
opts.on("-a", "--aggregate", String, "Aggregate individual feature results to scenario-level results. Must specify -s & -f arguments\n" +
|
67
|
+
" Example: uo -a -s baseline_scenario.csv -f example_project.json") do
|
68
|
+
@user_input[:aggregate] = "Aggregate all features to a whole Scenario" # This text does not get displayed to the user
|
69
|
+
end
|
70
|
+
opts.on("-d", "--delete_scenario", String, "Delete results from scenario. Must specify -s argument\n" +
|
71
|
+
" Example: uo -d -s baseline_scenario.csv") do
|
72
|
+
@user_input[:delete_scenario] = "Delete scenario results that were created from <SFP>" # This text does not get displayed to the user
|
73
|
+
end
|
74
|
+
opts.on("-s", "--scenario_file <SFP>", String, "Specify <SFP> (ScenarioCSV file path). Used as input for other commands") do |scenario|
|
75
|
+
@user_input[:scenario] = scenario
|
76
|
+
end
|
77
|
+
opts.on("-f", "--feature_file <FFP>", String, "Specify <FFP> (Feature file path). Used as input for other commands") do |feature|
|
78
|
+
@user_input[:feature] = feature
|
79
|
+
end
|
80
|
+
opts.on("-v", "--version", "Show CLI version and exit") do
|
81
|
+
@user_input[:version_request] = VERSION
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
begin
|
86
|
+
the_parser.parse!
|
87
|
+
rescue OptionParser::InvalidOption => e
|
88
|
+
puts e
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# Simulate energy usage for each Feature in the Scenario\
|
93
|
+
# params\
|
94
|
+
# +scenario+:: _string_ Path to csv file that defines the scenario\
|
95
|
+
# +feature_file_path+:: _string_ Path to Feature File used to describe set of features in the district
|
96
|
+
#
|
97
|
+
# FIXME: This only works when scenario_file and feature_file are in the project root directory
|
98
|
+
# Also, feels a little weird that now I'm only using instance variables and not passing anything to this function. I guess it's ok?
|
99
|
+
def self.run_func
|
100
|
+
name = "#{@scenario_name.split('.')[0].capitalize}"
|
101
|
+
root_dir = File.absolute_path(@scenario_root)
|
102
|
+
run_dir = File.join(root_dir, 'run', name.downcase)
|
103
|
+
csv_file = File.join(root_dir, @scenario_name)
|
104
|
+
featurefile = File.join(root_dir, @feature_name)
|
105
|
+
mapper_files_dir = File.join(root_dir, "mappers")
|
106
|
+
num_header_rows = 1
|
107
|
+
|
108
|
+
feature_file = URBANopt::GeoJSON::GeoFile.from_file(featurefile)
|
109
|
+
scenario_output = URBANopt::Scenario::ScenarioCSV.new(name, root_dir, run_dir, feature_file, mapper_files_dir, csv_file, num_header_rows)
|
110
|
+
return scenario_output
|
111
|
+
end
|
112
|
+
|
113
|
+
# Create a scenario csv file from a FeatureFile
|
114
|
+
# params\
|
115
|
+
# +feature_file_path+:: _string_ Path to a FeatureFile
|
116
|
+
def self.create_scenario_csv_file(feature_file_path)
|
117
|
+
feature_file_json = JSON.parse(File.read(feature_file_path), :symbolize_names => true)
|
118
|
+
Dir["#{@feature_root}/mappers/*.rb"].each do |mapper_file|
|
119
|
+
mapper_root, mapper_base = File.split(mapper_file)
|
120
|
+
mapper_name = mapper_base.split('.')[0]
|
121
|
+
scenario_file_name = "#{mapper_name.downcase}_scenario.csv"
|
122
|
+
CSV.open(File.join(@feature_root, scenario_file_name), "wb", :write_headers => true,
|
123
|
+
:headers => ["Feature Id","Feature Name","Mapper Class"]) do |csv|
|
124
|
+
feature_file_json[:features].each do |feature|
|
125
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# Create project folder
|
133
|
+
# params\
|
134
|
+
# +dir_name+:: _string_ Name of new project folder
|
135
|
+
#
|
136
|
+
# Folder gets created in the current working directory
|
137
|
+
# Includes weather for UO's example location, a base workflow file, and mapper files to show a baseline and a high-efficiency option.
|
138
|
+
def self.create_project_folder(dir_name)
|
139
|
+
if Dir.exist?(dir_name)
|
140
|
+
abort("ERROR: there is already a directory here named #{dir_name}... aborting")
|
141
|
+
else
|
142
|
+
puts "CREATING URBANopt project directory: #{dir_name}"
|
143
|
+
Dir.mkdir dir_name
|
144
|
+
Dir.mkdir File.join(dir_name, 'mappers')
|
145
|
+
Dir.mkdir File.join(dir_name, 'weather')
|
146
|
+
mappers_dir_abs_path = File.absolute_path(File.join(dir_name, 'mappers/'))
|
147
|
+
weather_dir_abs_path = File.absolute_path(File.join(dir_name, 'weather/'))
|
148
|
+
|
149
|
+
# FIXME: When residential hpxml flow is implemented (https://github.com/urbanopt/urbanopt-example-geojson-project/pull/24 gets merged) these files will change
|
150
|
+
example_feature_file = "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/example_project.json"
|
151
|
+
example_gem_file = "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/Gemfile"
|
152
|
+
remote_mapper_files = [
|
153
|
+
"https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/mappers/base_workflow.osw",
|
154
|
+
"https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/mappers/Baseline.rb",
|
155
|
+
"https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/mappers/HighEfficiency.rb",
|
156
|
+
]
|
157
|
+
remote_weather_files = [
|
158
|
+
"https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.epw",
|
159
|
+
"https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.ddy",
|
160
|
+
"https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.stat",
|
161
|
+
]
|
162
|
+
|
163
|
+
# Download files to user's local machine
|
164
|
+
remote_mapper_files.each do |mapper_file|
|
165
|
+
mapper_root, mapper_base = File.split(mapper_file)
|
166
|
+
mapper_download = open(mapper_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
|
167
|
+
IO.copy_stream(mapper_download, File.join(mappers_dir_abs_path, mapper_base))
|
168
|
+
end
|
169
|
+
remote_weather_files.each do |weather_file|
|
170
|
+
weather_root, weather_base = File.split(weather_file)
|
171
|
+
weather_download = open(weather_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
|
172
|
+
IO.copy_stream(weather_download, File.join(weather_dir_abs_path, weather_base))
|
173
|
+
end
|
174
|
+
gem_root, gem_base = File.split(example_gem_file)
|
175
|
+
example_gem_download = open(example_gem_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
|
176
|
+
IO.copy_stream(example_gem_download, File.join(dir_name, gem_base))
|
177
|
+
|
178
|
+
feature_root, feature_base = File.split(example_feature_file)
|
179
|
+
example_feature_download = open(example_feature_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
|
180
|
+
IO.copy_stream(example_feature_download, File.join(dir_name, feature_base))
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
# Perform CLI actions
|
186
|
+
if @user_input[:project_folder]
|
187
|
+
create_project_folder(@user_input[:project_folder])
|
188
|
+
puts "\nAn example FeatureFile is included: 'example_project.json'. You may place your own FeatureFile alongside the example."
|
189
|
+
puts "Weather data is provided for the example FeatureFile. Additional weather data files may be downloaded from energyplus.net/weather for free"
|
190
|
+
puts "If you use additional weather files, ensure they are added to the 'weather' directory. You will need to configure your mapper file and your osw file to use the desired weather file"
|
191
|
+
puts "Next, move inside your new folder ('cd <FolderYouJustCreated>') and create ScenarioFiles using this CLI: 'uo -m -f <FFP>'"
|
192
|
+
end
|
193
|
+
|
194
|
+
if @user_input[:make_scenario_from]
|
195
|
+
if @user_input[:feature].nil?
|
196
|
+
abort("\nYou must provide the '-s' flag and a valid path to a FeatureFile!\n---\n\n")
|
197
|
+
end
|
198
|
+
@feature_root, @feature_name = File.split(@user_input[:feature])
|
199
|
+
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}..."
|
200
|
+
create_scenario_csv_file(@user_input[:feature])
|
201
|
+
puts "Done"
|
202
|
+
end
|
203
|
+
|
204
|
+
if @user_input[:run_scenario]
|
205
|
+
if @user_input[:scenario].nil?
|
206
|
+
abort("\nYou must provide '-s' flag and a valid path to a ScenarioFile!\n---\n\n")
|
207
|
+
end
|
208
|
+
if @user_input[:feature].nil?
|
209
|
+
abort("\nYou must provide '-f' flag and a valid path to a FeatureFile!\n---\n\n")
|
210
|
+
end
|
211
|
+
@scenario_root, @scenario_name = File.split(@user_input[:scenario])
|
212
|
+
@feature_root, @feature_name = File.split(@user_input[:feature])
|
213
|
+
puts "\nSimulating features of '#{@feature_name}' as directed by '#{@scenario_name}'...\n\n"
|
214
|
+
scenario_runner = URBANopt::Scenario::ScenarioRunnerOSW.new
|
215
|
+
scenario_runner.run(run_func())
|
216
|
+
puts "Done"
|
217
|
+
end
|
218
|
+
|
219
|
+
if @user_input[:aggregate]
|
220
|
+
if @user_input[:scenario].nil?
|
221
|
+
abort("\nYou must provide '-s' flag and a valid path to a ScenarioFile!\n---\n\n")
|
222
|
+
end
|
223
|
+
if @user_input[:feature].nil?
|
224
|
+
abort("\nYou must provide '-f' flag and a valid path to a FeatureFile!\n---\n\n")
|
225
|
+
end
|
226
|
+
@scenario_root, @scenario_name = File.split(@user_input[:scenario])
|
227
|
+
@feature_root, @feature_name = File.split(@user_input[:feature])
|
228
|
+
puts "\nAggregating results across all features of #{@feature_name} according to '#{@scenario_name}'..."
|
229
|
+
scenario_result = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(run_func()).run
|
230
|
+
scenario_result.save
|
231
|
+
puts "Done"
|
232
|
+
end
|
233
|
+
|
234
|
+
if @user_input[:delete_scenario]
|
235
|
+
if @user_input[:scenario].nil?
|
236
|
+
abort("\nYou must provide '-s' flag and a valid path to a ScenarioFile!\n---\n\n")
|
237
|
+
end
|
238
|
+
@scenario_root, @scenario_name = File.split(@user_input[:scenario])
|
239
|
+
scenario_name = @scenario_name.split('.')[0]
|
240
|
+
scenario_root = File.absolute_path(@scenario_root)
|
241
|
+
scenario_results_dir = File.join(scenario_root, 'run', scenario_name)
|
242
|
+
puts "\nDeleting previous results from '#{@scenario_name}'..."
|
243
|
+
FileUtils.rm_rf(scenario_results_dir)
|
244
|
+
puts "Done"
|
245
|
+
end
|
246
|
+
|
247
|
+
if @user_input[:version_request]
|
248
|
+
puts "URBANopt CLI version: #{@user_input[:version_request]}"
|
249
|
+
end
|
250
|
+
|
251
|
+
end # End module CLI
|
252
|
+
|
253
|
+
end # End module Urbanopt
|
data/uo_cli.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "uo_cli/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "urbanopt-cli"
|
8
|
+
spec.version = URBANopt::CLI::VERSION
|
9
|
+
spec.authors = ["Nathan Moore"]
|
10
|
+
spec.email = ["nathan.moore@nrel.gov"]
|
11
|
+
|
12
|
+
spec.summary = "URBANopt CLI"
|
13
|
+
spec.description = "Interfacing with URBANopt"
|
14
|
+
spec.homepage = "https://docs.urbanopt.net/"
|
15
|
+
|
16
|
+
if spec.respond_to?(:metadata)
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
else
|
20
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
21
|
+
end
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
|
+
end
|
28
|
+
spec.bindir = "bin"
|
29
|
+
# spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.executables = ["uo"]
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_dependency "urbanopt-scenario", "~> 0.1.1"
|
34
|
+
spec.add_dependency "urbanopt-geojson", "~> 0.1.0"
|
35
|
+
|
36
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
37
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
38
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
39
|
+
spec.add_development_dependency "github_api", "~> 0.18.0"
|
40
|
+
|
41
|
+
# Set specific version while we are on Ruby 2.2.4
|
42
|
+
spec.add_development_dependency "rack", "2.1.2"
|
43
|
+
|
44
|
+
end
|