diff --git a/build-files.txt b/build-files.txt index c297f27..ffc06e0 100644 --- a/build-files.txt +++ b/build-files.txt @@ -2,6 +2,7 @@ source/dub/commandline.d source/dub/dependency.d source/dub/dependencyresolver.d +source/dub/description.d source/dub/dub.d source/dub/init.d source/dub/packagemanager.d diff --git a/source/dub/commandline.d b/source/dub/commandline.d index e8c5623..4a2605c 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -13,6 +13,7 @@ import dub.generators.generator; import dub.internal.vibecompat.core.file; import dub.internal.vibecompat.core.log; +import dub.internal.vibecompat.data.json; import dub.internal.vibecompat.inet.url; import dub.package_; import dub.packagemanager; @@ -810,7 +811,8 @@ } else if (m_stringImportPaths) { dub.listStringImportPaths(m_buildPlatform, config); } else { - dub.describeProject(m_buildPlatform, config); + auto desc = dub.project.describe(m_buildPlatform, config); + writeln(desc.serializeToPrettyJson()); } return 0; diff --git a/source/dub/dependency.d b/source/dub/dependency.d index a1cbc7c..7b88b57 100644 --- a/source/dub/dependency.d +++ b/source/dub/dependency.d @@ -500,6 +500,8 @@ m_version = vers; } + static Version fromString(string vers) { return Version(vers); } + bool opEquals(const Version oth) const { if (isUnknown || oth.isUnknown) { throw new Exception("Can't compare unknown versions! (this: %s, other: %s)".format(this, oth)); diff --git a/source/dub/description.d b/source/dub/description.d new file mode 100644 index 0000000..7c7e22c --- /dev/null +++ b/source/dub/description.d @@ -0,0 +1,88 @@ +/** + Types for project descriptions (dub describe). + + Copyright: © 2015 rejectedsoftware e.K. + License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. + Authors: Sönke Ludwig +*/ +module dub.description; + +import dub.compilers.buildsettings; +import dub.dependency; +import dub.internal.vibecompat.data.serialization; + + +/** + Describes a complete project for use in IDEs or build tools. + + The build settings will be specific to the compiler, platform + and configuration that has been selected. +*/ +struct ProjectDescription { + string rootPackage; + alias mainPackage = rootPackage; /// Compatibility alias + string configuration; + string compiler; + string[] architecture; + string[] platform; + PackageDescription[] packages; +} + + +/** + Build settings and meta data of a single package. +*/ +struct PackageDescription { + string path; + string name; + Version version_; + string description; + string homepage; + string[] authors; + string copyright; + string license; + string[] dependencies; + + @byName TargetType targetType; + string targetPath; + string targetName; + string targetFileName; + string workingDirectory; + string mainSourceFile; + string[] dflags; + string[] lflags; + string[] libs; + string[] copyFiles; + string[] versions; + string[] debugVersions; + string[] importPaths; + string[] stringImportPaths; + string[] preGenerateCommands; + string[] postGenerateCommands; + string[] preBuildCommands; + string[] postBuildCommands; + @byName BuildRequirements[] buildRequirements; + @byName BuildOptions[] options; + SourceFileDescription[] files; +} + +/** + Description for a single source file. +*/ +struct SourceFileDescription { + @byName SourceFileRole role; + alias type = role; /// Compatibility alias + string path; +} + +/** + Determines +*/ +enum SourceFileRole { + unusedStringImport, + unusedImport, + unusedSource, + stringImport, + import_, + source +} diff --git a/source/dub/dub.d b/source/dub/dub.d index fba29ee..b0f211a 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -414,18 +414,11 @@ } /// Outputs a JSON description of the project, including its dependencies. - void describeProject(BuildPlatform platform, string config) + deprecated void describeProject(BuildPlatform platform, string config) { - auto dst = Json.emptyObject; - dst.configuration = config; - dst.compiler = platform.compiler; - dst.architecture = platform.architecture.serializeToJson(); - dst.platform = platform.platform.serializeToJson(); - - m_project.describe(dst, platform, config); - import std.stdio; - write(dst.toPrettyString()); + auto desc = m_project.describe(platform, config); + writeln(desc.serializeToPrettyJson()); } void listImportPaths(BuildPlatform platform, string config) diff --git a/source/dub/package_.d b/source/dub/package_.d index ee1b6a0..c6eaa05 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -11,6 +11,7 @@ import dub.compilers.compiler; import dub.dependency; +import dub.description; import dub.recipe.json; import dub.recipe.sdl; @@ -360,61 +361,78 @@ return false; } - void describe(ref Json dst, BuildPlatform platform, string config) + /** Returns a description of the package for use in IDEs or build tools. + */ + PackageDescription describe(BuildPlatform platform, string config) { - dst.path = m_path.toNativeString(); - dst.name = this.name; - dst["version"] = this.vers; - dst.description = m_info.description; - dst.homepage = m_info.homepage; - dst.authors = m_info.authors.serializeToJson(); - dst.copyright = m_info.copyright; - dst.license = m_info.license; - dst.dependencies = m_info.dependencies.keys.serializeToJson(); + PackageDescription ret; + ret.path = m_path.toNativeString(); + ret.name = this.name; + ret.version_ = this.ver; + ret.description = m_info.description; + ret.homepage = m_info.homepage; + ret.authors = m_info.authors; + ret.copyright = m_info.copyright; + ret.license = m_info.license; + ret.dependencies = getDependencies(config).keys; // save build settings BuildSettings bs = getBuildSettings(platform, config); BuildSettings allbs = getCombinedBuildSettings(); - foreach (string k, v; bs.serializeToJson()) dst[k] = v; - dst.remove("requirements"); - dst.remove("sourceFiles"); - dst.remove("importFiles"); - dst.remove("stringImportFiles"); - dst.targetType = bs.targetType.to!string(); - if (dst.targetType != TargetType.none) - dst.targetFileName = getTargetFileName(bs, platform); + ret.targetType = bs.targetType; + ret.targetPath = bs.targetPath; + ret.targetName = bs.targetName; + if (ret.targetType != TargetType.none) + ret.targetFileName = getTargetFileName(bs, platform); + ret.workingDirectory = bs.workingDirectory; + ret.mainSourceFile = bs.mainSourceFile; + ret.dflags = bs.dflags; + ret.lflags = bs.lflags; + ret.libs = bs.libs; + ret.copyFiles = bs.copyFiles; + ret.versions = bs.versions; + ret.debugVersions = bs.debugVersions; + ret.importPaths = bs.importPaths; + ret.stringImportPaths = bs.stringImportPaths; + ret.preGenerateCommands = bs.preGenerateCommands; + ret.postGenerateCommands = bs.postGenerateCommands; + ret.preBuildCommands = bs.preBuildCommands; + ret.postBuildCommands = bs.postBuildCommands; // prettify build requirements output - Json[] breqs; for (int i = 1; i <= BuildRequirements.max; i <<= 1) if (bs.requirements & i) - breqs ~= Json(to!string(cast(BuildRequirements)i)); - dst.buildRequirements = breqs; + ret.buildRequirements ~= cast(BuildRequirements)i; // prettify options output - Json[] bopts; for (int i = 1; i <= BuildOptions.max; i <<= 1) if (bs.options & i) - bopts ~= Json(to!string(cast(BuildOptions)i)); - dst.options = bopts; + ret.options ~= cast(BuildOptions)i; // collect all possible source files and determine their types - string[string] sourceFileTypes; - foreach (f; allbs.stringImportFiles) sourceFileTypes[f] = "unusedStringImport"; - foreach (f; allbs.importFiles) sourceFileTypes[f] = "unusedImport"; - foreach (f; allbs.sourceFiles) sourceFileTypes[f] = "unusedSource"; - foreach (f; bs.stringImportFiles) sourceFileTypes[f] = "stringImport"; - foreach (f; bs.importFiles) sourceFileTypes[f] = "import"; - foreach (f; bs.sourceFiles) sourceFileTypes[f] = "source"; - Json[] files; + SourceFileRole[string] sourceFileTypes; + foreach (f; allbs.stringImportFiles) sourceFileTypes[f] = SourceFileRole.unusedStringImport; + foreach (f; allbs.importFiles) sourceFileTypes[f] = SourceFileRole.unusedImport; + foreach (f; allbs.sourceFiles) sourceFileTypes[f] = SourceFileRole.unusedSource; + foreach (f; bs.stringImportFiles) sourceFileTypes[f] = SourceFileRole.stringImport; + foreach (f; bs.importFiles) sourceFileTypes[f] = SourceFileRole.import_; + foreach (f; bs.sourceFiles) sourceFileTypes[f] = SourceFileRole.source; foreach (f; sourceFileTypes.byKey.array.sort()) { - auto jf = Json.emptyObject; - jf["path"] = f; - jf["type"] = sourceFileTypes[f]; - files ~= jf; + SourceFileDescription sf; + sf.path = f; + sf.type = sourceFileTypes[f]; + ret.files ~= sf; } - dst.files = Json(files); + + return ret; + } + // ditto + deprecated void describe(ref Json dst, BuildPlatform platform, string config) + { + auto res = describe(platform, config); + foreach (string key, value; res.serializeToJson()) + dst[key] = value; } private void fillWithDefaults() @@ -571,7 +589,6 @@ } } - private string determineVersionFromSCM(Path path) { import std.process; diff --git a/source/dub/project.d b/source/dub/project.d index 30e98b0..c4b104c 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -9,6 +9,7 @@ import dub.compilers.compiler; import dub.dependency; +import dub.description; import dub.internal.utils; import dub.internal.vibecompat.core.file; import dub.internal.vibecompat.core.log; @@ -571,25 +572,33 @@ return all_found; }*/ - /// Outputs a JSON description of the project, including its deoendencies. - void describe(ref Json dst, BuildPlatform platform, string config) + /// Outputs a build description of the project, including its dependencies. + ProjectDescription describe(BuildPlatform platform, string config) { - dst.mainPackage = m_rootPackage.name; // deprecated - dst.rootPackage = m_rootPackage.name; + ProjectDescription ret; + ret.rootPackage = m_rootPackage.name; + ret.configuration = config; + ret.compiler = platform.compiler; + ret.architecture = platform.architecture; + ret.platform = platform.platform; auto configs = getPackageConfigs(platform, config); // FIXME: use the generator system to collect the list of actually used build dependencies and source files - auto mp = Json.emptyObject; - m_rootPackage.describe(mp, platform, config); - dst.packages = Json([mp]); + ret.packages ~= m_rootPackage.describe(platform, config); - foreach (dep; m_dependencies) { - auto dp = Json.emptyObject; - dep.describe(dp, platform, configs[dep.name]); - dst.packages = dst.packages.get!(Json[]) ~ dp; - } + foreach (dep; m_dependencies) + ret.packages ~= dep.describe(platform, configs[dep.name]); + + return ret; + } + /// ditto + deprecated void describe(ref Json dst, BuildPlatform platform, string config) + { + auto desc = describe(platform, config); + foreach (string key, value; desc.serializeToJson()) + dst[key] = value; } private string[] listPaths(string attributeName)(BuildPlatform platform, string config)