diff --git a/build-files.txt b/build-files.txt index b0b37fc..6b4f028 100644 --- a/build-files.txt +++ b/build-files.txt @@ -1,4 +1,5 @@ source/app.d +source/dub/commandline.d source/dub/dependency.d source/dub/dub.d source/dub/init.d diff --git a/source/app.d b/source/app.d index 370c020..af2b866 100644 --- a/source/app.d +++ b/source/app.d @@ -1,447 +1,17 @@ /** - The entry point to dub + Application entry point. - Copyright: © 2012-2013 Matthias Dondorff + Copyright: © 2013 rejectedsoftware e.K. License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. - Authors: Matthias Dondorff, Sönke Ludwig + Authors: Sönke Ludwig */ module app; -import dub.compilers.compiler; -import dub.dependency; -import dub.dub; -import dub.generators.generator; -import dub.internal.vibecompat.core.file; -import dub.internal.vibecompat.core.log; -import dub.internal.vibecompat.inet.url; -import dub.package_; -import dub.packagesupplier; -import dub.project; -import dub.version_; - -import std.algorithm; -import std.array; -import std.conv; -import std.encoding; -import std.exception; -import std.file; -import std.getopt; -import std.process; - +import dub.commandline; int main(string[] args) { - logDiagnostic("DUB version %s", dubVersion); - - string cmd; - - version(Windows){ - // rdmd uses $TEMP to compute a temporary path. since cygwin substitutes backslashes - // with slashes, this causes OPTLINK to fail (it thinks path segments are options) - // we substitute the other way around here to fix this. - environment["TEMP"] = environment["TEMP"].replace("/", "\\"); - } - - try { - // split application arguments from DUB arguments - string[] app_args; - auto app_args_idx = args.countUntil("--"); - if (app_args_idx >= 0) { - app_args = args[app_args_idx+1 .. $]; - args = args[0 .. app_args_idx]; - } - - // parse general options - bool verbose, vverbose, quiet, vquiet; - bool help, nodeps, annotate; - LogLevel loglevel = LogLevel.info; - string build_type, build_config; - string compiler_name = "dmd"; - string arch; - bool rdmd = false; - bool print_platform, print_builds, print_configs; - bool place_system_wide = false, place_locally = false; - string retrieved_version; - string[] registry_urls; - string[] debug_versions; - string root_path = getcwd(); - getopt(args, - "v|verbose", &verbose, - "vverbose", &vverbose, - "q|quiet", &quiet, - "vquiet", &vquiet, - "h|help", &help, // obsolete - "nodeps", &nodeps, - "annotate", &annotate, - "build", &build_type, - "compiler", &compiler_name, - "arch", &arch, - "rdmd", &rdmd, - "config", &build_config, - "debug", &debug_versions, - "print-builds", &print_builds, - "print-configs", &print_configs, - "print-platform", &print_platform, - "system", &place_system_wide, - "local", &place_locally, - "version", &retrieved_version, - "registry", ®istry_urls, - "root", &root_path - ); - - if( vverbose ) loglevel = LogLevel.debug_; - else if( verbose ) loglevel = LogLevel.diagnostic; - else if( vquiet ) loglevel = LogLevel.none; - else if( quiet ) loglevel = LogLevel.warn; - setLogLevel(loglevel); - - // extract the command - if( args.length > 1 && !args[1].startsWith("-") ){ - cmd = args[1]; - args = args[0] ~ args[2 .. $]; - } else cmd = "run"; - - // display help if requested (obsolete) - if( help ){ - showHelp(cmd); - return 0; - } - - BuildSettings build_settings; - auto compiler = getCompiler(compiler_name); - auto build_platform = compiler.determinePlatform(build_settings, compiler_name, arch); - build_settings.addDebugVersions(debug_versions); - - if( print_platform ){ - logInfo("Build platform:"); - logInfo(" Compiler: %s", build_platform.compiler); - logInfo(" System: %s", build_platform.platform.join(" ")); - logInfo(" Architecture: %s", build_platform.architecture.join(" ")); - logInfo(""); - } - - auto package_suppliers = registry_urls.map!(url => cast(PackageSupplier)new RegistryPackageSupplier(Url(url))).array; - Dub dub = new Dub(package_suppliers, root_path); - string def_config; - - // make the CWD package available so that for example sub packages can reference their - // parent package. - try dub.packageManager.getTemporaryPackage(Path(root_path), Version("~master")); - catch (Exception e) { logDiagnostic("No package found in current working directory."); } - - bool loadCwdPackage(Package pack) - { - if (!existsFile(dub.rootPath~"package.json") && !existsFile(dub.rootPath~"source/app.d")) { - logInfo(""); - logInfo("Neither package.json, nor source/app.d was found in the current directory."); - logInfo("Please run dub from the root directory of an existing package, or create a new"); - logInfo("package using \"dub init \"."); - logInfo(""); - showHelp(null); - return false; - } - - if (pack) dub.loadPackage(pack); - else dub.loadPackageFromCwd(); - - def_config = dub.getDefaultConfiguration(build_platform); - - return true; - } - - string package_name; - bool loadSelectedPackage() - { - Package pack; - if (!package_name.empty) { - // load package in root_path to enable searching for sub packages - loadCwdPackage(null); - pack = dub.packageManager.getFirstPackage(package_name); - enforce(pack, "Failed to find a package named '"~package_name~"'."); - logInfo("Building package %s in %s", pack.name, pack.path.toNativeString()); - dub.rootPath = pack.path; - } - if (!loadCwdPackage(pack)) return false; - if (!build_config.length) build_config = def_config; - return true; - } - - static void warnRenamed(string prev, string curr) - { - logWarn("Command '%s' was renamed to '%s'. Old name is deprecated, please update your scripts", prev, curr); - } - - // handle the command - switch( cmd ){ - default: - enforce(false, "Command is unknown: " ~ cmd); - assert(false); - case "help": - if(args.length >= 2) cmd = args[1]; - showHelp(cmd); - return 0; - case "init": - string dir; - string type = "minimal"; - if (args.length >= 2) dir = args[1]; - if (args.length >= 3) type = args[2]; - dub.createEmptyPackage(Path(dir), type); - return 0; - case "upgrade": - dub.loadPackageFromCwd(); - logInfo("Upgrading project in %s", dub.projectPath.toNativeString()); - dub.update(UpdateOptions.Upgrade | (annotate ? UpdateOptions.JustAnnotate : UpdateOptions.None)); - return 0; - case "install": - warnRenamed(cmd, "fetch"); - goto case "fetch"; - case "fetch": - enforce(args.length >= 2, "Missing package name."); - auto location = PlacementLocation.userWide; - auto name = args[1]; - enforce(!place_locally || !place_system_wide, "Cannot place package locally and system wide at the same time."); - if (place_locally) location = PlacementLocation.local; - else if (place_system_wide) location = PlacementLocation.systemWide; - if (retrieved_version.length) dub.fetch(name, Dependency(retrieved_version), location, true); - else { - try { - dub.fetch(name, Dependency(">=0.0.0"), location, true); - logInfo( - "Please note that you need to use `dub run ` " ~ - "or add it to dependencies of your package to actually use/run it. " ~ - "dub does not do actual installation of packages outside of its own ecosystem."); - } - catch(Exception e){ - logInfo("Getting a release version failed: %s", e.msg); - logInfo("Retry with ~master..."); - dub.fetch(name, Dependency("~master"), location, true); - } - } - break; - case "uninstall": - warnRenamed(cmd, "remove"); - goto case "remove"; - case "remove": - enforce(args.length >= 2, "Missing package name."); - auto location = PlacementLocation.userWide; - auto package_id = args[1]; - enforce(!place_locally || !place_system_wide, "Cannot place package locally and system wide at the same time."); - if ( place_locally ) location = PlacementLocation.local; - else if( place_system_wide ) location = PlacementLocation.systemWide; - try dub.remove(package_id, retrieved_version, location); - catch logError("Please specify a individual version or use the wildcard identifier '%s' (without quotes).", Dub.RemoveVersionWildcard); - break; - case "add-local": - enforce(args.length >= 3, "Missing arguments."); - dub.addLocalPackage(args[1], args[2], place_system_wide); - break; - case "remove-local": - enforce(args.length >= 2, "Missing path to package."); - dub.removeLocalPackage(args[1], place_system_wide); - break; - case "add-path": - enforce(args.length >= 2, "Missing search path."); - dub.addSearchPath(args[1], place_system_wide); - break; - case "remove-path": - enforce(args.length >= 2, "Missing search path."); - dub.removeSearchPath(args[1], place_system_wide); - break; - case "list-installed": - warnRenamed(cmd, "list"); - goto case "list"; - case "list": - logInfo("Packages present in the system and known to dub:"); - foreach (p; dub.packageManager.getPackageIterator()) - logInfo(" %s %s: %s", p.name, p.ver, p.path.toNativeString()); - logInfo(""); - break; - case "run": - case "build": - case "generate": - string generator; - if( cmd == "run" || cmd == "build" ) { - generator = rdmd ? "rdmd" : "build"; - if (args.length >= 2) package_name = args[1]; - } else { - if (args.length >= 2) generator = args[1]; - if (args.length >= 3) package_name = args[2]; - if(generator.empty) { - logInfo("Usage: dub generate []"); - return 1; - } - } - - if (!loadSelectedPackage()) return 1; - - if( print_builds ){ - logInfo("Available build types:"); - foreach( tp; ["debug", "release", "unittest", "profile"] ) - logInfo(" %s", tp); - logInfo(""); - } - - if( print_configs ){ - logInfo("Available configurations:"); - foreach( tp; dub.configurations ) - logInfo(" %s%s", tp, tp == def_config ? " [default]" : null); - logInfo(""); - } - - if( !nodeps ){ - logInfo("Checking dependencies in '%s'", dub.projectPath.toNativeString()); - dub.update(annotate ? UpdateOptions.JustAnnotate : UpdateOptions.None); - } - - enforce(build_config.length == 0 || dub.configurations.canFind(build_config), "Unknown build configuration: "~build_config); - - if (build_type.length == 0) { - if (environment.get("DFLAGS")) build_type = "$DFLAGS"; - else build_type = "debug"; - } - - GeneratorSettings gensettings; - gensettings.platform = build_platform; - gensettings.config = build_config; - gensettings.buildType = build_type; - gensettings.compiler = compiler; - gensettings.buildSettings = build_settings; - gensettings.run = cmd == "run"; - gensettings.runArgs = app_args; - - logDiagnostic("Generating using %s", generator); - dub.generateProject(generator, gensettings); - if (build_type == "ddox") dub.runDdox(gensettings.run); - break; - case "describe": - if (args.length >= 2) package_name = args[1]; - if (!loadSelectedPackage()) return 1; - dub.describeProject(build_platform, build_config); - break; - } - - return 0; - } - catch(Throwable e) - { - logError("Error: %s\n", e.msg); - logDiagnostic("Full exception: %s", sanitize(e.toString())); - logInfo("Run 'dub help' for usage information."); - return 1; - } + version (unittest) return 0; + else return runDubCommandLine(args); } -private void showHelp(string command) -{ - if(command == "remove" || command == "fetch") { - logInfo( -`Usage: dub [] - -Note: use dependencies (package.json) if you want to add a dependency, you - don't have to fiddle with caching stuff. - -Explicit retrieval/removal of packages is only needed when you want to put packages to a -place where several applications can share these. If you just have an -dependency to a package, just add it to your package.json, dub will do the rest -for you. - -Without specified options, placement/removal will default to a user wide shared -location. - -Complete applications can be retrieved and run easily by e.g. - dub fetch vibelog --local - cd vibelog - dub -This will grab all needed dependencies and compile and run the application. - -Note: dub does not do any real "installation" of packages, those are registered -only within dub internal ecosystem. Generation of native system packages / installer -may be added later. - -Options: - --version Use the specified version/branch instead of the latest - For the remove command, this may be a wildcard - string: "*", which will remove all packages from the - specified location. - --system Put package into system wide dub cache instead of user local one - --local Put package to a sub folder of the current directory - Note that system and local cannot be mixed. -`); - return; - } - - // No specific help, show general help. - logInfo( -`Usage: dub [] [] [-- ] - -Manages the DUB project in the current directory. "--" can be used to separate -DUB options from options passed to the application. If the command is omitted, -dub will default to "run". - -Available commands: - help Prints this help screen - init [ []] - Initializes an empty project of the specified type in - the given directory. By default, the current working - dirctory is used. Available types: - minimal (default), vibe.d - run [] Builds and runs a package (default command) - build [] Builds a package (uses the main package in the current - working directory by default) - upgrade Forces an upgrade of all dependencies - fetch Manually retrieves a package. See 'dub help fetch'. - remove Removes present package. See 'dub help remove'. - add-local - Adds a local package directory (e.g. a git repository) - remove-local Removes a local package directory - add-path Adds a default package search path - remove-path Removes a package search path - list Prints a list of all present packages dub is aware of - generate [] - Generates project files using the specified generator: - visuald, visuald-combined, mono-d, build, rdmd - describe [] Prints a JSON description of the project and its - dependencies - -General options: - --annotate Do not execute dependency retrieval, just print - -v --verbose Also output debug messages - --vverbose Also output trace messages (produces a lot of output) - -q --quiet Only output warnings and errors - --vquiet No output - --registry=URL Search the given DUB registry URL first when resolving - dependencies. Can be specified multiple times. - --root=PATH Path to operate in instead of the current working dir - -Build/run options: - --build=NAME Specifies the type of build to perform. Note that - setting the DFLAGS environment variable will override - the build type with custom flags. - Possible names: - debug (default), plain, release, unittest, profile, - docs, ddox, cov, unittest-cov and custom types - --config=NAME Builds the specified configuration. Configurations can - be defined in package.json - --compiler=NAME Specifies the compiler binary to use. Arbitrary pre- - and suffixes to the identifiers below are recognized - (e.g. ldc2 or dmd-2.063) and matched to the proper - compiler type: - dmd (default), gdc, ldc, gdmd, ldmd - --arch=NAME Force a different architecture (e.g. x86 or x86_64) - --nodeps Do not check dependencies for 'run' or 'build' - --print-builds Prints the list of available build types - --print-configs Prints the list of available configurations - --print-platform Prints the identifiers for the current build platform - as used for the build fields in package.json - --rdmd Use rdmd instead of directly invoking the compiler - --debug=NAME Define the specified debug version identifier when - building - can be used multiple times - -Fetch/remove options: - --version Use the specified version/branch instead of the latest - --system Put package into system wide dub cache instead of user local one - --local Put packahe to a sub folder of the current directory - -`); - logInfo("DUB version %s", dubVersion); -} diff --git a/source/dub/commandline.d b/source/dub/commandline.d new file mode 100644 index 0000000..7a8fbdc --- /dev/null +++ b/source/dub/commandline.d @@ -0,0 +1,447 @@ +/** + Defines the behavior of the DUB command line client. + + Copyright: © 2012-2013 Matthias Dondorff + License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. + Authors: Matthias Dondorff, Sönke Ludwig +*/ +module dub.commandline; + +import dub.compilers.compiler; +import dub.dependency; +import dub.dub; +import dub.generators.generator; +import dub.internal.vibecompat.core.file; +import dub.internal.vibecompat.core.log; +import dub.internal.vibecompat.inet.url; +import dub.package_; +import dub.packagesupplier; +import dub.project; +import dub.version_; + +import std.algorithm; +import std.array; +import std.conv; +import std.encoding; +import std.exception; +import std.file; +import std.getopt; +import std.process; + + +int runDubCommandLine(string[] args) +{ + logDiagnostic("DUB version %s", dubVersion); + + string cmd; + + version(Windows){ + // rdmd uses $TEMP to compute a temporary path. since cygwin substitutes backslashes + // with slashes, this causes OPTLINK to fail (it thinks path segments are options) + // we substitute the other way around here to fix this. + environment["TEMP"] = environment["TEMP"].replace("/", "\\"); + } + + try { + // split application arguments from DUB arguments + string[] app_args; + auto app_args_idx = args.countUntil("--"); + if (app_args_idx >= 0) { + app_args = args[app_args_idx+1 .. $]; + args = args[0 .. app_args_idx]; + } + + // parse general options + bool verbose, vverbose, quiet, vquiet; + bool help, nodeps, annotate; + LogLevel loglevel = LogLevel.info; + string build_type, build_config; + string compiler_name = "dmd"; + string arch; + bool rdmd = false; + bool print_platform, print_builds, print_configs; + bool place_system_wide = false, place_locally = false; + string retrieved_version; + string[] registry_urls; + string[] debug_versions; + string root_path = getcwd(); + getopt(args, + "v|verbose", &verbose, + "vverbose", &vverbose, + "q|quiet", &quiet, + "vquiet", &vquiet, + "h|help", &help, // obsolete + "nodeps", &nodeps, + "annotate", &annotate, + "build", &build_type, + "compiler", &compiler_name, + "arch", &arch, + "rdmd", &rdmd, + "config", &build_config, + "debug", &debug_versions, + "print-builds", &print_builds, + "print-configs", &print_configs, + "print-platform", &print_platform, + "system", &place_system_wide, + "local", &place_locally, + "version", &retrieved_version, + "registry", ®istry_urls, + "root", &root_path + ); + + if( vverbose ) loglevel = LogLevel.debug_; + else if( verbose ) loglevel = LogLevel.diagnostic; + else if( vquiet ) loglevel = LogLevel.none; + else if( quiet ) loglevel = LogLevel.warn; + setLogLevel(loglevel); + + // extract the command + if( args.length > 1 && !args[1].startsWith("-") ){ + cmd = args[1]; + args = args[0] ~ args[2 .. $]; + } else cmd = "run"; + + // display help if requested (obsolete) + if( help ){ + showHelp(cmd); + return 0; + } + + BuildSettings build_settings; + auto compiler = getCompiler(compiler_name); + auto build_platform = compiler.determinePlatform(build_settings, compiler_name, arch); + build_settings.addDebugVersions(debug_versions); + + if( print_platform ){ + logInfo("Build platform:"); + logInfo(" Compiler: %s", build_platform.compiler); + logInfo(" System: %s", build_platform.platform.join(" ")); + logInfo(" Architecture: %s", build_platform.architecture.join(" ")); + logInfo(""); + } + + auto package_suppliers = registry_urls.map!(url => cast(PackageSupplier)new RegistryPackageSupplier(Url(url))).array; + Dub dub = new Dub(package_suppliers, root_path); + string def_config; + + // make the CWD package available so that for example sub packages can reference their + // parent package. + try dub.packageManager.getTemporaryPackage(Path(root_path), Version("~master")); + catch (Exception e) { logDiagnostic("No package found in current working directory."); } + + bool loadCwdPackage(Package pack) + { + if (!existsFile(dub.rootPath~"package.json") && !existsFile(dub.rootPath~"source/app.d")) { + logInfo(""); + logInfo("Neither package.json, nor source/app.d was found in the current directory."); + logInfo("Please run dub from the root directory of an existing package, or create a new"); + logInfo("package using \"dub init \"."); + logInfo(""); + showHelp(null); + return false; + } + + if (pack) dub.loadPackage(pack); + else dub.loadPackageFromCwd(); + + def_config = dub.getDefaultConfiguration(build_platform); + + return true; + } + + string package_name; + bool loadSelectedPackage() + { + Package pack; + if (!package_name.empty) { + // load package in root_path to enable searching for sub packages + loadCwdPackage(null); + pack = dub.packageManager.getFirstPackage(package_name); + enforce(pack, "Failed to find a package named '"~package_name~"'."); + logInfo("Building package %s in %s", pack.name, pack.path.toNativeString()); + dub.rootPath = pack.path; + } + if (!loadCwdPackage(pack)) return false; + if (!build_config.length) build_config = def_config; + return true; + } + + static void warnRenamed(string prev, string curr) + { + logWarn("Command '%s' was renamed to '%s'. Old name is deprecated, please update your scripts", prev, curr); + } + + // handle the command + switch( cmd ){ + default: + enforce(false, "Command is unknown: " ~ cmd); + assert(false); + case "help": + if(args.length >= 2) cmd = args[1]; + showHelp(cmd); + return 0; + case "init": + string dir; + string type = "minimal"; + if (args.length >= 2) dir = args[1]; + if (args.length >= 3) type = args[2]; + dub.createEmptyPackage(Path(dir), type); + return 0; + case "upgrade": + dub.loadPackageFromCwd(); + logInfo("Upgrading project in %s", dub.projectPath.toNativeString()); + dub.update(UpdateOptions.Upgrade | (annotate ? UpdateOptions.JustAnnotate : UpdateOptions.None)); + return 0; + case "install": + warnRenamed(cmd, "fetch"); + goto case "fetch"; + case "fetch": + enforce(args.length >= 2, "Missing package name."); + auto location = PlacementLocation.userWide; + auto name = args[1]; + enforce(!place_locally || !place_system_wide, "Cannot place package locally and system wide at the same time."); + if (place_locally) location = PlacementLocation.local; + else if (place_system_wide) location = PlacementLocation.systemWide; + if (retrieved_version.length) dub.fetch(name, Dependency(retrieved_version), location, true); + else { + try { + dub.fetch(name, Dependency(">=0.0.0"), location, true); + logInfo( + "Please note that you need to use `dub run ` " ~ + "or add it to dependencies of your package to actually use/run it. " ~ + "dub does not do actual installation of packages outside of its own ecosystem."); + } + catch(Exception e){ + logInfo("Getting a release version failed: %s", e.msg); + logInfo("Retry with ~master..."); + dub.fetch(name, Dependency("~master"), location, true); + } + } + break; + case "uninstall": + warnRenamed(cmd, "remove"); + goto case "remove"; + case "remove": + enforce(args.length >= 2, "Missing package name."); + auto location = PlacementLocation.userWide; + auto package_id = args[1]; + enforce(!place_locally || !place_system_wide, "Cannot place package locally and system wide at the same time."); + if ( place_locally ) location = PlacementLocation.local; + else if( place_system_wide ) location = PlacementLocation.systemWide; + try dub.remove(package_id, retrieved_version, location); + catch logError("Please specify a individual version or use the wildcard identifier '%s' (without quotes).", Dub.RemoveVersionWildcard); + break; + case "add-local": + enforce(args.length >= 3, "Missing arguments."); + dub.addLocalPackage(args[1], args[2], place_system_wide); + break; + case "remove-local": + enforce(args.length >= 2, "Missing path to package."); + dub.removeLocalPackage(args[1], place_system_wide); + break; + case "add-path": + enforce(args.length >= 2, "Missing search path."); + dub.addSearchPath(args[1], place_system_wide); + break; + case "remove-path": + enforce(args.length >= 2, "Missing search path."); + dub.removeSearchPath(args[1], place_system_wide); + break; + case "list-installed": + warnRenamed(cmd, "list"); + goto case "list"; + case "list": + logInfo("Packages present in the system and known to dub:"); + foreach (p; dub.packageManager.getPackageIterator()) + logInfo(" %s %s: %s", p.name, p.ver, p.path.toNativeString()); + logInfo(""); + break; + case "run": + case "build": + case "generate": + string generator; + if( cmd == "run" || cmd == "build" ) { + generator = rdmd ? "rdmd" : "build"; + if (args.length >= 2) package_name = args[1]; + } else { + if (args.length >= 2) generator = args[1]; + if (args.length >= 3) package_name = args[2]; + if(generator.empty) { + logInfo("Usage: dub generate []"); + return 1; + } + } + + if (!loadSelectedPackage()) return 1; + + if( print_builds ){ + logInfo("Available build types:"); + foreach( tp; ["debug", "release", "unittest", "profile"] ) + logInfo(" %s", tp); + logInfo(""); + } + + if( print_configs ){ + logInfo("Available configurations:"); + foreach( tp; dub.configurations ) + logInfo(" %s%s", tp, tp == def_config ? " [default]" : null); + logInfo(""); + } + + if( !nodeps ){ + logInfo("Checking dependencies in '%s'", dub.projectPath.toNativeString()); + dub.update(annotate ? UpdateOptions.JustAnnotate : UpdateOptions.None); + } + + enforce(build_config.length == 0 || dub.configurations.canFind(build_config), "Unknown build configuration: "~build_config); + + if (build_type.length == 0) { + if (environment.get("DFLAGS")) build_type = "$DFLAGS"; + else build_type = "debug"; + } + + GeneratorSettings gensettings; + gensettings.platform = build_platform; + gensettings.config = build_config; + gensettings.buildType = build_type; + gensettings.compiler = compiler; + gensettings.buildSettings = build_settings; + gensettings.run = cmd == "run"; + gensettings.runArgs = app_args; + + logDiagnostic("Generating using %s", generator); + dub.generateProject(generator, gensettings); + if (build_type == "ddox") dub.runDdox(gensettings.run); + break; + case "describe": + if (args.length >= 2) package_name = args[1]; + if (!loadSelectedPackage()) return 1; + dub.describeProject(build_platform, build_config); + break; + } + + return 0; + } + catch(Throwable e) + { + logError("Error: %s\n", e.msg); + logDiagnostic("Full exception: %s", sanitize(e.toString())); + logInfo("Run 'dub help' for usage information."); + return 1; + } +} + +private void showHelp(string command) +{ + if(command == "remove" || command == "fetch") { + logInfo( +`Usage: dub [] + +Note: use dependencies (package.json) if you want to add a dependency, you + don't have to fiddle with caching stuff. + +Explicit retrieval/removal of packages is only needed when you want to put packages to a +place where several applications can share these. If you just have an +dependency to a package, just add it to your package.json, dub will do the rest +for you. + +Without specified options, placement/removal will default to a user wide shared +location. + +Complete applications can be retrieved and run easily by e.g. + dub fetch vibelog --local + cd vibelog + dub +This will grab all needed dependencies and compile and run the application. + +Note: dub does not do any real "installation" of packages, those are registered +only within dub internal ecosystem. Generation of native system packages / installer +may be added later. + +Options: + --version Use the specified version/branch instead of the latest + For the remove command, this may be a wildcard + string: "*", which will remove all packages from the + specified location. + --system Put package into system wide dub cache instead of user local one + --local Put package to a sub folder of the current directory + Note that system and local cannot be mixed. +`); + return; + } + + // No specific help, show general help. + logInfo( +`Usage: dub [] [] [-- ] + +Manages the DUB project in the current directory. "--" can be used to separate +DUB options from options passed to the application. If the command is omitted, +dub will default to "run". + +Available commands: + help Prints this help screen + init [ []] + Initializes an empty project of the specified type in + the given directory. By default, the current working + dirctory is used. Available types: + minimal (default), vibe.d + run [] Builds and runs a package (default command) + build [] Builds a package (uses the main package in the current + working directory by default) + upgrade Forces an upgrade of all dependencies + fetch Manually retrieves a package. See 'dub help fetch'. + remove Removes present package. See 'dub help remove'. + add-local + Adds a local package directory (e.g. a git repository) + remove-local Removes a local package directory + add-path Adds a default package search path + remove-path Removes a package search path + list Prints a list of all present packages dub is aware of + generate [] + Generates project files using the specified generator: + visuald, visuald-combined, mono-d, build, rdmd + describe [] Prints a JSON description of the project and its + dependencies + +General options: + --annotate Do not execute dependency retrieval, just print + -v --verbose Also output debug messages + --vverbose Also output trace messages (produces a lot of output) + -q --quiet Only output warnings and errors + --vquiet No output + --registry=URL Search the given DUB registry URL first when resolving + dependencies. Can be specified multiple times. + --root=PATH Path to operate in instead of the current working dir + +Build/run options: + --build=NAME Specifies the type of build to perform. Note that + setting the DFLAGS environment variable will override + the build type with custom flags. + Possible names: + debug (default), plain, release, unittest, profile, + docs, ddox, cov, unittest-cov and custom types + --config=NAME Builds the specified configuration. Configurations can + be defined in package.json + --compiler=NAME Specifies the compiler binary to use. Arbitrary pre- + and suffixes to the identifiers below are recognized + (e.g. ldc2 or dmd-2.063) and matched to the proper + compiler type: + dmd (default), gdc, ldc, gdmd, ldmd + --arch=NAME Force a different architecture (e.g. x86 or x86_64) + --nodeps Do not check dependencies for 'run' or 'build' + --print-builds Prints the list of available build types + --print-configs Prints the list of available configurations + --print-platform Prints the identifiers for the current build platform + as used for the build fields in package.json + --rdmd Use rdmd instead of directly invoking the compiler + --debug=NAME Define the specified debug version identifier when + building - can be used multiple times + +Fetch/remove options: + --version Use the specified version/branch instead of the latest + --system Put package into system wide dub cache instead of user local one + --local Put packahe to a sub folder of the current directory + +`); + logInfo("DUB version %s", dubVersion); +}