fda3ec4783
Relying on logs/HEAD in case of CI doesn't work.
202 lines
7.4 KiB
QML
202 lines
7.4 KiB
QML
import qbs.File
|
|
import qbs.FileInfo
|
|
import qbs.Process
|
|
import qbs.TextFile
|
|
import qbs.Utilities
|
|
|
|
Module {
|
|
property string type: typeProbe.type
|
|
property string repoDir: project.sourceDirectory
|
|
|
|
// TODO: If minimal qbs version is 1.23 replace with FileInfo.executableSuffix()
|
|
readonly property string executableSuffix: project.qbs.targetOS.contains("windows") ? ".exe" : ""
|
|
property string toolFilePath: {
|
|
if (type === "git")
|
|
return "git" + executableSuffix;
|
|
if (type === "svn")
|
|
return "svn" + executableSuffix;
|
|
}
|
|
|
|
property string headerFileName: "vcs-repo-state.h"
|
|
readonly property string repoState: gitProbe.repoState || subversionProbe.repoState
|
|
readonly property string repoStateTag: gitProbe.repoStateTag || subversionProbe.repoStateTag
|
|
readonly property string repoStateDistance: gitProbe.repoStateDistance || subversionProbe.repoStateDistance
|
|
readonly property string repoStateRevision: gitProbe.repoStateRevision || subversionProbe.repoStateRevision
|
|
|
|
// Internal
|
|
readonly property string includeDir: FileInfo.joinPaths(product.buildDirectory, "vcs-include")
|
|
readonly property string metaDataBaseDir: typeProbe.metaDataBaseDir
|
|
|
|
PropertyOptions {
|
|
name: "type"
|
|
allowedValues: ["git", "svn"]
|
|
description: "the version control system your project is using"
|
|
}
|
|
|
|
Depends { name: "cpp"; condition: headerFileName }
|
|
Properties {
|
|
condition: headerFileName
|
|
cpp.includePaths: [includeDir]
|
|
}
|
|
|
|
Probe {
|
|
id: typeProbe
|
|
|
|
property string tool: toolFilePath
|
|
property string theRepoDir: repoDir
|
|
|
|
property string type
|
|
property string metaDataBaseDir
|
|
|
|
configure: {
|
|
var detector = new Process();
|
|
try {
|
|
detector.setWorkingDirectory(theRepoDir);
|
|
if (detector.exec(tool || "git", ["rev-parse", "--git-dir"]) === 0) {
|
|
found = true;
|
|
type = "git";
|
|
metaDataBaseDir = detector.readStdOut().trim();
|
|
if (!FileInfo.isAbsolutePath(metaDataBaseDir))
|
|
metaDataBaseDir = FileInfo.joinPaths(theRepoDir, metaDataBaseDir);
|
|
return;
|
|
}
|
|
if (detector.exec(tool || "svn",
|
|
["info", "--show-item", "wc-root", "--no-newline"]) === 0) {
|
|
found = true
|
|
type = "svn";
|
|
metaDataBaseDir = FileInfo.joinPaths(detector.readStdOut(), ".svn");
|
|
return;
|
|
} else if (detector.exec(tool || "svn", ["info"]) === 0) {
|
|
if (detector.exec(tool || "svn", ["--version", "--quiet"]) === 0
|
|
&& Utilities.versionCompare(detector.readStdOut().trim(), "1.9") < 0) {
|
|
throw "svn too old, version >= 1.9 required";
|
|
}
|
|
}
|
|
} finally {
|
|
detector.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
Probe {
|
|
id: gitProbe
|
|
condition: type === "git"
|
|
|
|
property string tool: toolFilePath
|
|
property string theRepoDir: repoDir
|
|
|
|
property string repoState
|
|
property string repoStateTag
|
|
property string repoStateDistance
|
|
property string repoStateRevision
|
|
|
|
configure: {
|
|
var commitsProbe = new Process();
|
|
try {
|
|
commitsProbe.setWorkingDirectory(theRepoDir);
|
|
var exitCode = commitsProbe.exec(tool, ["rev-list", "HEAD", "--count"], false);
|
|
if (exitCode !== 0) {
|
|
console.info("Cannot read repo state.");
|
|
return;
|
|
}
|
|
|
|
var count = parseInt(commitsProbe.readStdOut().trim());
|
|
if (count < 1) {
|
|
console.info("The repo has no commits yet.");
|
|
return;
|
|
}
|
|
} finally {
|
|
commitsProbe.close();
|
|
}
|
|
|
|
var proc = new Process();
|
|
try {
|
|
proc.setWorkingDirectory(theRepoDir);
|
|
// tag is formatted as TAG-N-gSHA:
|
|
// 1. latest stable version is TAG, or vX.Y.Z
|
|
// 2. number of commits since latest stable version is N
|
|
// 3. latest commit is gSHA
|
|
proc.exec(tool, ["describe", "--always", "HEAD"], true);
|
|
repoState = proc.readStdOut().trim();
|
|
if (repoState) {
|
|
found = true;
|
|
|
|
const tagSections = repoState.split("-");
|
|
|
|
if (tagSections.length >= 3) {
|
|
repoStateTag = tagSections[0];
|
|
repoStateDistance = tagSections[1];
|
|
repoStateRevision = tagSections[2];
|
|
} else {
|
|
repoStateRevision = tagSections[0];
|
|
}
|
|
}
|
|
} finally {
|
|
proc.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
Probe {
|
|
id: subversionProbe
|
|
condition: type === "svn"
|
|
|
|
property string tool: toolFilePath
|
|
property string theRepoDir: repoDir
|
|
property string filePath: FileInfo.joinPaths(metaDataBaseDir, "wc.db")
|
|
property var timestamp: File.lastModified(filePath)
|
|
|
|
property string repoState
|
|
property string repoStateTag
|
|
property string repoStateDistance
|
|
property string repoStateRevision
|
|
|
|
configure: {
|
|
var proc = new Process();
|
|
try {
|
|
proc.setWorkingDirectory(theRepoDir);
|
|
proc.exec(tool, ["info", "-r", "HEAD", "--show-item", "revision", "--no-newline"],
|
|
true);
|
|
repoState = proc.readStdOut().trim();
|
|
if (repoState)
|
|
found = true;
|
|
} finally {
|
|
proc.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
Rule {
|
|
condition: headerFileName
|
|
multiplex: true
|
|
Artifact {
|
|
filePath: FileInfo.joinPaths(product.vcs2.includeDir, product.vcs2.headerFileName)
|
|
fileTags: ["hpp"]
|
|
}
|
|
prepare: {
|
|
var cmd = new JavaScriptCommand();
|
|
cmd.description = "generating " + output.fileName;
|
|
cmd.highlight = "codegen";
|
|
cmd.repoState = product.vcs2.repoState;
|
|
cmd.repoStateTag = product.vcs2.repoStateTag;
|
|
cmd.repoStateDistance = product.vcs2.repoStateDistance;
|
|
cmd.repoStateRevision = product.vcs2.repoStateRevision;
|
|
cmd.sourceCode = function() {
|
|
var f = new TextFile(output.filePath, TextFile.WriteOnly);
|
|
try {
|
|
f.writeLine("#ifndef VCS_REPO_STATE_H");
|
|
f.writeLine("#define VCS_REPO_STATE_H");
|
|
f.writeLine('#define VCS_REPO_STATE "' + (repoState ? repoState : "none") + '"')
|
|
f.writeLine('#define VCS_REPO_STATE_TAG "' + (repoStateTag ? repoStateTag : "none") + '"')
|
|
f.writeLine('#define VCS_REPO_STATE_DISTANCE "' + (repoStateDistance ? repoStateDistance : "none") + '"')
|
|
f.writeLine('#define VCS_REPO_STATE_REVISION "' + (repoStateRevision ? repoStateRevision : "none") + '"')
|
|
f.writeLine("#endif");
|
|
} finally {
|
|
f.close();
|
|
}
|
|
};
|
|
return [cmd];
|
|
}
|
|
}
|
|
}
|