]> git.tdb.fi Git - builder.git/blob - source/datatransform.cpp
Refactor logger to do message formatting internally
[builder.git] / source / datatransform.cpp
1 #include <msp/fs/dir.h>
2 #include <msp/fs/stat.h>
3 #include <msp/fs/utils.h>
4 #include <msp/strings/regex.h>
5 #include "builder.h"
6 #include "cache.h"
7 #include "component.h"
8 #include "datatransform.h"
9 #include "file.h"
10 #include "sourcepackage.h"
11
12 using namespace std;
13 using namespace Msp;
14
15 DataTransform::DataTransform(Builder &b, const Component &c, const FS::Path &p):
16         FileTarget(b, c.get_package(), p)
17 {
18         component = &c;
19
20         if(FS::Stat st = FS::lstat(FS::dirname(path)))
21                 dir_mtime = st.get_modify_time();
22 }
23
24 void DataTransform::find_dependencies()
25 {
26         vector<string> files;
27         Cache &cache = component->get_package().get_cache();
28         const Time::TimeStamp &cache_mtime = cache.get_mtime();
29         if(mtime<cache_mtime && dir_mtime<cache_mtime && cache.has_key(this, "files"))
30                 files = cache.get_values(this, "files");
31         else
32         {
33                 builder.get_logger().log("files", "Reading imports from %s", path.str());
34                 IO::File in(path.str());
35                 DataFile::Parser parser(in, path.str());
36
37                 vector<string> dir_files;
38                 while(!in.eof())
39                 {
40                         DataFile::Statement st = parser.parse();
41                         if(st.keyword=="for_each")
42                         {
43                                 // There's bound to be at least one file: the transform itself
44                                 if(dir_files.empty())
45                                 {
46                                         FS::Path dir = FS::dirname(path);
47                                         builder.get_logger().log("files", "Traversing %s", dir.str());
48                                         dir_files = list_files(dir);
49                                 }
50
51                                 for(const DataFile::Value &a: st.args)
52                                 {
53                                         Regex re(a.get<string>());
54                                         for(const string &f: dir_files)
55                                                 if(re.match(f))
56                                                         files.push_back(f);
57                                 }
58                         }
59                         else if(st.keyword=="file" && st.args.size()==1)
60                                 files.push_back(st.args.front().get<string>());
61                 }
62
63                 cache.set_values(this, "files", files);
64         }
65
66         for(const string &f: files)
67         {
68                 FS::Path file_path = FS::dirname(path)/f;
69                 if(Target *tgt = builder.get_vfs().get_target(file_path))
70                         add_transitive_dependency(*tgt);
71                 else
72                         add_transitive_dependency(*new File(builder, *package, file_path));
73         }
74 }