Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/process/kill.h" | 8 #include "base/process/kill.h" |
| 9 #include "base/process/launch.h" | 9 #include "base/process/launch.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 return false; | 229 return false; |
| 230 } | 230 } |
| 231 #endif | 231 #endif |
| 232 | 232 |
| 233 } // namespace | 233 } // namespace |
| 234 | 234 |
| 235 const char kExecScript[] = "exec_script"; | 235 const char kExecScript[] = "exec_script"; |
| 236 const char kExecScript_Help[] = | 236 const char kExecScript_Help[] = |
| 237 "exec_script: Synchronously run a script and return the output.\n" | 237 "exec_script: Synchronously run a script and return the output.\n" |
| 238 "\n" | 238 "\n" |
| 239 " exec_script(filename, arguments, input_conversion,\n" | 239 " exec_script(filename [, arguments [, input_conversion [,\n" |
|
bbudge
2014/01/08 23:22:32
I can't grok these brackets.
brettw
2014/01/09 23:48:53
I changed this to use a more C++ style of annotati
bbudge
2014/01/10 00:37:54
Sorry, I somehow didn't think the left/right brack
| |
| 240 " [file_dependencies])\n" | 240 " file_dependencies]]])\n" |
| 241 "\n" | 241 "\n" |
| 242 " Runs the given script, returning the stdout of the script. The build\n" | 242 " Runs the given script, returning the stdout of the script. The build\n" |
| 243 " generation will fail if the script does not exist or returns a nonzero\n" | 243 " generation will fail if the script does not exist or returns a nonzero\n" |
| 244 " exit code.\n" | 244 " exit code.\n" |
| 245 "\n" | 245 "\n" |
| 246 " The current directory when executing the script will be the root\n" | 246 " The current directory when executing the script will be the root\n" |
| 247 " build directory. If you are passing file names, you will want to use\n" | 247 " build directory. If you are passing file names, you will want to use\n" |
| 248 " the rebase_path() function to make file names relative to this\n" | 248 " the rebase_path() function to make file names relative to this\n" |
| 249 " path (see \"gn help rebase_path\").\n" | 249 " path (see \"gn help rebase_path\").\n" |
| 250 "\n" | 250 "\n" |
| 251 "Arguments:\n" | 251 "Arguments:\n" |
| 252 "\n" | 252 "\n" |
| 253 " filename:\n" | 253 " filename:\n" |
| 254 " File name of python script to execute. Non-absolute names will\n" | 254 " File name of python script to execute. Non-absolute names will\n" |
| 255 " be treated as relative to the current build file.\n" | 255 " be treated as relative to the current build file.\n" |
| 256 "\n" | 256 "\n" |
| 257 " arguments:\n" | 257 " arguments:\n" |
| 258 " A list of strings to be passed to the script as arguments.\n" | 258 " A list of strings to be passed to the script as arguments.\n" |
| 259 " May be unspecified or the empty list which means no arguments.\n" | |
| 259 "\n" | 260 "\n" |
| 260 " input_conversion:\n" | 261 " input_conversion:\n" |
| 261 " Controls how the file is read and parsed.\n" | 262 " Controls how the file is read and parsed.\n" |
| 262 " See \"gn help input_conversion\".\n" | 263 " See \"gn help input_conversion\".\n" |
| 263 "\n" | 264 "\n" |
| 265 " If unspecified, defaults to the empty string which causes the\n" | |
| 266 " script result to be discarded. exec script will return None.\n" | |
| 267 "\n" | |
| 264 " dependencies:\n" | 268 " dependencies:\n" |
| 265 " (Optional) A list of files that this script reads or otherwise\n" | 269 " (Optional) A list of files that this script reads or otherwise\n" |
| 266 " depends on. These dependencies will be added to the build result\n" | 270 " depends on. These dependencies will be added to the build result\n" |
| 267 " such that if any of them change, the build will be regenerated and\n" | 271 " such that if any of them change, the build will be regenerated and\n" |
| 268 " the script will be re-run.\n" | 272 " the script will be re-run.\n" |
| 269 "\n" | 273 "\n" |
| 270 " The script itself will be an implicit dependency so you do not\n" | 274 " The script itself will be an implicit dependency so you do not\n" |
| 271 " need to list it.\n" | 275 " need to list it.\n" |
| 272 "\n" | 276 "\n" |
| 273 "Example:\n" | 277 "Example:\n" |
| 274 "\n" | 278 "\n" |
| 275 " all_lines = exec_script(\"myscript.py\", [some_input], \"list lines\",\n" | 279 " all_lines = exec_script(\"myscript.py\", [some_input], \"list lines\",\n" |
| 276 " [ rebase_path(\"data_file.txt\", \".\"," | 280 " [ rebase_path(\"data_file.txt\", \".\"," |
| 277 " root_build_dir) ])\n"; | 281 " root_build_dir) ])\n" |
| 282 "\n" | |
| 283 " # This example just calls the script with no arguments and discards\n" | |
| 284 " # the result.\n" | |
| 285 " exec_script(\"//foo/bar/myscript.py\")\n"; | |
| 278 | 286 |
| 279 Value RunExecScript(Scope* scope, | 287 Value RunExecScript(Scope* scope, |
| 280 const FunctionCallNode* function, | 288 const FunctionCallNode* function, |
| 281 const std::vector<Value>& args, | 289 const std::vector<Value>& args, |
| 282 Err* err) { | 290 Err* err) { |
| 283 if (args.size() != 3 && args.size() != 4) { | 291 if (args.size() < 1 || args.size() > 4) { |
| 284 *err = Err(function->function(), "Wrong number of arguments to exec_script", | 292 *err = Err(function->function(), "Wrong number of arguments to exec_script", |
| 285 "I expected three or four arguments."); | 293 "I expected between one and four arguments."); |
| 286 return Value(); | 294 return Value(); |
| 287 } | 295 } |
| 288 | 296 |
| 289 const Settings* settings = scope->settings(); | 297 const Settings* settings = scope->settings(); |
| 290 const BuildSettings* build_settings = settings->build_settings(); | 298 const BuildSettings* build_settings = settings->build_settings(); |
| 291 const SourceDir& cur_dir = scope->GetSourceDir(); | 299 const SourceDir& cur_dir = scope->GetSourceDir(); |
| 292 | 300 |
| 293 // Find the python script to run. | 301 // Find the python script to run. |
| 294 if (!args[0].VerifyTypeIs(Value::STRING, err)) | 302 if (!args[0].VerifyTypeIs(Value::STRING, err)) |
| 295 return Value(); | 303 return Value(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 320 build_settings->GetFullPath(cur_dir.ResolveRelativeFile( | 328 build_settings->GetFullPath(cur_dir.ResolveRelativeFile( |
| 321 deps_value.list_value()[0].string_value()))); | 329 deps_value.list_value()[0].string_value()))); |
| 322 } | 330 } |
| 323 } | 331 } |
| 324 | 332 |
| 325 // Make the command line. | 333 // Make the command line. |
| 326 const base::FilePath& python_path = build_settings->python_path(); | 334 const base::FilePath& python_path = build_settings->python_path(); |
| 327 CommandLine cmdline(python_path); | 335 CommandLine cmdline(python_path); |
| 328 cmdline.AppendArgPath(script_path); | 336 cmdline.AppendArgPath(script_path); |
| 329 | 337 |
| 330 const Value& script_args = args[1]; | 338 if (args.size() >= 2) { |
| 331 if (!script_args.VerifyTypeIs(Value::LIST, err)) | 339 // Optional command-line arguments to the script. |
| 332 return Value(); | 340 const Value& script_args = args[1]; |
| 333 for (size_t i = 0; i < script_args.list_value().size(); i++) { | 341 if (!script_args.VerifyTypeIs(Value::LIST, err)) |
| 334 if (!script_args.list_value()[i].VerifyTypeIs(Value::STRING, err)) | |
| 335 return Value(); | 342 return Value(); |
| 336 cmdline.AppendArg(script_args.list_value()[i].string_value()); | 343 for (size_t i = 0; i < script_args.list_value().size(); i++) { |
| 344 if (!script_args.list_value()[i].VerifyTypeIs(Value::STRING, err)) | |
| 345 return Value(); | |
| 346 cmdline.AppendArg(script_args.list_value()[i].string_value()); | |
| 347 } | |
| 337 } | 348 } |
| 338 | 349 |
| 339 // Log command line for debugging help. | 350 // Log command line for debugging help. |
| 340 trace.SetCommandLine(cmdline); | 351 trace.SetCommandLine(cmdline); |
| 341 base::TimeTicks begin_exec; | 352 base::TimeTicks begin_exec; |
| 342 if (g_scheduler->verbose_logging()) { | 353 if (g_scheduler->verbose_logging()) { |
| 343 #if defined(OS_WIN) | 354 #if defined(OS_WIN) |
| 344 g_scheduler->Log("Pythoning", | 355 g_scheduler->Log("Pythoning", |
| 345 base::UTF16ToUTF8(cmdline.GetCommandLineString())); | 356 base::UTF16ToUTF8(cmdline.GetCommandLineString())); |
| 346 #else | 357 #else |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 "\nReturned " + base::IntToString(exit_code); | 398 "\nReturned " + base::IntToString(exit_code); |
| 388 if (!output.empty()) | 399 if (!output.empty()) |
| 389 msg += " and printed out:\n\n" + output; | 400 msg += " and printed out:\n\n" + output; |
| 390 else | 401 else |
| 391 msg += "."; | 402 msg += "."; |
| 392 *err = Err(function->function(), "Script returned non-zero exit code.", | 403 *err = Err(function->function(), "Script returned non-zero exit code.", |
| 393 msg); | 404 msg); |
| 394 return Value(); | 405 return Value(); |
| 395 } | 406 } |
| 396 | 407 |
| 397 return ConvertInputToValue(output, function, args[2], err); | 408 // Default to None value for the input conversion if unspecified. |
| 409 return ConvertInputToValue(output, function, | |
| 410 args.size() >= 3 ? args[2] : Value(), err); | |
| 398 } | 411 } |
| 399 | 412 |
| 400 } // namespace functions | 413 } // namespace functions |
| OLD | NEW |