]> git.tdb.fi Git - builder.git/blob - source/datatransform.cpp
Fix DataCollection dependencies
[builder.git] / source / datatransform.cpp
1 #include <msp/fs/dir.h>
2 #include <msp/fs/utils.h>
3 #include <msp/strings/format.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
21 void DataTransform::find_dependencies()
22 {
23         list<string> files;
24         Cache &cache = component->get_package().get_cache();
25         // XXX Should check directory mtime as well
26         if(mtime<cache.get_mtime() && cache.has_key(this, "files"))
27                 files = cache.get_values(this, "files");
28         else
29         {
30                 builder.get_logger().log("files", format("Reading imports from %s", path.str()));
31                 IO::File in(path.str());
32                 DataFile::Parser parser(in, path.str());
33
34                 list<string> dir_files;
35                 while(!in.eof())
36                 {
37                         DataFile::Statement st = parser.parse();
38                         if(st.keyword=="for_each")
39                         {
40                                 // There's bound to be at least one file: the transform itself
41                                 if(dir_files.empty())
42                                 {
43                                         FS::Path dir = FS::dirname(path);
44                                         builder.get_logger().log("files", format("Traversing %s", dir.str()));
45                                         dir_files = list_files(dir);
46                                 }
47
48                                 for(DataFile::Statement::Arguments::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
49                                 {
50                                         Regex re(i->get<string>());
51                                         for(list<string>::const_iterator j=dir_files.begin(); j!=dir_files.end(); ++j)
52                                                 if(re.match(*j))
53                                                         files.push_back(*j);
54                                 }
55                         }
56                         else if(st.keyword=="file" && st.args.size()==1)
57                                 files.push_back(st.args.front().get<string>());
58                 }
59
60                 cache.set_values(this, "files", files);
61         }
62
63         for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
64         {
65                 FS::Path file_path = FS::dirname(path)/ *i;
66                 if(Target *tgt = builder.get_vfs().get_target(file_path))
67                         add_transitive_dependency(*tgt);
68                 else
69                         add_transitive_dependency(*new File(builder, *package, file_path));
70         }
71 }