• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include <sstream>
6 
7 #include "base/files/file_util.h"
8 #include "base/strings/string_split.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "gn/err.h"
12 #include "gn/filesystem_utils.h"
13 #include "gn/functions.h"
14 #include "gn/input_file.h"
15 #include "gn/output_conversion.h"
16 #include "gn/parse_tree.h"
17 #include "gn/scheduler.h"
18 #include "util/build_config.h"
19 
20 namespace functions {
21 
22 const char kWriteFile[] = "write_file";
23 const char kWriteFile_HelpShort[] = "write_file: Write a file to disk.";
24 const char kWriteFile_Help[] =
25     R"(write_file: Write a file to disk.
26 
27   write_file(filename, data, output_conversion = "")
28 
29   If data is a list, the list will be written one-item-per-line with no quoting
30   or brackets.
31 
32   If the file exists and the contents are identical to that being written, the
33   file will not be updated. This will prevent unnecessary rebuilds of targets
34   that depend on this file.
35 
36   One use for write_file is to write a list of inputs to an script that might
37   be too long for the command line. However, it is preferable to use response
38   files for this purpose. See "gn help response_file_contents".
39 
40 Arguments
41 
42   filename
43       Filename to write. This must be within the output directory.
44 
45   data
46       The list or string to write.
47 
48   output_conversion
49     Controls how the output is written. See "gn help io_conversion".
50 )";
51 
RunWriteFile(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)52 Value RunWriteFile(Scope* scope,
53                    const FunctionCallNode* function,
54                    const std::vector<Value>& args,
55                    Err* err) {
56   if (args.size() != 3 && args.size() != 2) {
57     *err = Err(function->function(), "Wrong number of arguments to write_file",
58                "I expected two or three arguments.");
59     return Value();
60   }
61 
62   // Compute the file name and make sure it's in the output dir.
63   const SourceDir& cur_dir = scope->GetSourceDir();
64   SourceFile source_file = cur_dir.ResolveRelativeFile(
65       args[0], err, scope->settings()->build_settings()->root_path_utf8());
66   if (err->has_error())
67     return Value();
68   if (!EnsureStringIsInOutputDir(
69           scope->settings()->build_settings()->build_dir(), source_file.value(),
70           args[0].origin(), err))
71     return Value();
72   g_scheduler->AddWrittenFile(source_file);  // Track that we wrote this file.
73 
74   // Track how to recreate this file, since we write it a gen time.
75   // Note this is a hack since the correct output is not a dependency proper,
76   // but an addition of this file to the output of the gn rule that writes it.
77   // This dependency will, however, cause the gen step to be re-run and the
78   // build restarted if the file is missing.
79   g_scheduler->AddGenDependency(
80       scope->settings()->build_settings()->GetFullPath(source_file));
81 
82   // Extract conversion value.
83   Value output_conversion;
84   if (args.size() != 3)
85     output_conversion = Value();
86   else
87     output_conversion = args[2];
88 
89   // Compute output.
90   std::ostringstream contents;
91   ConvertValueToOutput(scope->settings(), args[1], output_conversion, contents,
92                        err);
93   if (err->has_error())
94     return Value();
95 
96   base::FilePath file_path =
97       scope->settings()->build_settings()->GetFullPath(source_file);
98 
99   // Make sure we're not replacing the same contents.
100   if (!WriteFileIfChanged(file_path, contents.str(), err))
101     *err = Err(function->function(), err->message(), err->help_text());
102 
103   return Value();
104 }
105 
106 }  // namespace functions
107