Example #1
0
 //-- Protected interface
 /// Constructor to be called by derived classes.
 protected BuildTranslation(BuildGraph buildGraph)
 {
     if (buildGraph == null) {
         throw new ArgumentNullException("buildGraph");
     }
     ModuleName = "";
     BuildNode = new BuildNode(this);
     BuildGraph = buildGraph;
     BuildGraph.Add(this);
 }
Example #2
0
 private void WriteDepsCacheFile(FileStream depsCacheFileStream, BuildNode buildNode)
 {
     string depsCacheString = DependencyCache.CreateDepsCacheString(
         buildNode.Translation,
         m_buildOptions.FileDecider);
     QRFileStream.WriteAllText(depsCacheFileStream, depsCacheString);
 }
Example #3
0
        private bool RequiresBuild(BuildNode buildNode, string previousBuildNodeState)
        {
            //  No need to check if the file exists, because it has been opened-or-created
            //  prior to this function call.

            //  Load a string representation of the previous state of files on disk.
            //  If the deps cache does not exist, then return true to indicate we must build.
            if (String.IsNullOrEmpty(previousBuildNodeState)) {
                return true;
            }

            //  Create a string representation of the current state of files on disk.
            string currentBuildNodeState = DependencyCache.CreateDepsCacheString(
                buildNode.Translation,
                m_buildOptions.FileDecider);
            //  Compare previous and current state.
            bool filesChanged = (previousBuildNodeState != currentBuildNodeState);
            return filesChanged;
        }
Example #4
0
        private bool PropagateDependenciesFromImplicitInputs(BuildNode buildNode)
        {
            bool implicitDependenciesReady = true;

            //  Create BuildFiles for ImplicitInputs and update Dependencies/Consumers.
            foreach (string path in buildNode.Translation.ImplicitInputs) {
                BuildFile buildFile = m_buildGraph.CreateOrGetBuildFile(path);
                if (buildFile.BuildNode != null) {
                    buildNode.Dependencies.Add(buildFile.BuildNode);
                    buildFile.BuildNode.Consumers.Add(buildNode);
                    buildFile.Consumers.Add(buildNode);
                    if (!buildFile.BuildNode.Status.Executed()) {
                        implicitDependenciesReady = false;
                    }
                    if (!m_requiredNodes.Contains(buildFile.BuildNode)) {
                        m_requiredNodes.Add(buildFile.BuildNode);
                        bool generatorReady = AllDependenciesExecuted(buildFile.BuildNode);
                        if (generatorReady) {
                            m_runList.Enqueue(buildFile.BuildNode);
                            m_runSet.Add(buildFile.BuildNode);
                        }
                    }
                }
            }

            return implicitDependenciesReady;
        }
Example #5
0
        private void NotifyBuildNodeCompletion(BuildNode buildNode)
        {
            foreach (BuildNode consumer in buildNode.Consumers) {
                //  Skip consumers that aren't part of this build.
                if (!m_requiredNodes.Contains(consumer)) {
                    continue;
                }

                bool consumerReady = AllDependenciesExecuted(consumer);
                if (consumerReady) {
                    m_runList.Enqueue(consumer);
                    m_runSet.Add(consumer);
                }
                else {
                    continue;
                }
            }
        }
Example #6
0
        /// Executes the Translation associated with buildNode, if all dependencies
        /// are up-to-date.  This includes explicit and implicit IOs.
        private BuildStatus ExecuteOneBuildNode(BuildNode buildNode)
        {
            //  depsCache file opened for exclusive access here.
            using (FileStream depsCacheFileStream = new FileStream(buildNode.Translation.DepsCacheFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) {
                if (!buildNode.Translation.RequiresImplicitInputs) {
                    string prevDepsCacheFileContents = QRFileStream.ReadAllText(depsCacheFileStream);
                    bool requiresBuild = RequiresBuild(buildNode, prevDepsCacheFileContents);
                    if (!requiresBuild) {
                        //  success!  we can early-exit
                        return BuildStatus.TranslationUpToDate;
                    }

                    //  Ensure explicit inputs exist prior to execution.
                    //  This must be done here since Translation.Execute() is not expected to do the checks.
                    bool explicitInputsExist = FilesExist(buildNode.Translation.ExplicitInputs);
                    if (!explicitInputsExist) {
                        //  failed.  some input does not exist
                        return BuildStatus.InputsDoNotExist;
                    }

                    //  fall through to Execute()
                }
                else { // buildNode.Translation.RequiresImplicitInputs
                    if (!buildNode.ImplicitInputsUpToDate) {
                        string prevDepsCacheFileContents = QRFileStream.ReadAllText(depsCacheFileStream);
                        bool requiresBuild = RequiresBuild(buildNode, prevDepsCacheFileContents);
                        if (!requiresBuild) {
                            //  success!  we can early-exit
                            return BuildStatus.TranslationUpToDate;
                        }

                        //  Ensure explicit inputs exist prior to execution.
                        //  This must be done here since Translation.Execute() is not expected to do the checks.
                        bool explicitInputsExist = FilesExist(buildNode.Translation.ExplicitInputs);
                        if (!explicitInputsExist) {
                            //  failed.  some input does not exist
                            return BuildStatus.InputsDoNotExist;
                        }

                        //  Since all explicit inputs exist, we can update the implicit IOs.
                        bool updateImplicitInputsSucceeded = buildNode.Translation.UpdateImplicitInputs();
                        if (!updateImplicitInputsSucceeded) {
                            return BuildStatus.ExecuteFailed;
                        }
                        return BuildStatus.ImplicitInputsComputed;
                    }
                    else { // buildNode.ImplicitInputsUpToDate
                        //  Ensure explicit inputs exist prior to execution.
                        //  This must be done here since Translation.Execute() is not expected to do the checks.
                        bool explicitInputsExist = FilesExist(buildNode.Translation.ExplicitInputs);
                        if (!explicitInputsExist) {
                            //  failed.  some input does not exist
                            return BuildStatus.InputsDoNotExist;
                        }

                        //  Ensure inputs exist prior to execution.
                        //  This must be done here since Translation.Execute() is not expected to do the checks.
                        bool implicitInputsExist = FilesExist(buildNode.Translation.ImplicitInputs);
                        if (!implicitInputsExist) {
                            //  failed.  some input does not exist
                            return BuildStatus.InputsDoNotExist;
                        }

                        //  fall through to Execute()
                    }
                }

                bool executeSucceeded = false;
                try {
                    executeSucceeded = buildNode.Translation.Execute();
                }
                catch (Exception) {
                    //  TODO: log the error
                }
                if (!executeSucceeded) {
                    //  Clear the deps cache, so this failed node must execute on the next build.
                    return BuildStatus.ExecuteFailed;
                }

                //  success.
                WriteDepsCacheFile(depsCacheFileStream, buildNode);
                return BuildStatus.ExecuteSucceeded;
            }
        }
Example #7
0
        private bool AllDependenciesExecuted(BuildNode buildNode)
        {
            foreach (BuildNode dependency in buildNode.Dependencies) {
                if (!m_requiredNodes.Contains(dependency)) {
                    continue;
                }

                if (!dependency.Status.Executed()) {
                    return false;
                }
            }
            return true;
        }