diff --git a/lib/decking.js b/lib/decking.js index 22fce74..7f2639f 100644 --- a/lib/decking.js +++ b/lib/decking.js @@ -169,44 +169,72 @@ Decking.prototype._build = function(image, done) { } var targetPath = target + "/Dockerfile"; - this.logger.log("Building image " + image + " from " + targetPath); // @TODO for now, always assume we want to build from a Dockerfile // @TODO need a lot of careful validation here - var readStream = fs.createReadStream(targetPath); - var writeStream = fs.createWriteStream("./Dockerfile"); var self = this; + var buildDep = false; - // ensure we don't try and create the tarball until the local Dockerfile exists - writeStream.on("close", function() { - var options = {t: image}; - if(self.hasArg("--no-cache")) { - self.logger.log("Not using image cache"); - options.nocache = true; + if(self.hasArg("--no-dependencies")) { + self.logger.log("Not building dependencies"); + } else { + // Detecting local dependency + var dockerfileContent = fs.readFileSync(targetPath); + var fromRe = /^\s*from\s*(\S*)/i; + var fromMatch = fromRe.exec(dockerfileContent); + if (fromMatch) { + var dependency = fromMatch[1]; + if (this.config.images[dependency]) { + // the dependency is declared in the local images, let's build that one first + buildDep = true; + self.logger.log("Found dependency : " + dependency); + self._build(dependency, function(err) { + if (err) return done(err); + continueFn(); + }); + } } + } - self.logger.log("Uploading compressed context..."); + if (!buildDep) continueFn(); - // @TODO allow user to specifiy --exclude params to avoid unnecessarily huge tarballs - var tar = child_process.spawn("tar", ["-c", "-", "./"]); + function continueFn() { + self.logger.log("Building image " + image + " from " + targetPath); - return self.docker.buildImage(tar.stdout, options, function(err, res) { - fs.unlink("./Dockerfile", function(err) { - if(err) return self.logger.log("[WARN] Could not remove Dockerfile"); - }); - if(err) return done(err); - if(res.headers["content-type"] === "application/json") { - res.pipe(JSONStream.parse("stream")).pipe(process.stdout); - } else { - // we don't need an if/else but let's keep it for clarity; it'd be too easy to - // skim-read the code and misinterpret the first pipe otherwise - res.pipe(process.stdout); + var readStream = fs.createReadStream(targetPath); + var writeStream = fs.createWriteStream("./Dockerfile"); + + // ensure we don't try and create the tarball until the local Dockerfile exists + writeStream.on("close", function() { + var options = {t: image}; + if(self.hasArg("--no-cache")) { + self.logger.log("Not using image cache"); + options.nocache = true; } - return res.on("end", done); + + self.logger.log("Uploading compressed context..."); + + // @TODO allow user to specifiy --exclude params to avoid unnecessarily huge tarballs + var tar = child_process.spawn("tar", ["-c", "-", "./"]); + + return self.docker.buildImage(tar.stdout, options, function(err, res) { + fs.unlink("./Dockerfile", function(err) { + if(err) return self.logger.log("[WARN] Could not remove Dockerfile"); + }); + if(err) return done(err); + if(res.headers["content-type"] === "application/json") { + res.pipe(JSONStream.parse("stream")).pipe(process.stdout); + } else { + // we don't need an if/else but let's keep it for clarity; it'd be too easy to + // skim-read the code and misinterpret the first pipe otherwise + res.pipe(process.stdout); + } + return res.on("end", done); + }); }); - }); - readStream.pipe(writeStream); + readStream.pipe(writeStream); + } }; // ----------