diff --git a/.gitignore b/.gitignore index a5e949d..e2129a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,20 @@ *.o *.obj -.dub/ +.dub +.directory dub.selections.json -bin/dub docs.json __dummy.html + +# Ignore build files. +/bin/dub +/bin/__test__library-nonet__ +/bin/__test__library__ + +# Ignore files or directories created by the test suite. +/test/custom-source-main-bug487/custom-source-main-bug487 +/test/3-copyFiles/bin/ +/test/ignore-hidden-1/ignore-hidden-1 +/test/ignore-hidden-2/ignore-hidden-2 diff --git a/source/dub/commandline.d b/source/dub/commandline.d index 1f3f281..420447b 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -109,7 +109,6 @@ new TestCommand, new GenerateCommand, new DescribeCommand, - new ListImportsCommand, new CleanCommand, new DustmiteCommand ), @@ -747,13 +746,28 @@ } class DescribeCommand : PackageBuildCommand { + private { + bool m_importPaths = false; + bool m_stringImportPaths = false; + } + this() { this.name = "describe"; this.argumentsPattern = "[]"; this.description = "Prints a JSON description of the project and its dependencies"; this.helpText = [ - "Prints a JSON build description for the root package an all of their dependencies in a format similar to a JSON package description file. This is useful mostly for IDEs.", + "Prints a JSON build description for the root package an all of " + "their dependencies in a format similar to a JSON package " + "description file. This is useful mostly for IDEs.", + "", + "When --import-paths is supplied, the import paths for a project ", + "will be printed line-by-line instead. The paths for D source " + "files across all dependent projects will be included.", + "", + "--string-import-paths can can supplied to print the string " + "import paths for a project.", + "", "All usual options that are also used for build/run/generate apply." ]; } @@ -761,10 +775,23 @@ override void prepare(scope CommandArgs args) { super.prepare(args); + + args.getopt("import-paths", &m_importPaths, [ + "List the import paths for project." + ]); + + args.getopt("string-import-paths", &m_stringImportPaths, [ + "List the string import paths for project." + ]); } override int execute(Dub dub, string[] free_args, string[] app_args) { + enforceUsage( + !(m_importPaths && m_stringImportPaths), + "--import-paths and --string-import-paths may not be used together." + ); + // disable all log output and use "writeln" to output the JSON description auto ll = getLogLevel(); setLogLevel(LogLevel.none); @@ -777,43 +804,16 @@ m_defaultConfig = dub.project.getDefaultConfiguration(m_buildPlatform); - dub.describeProject(m_buildPlatform, m_buildConfig.length ? m_buildConfig : m_defaultConfig); - return 0; - } -} + auto config = m_buildConfig.length ? m_buildConfig : m_defaultConfig; -class ListImportsCommand : PackageBuildCommand { - this() - { - this.name = "list-import-paths"; - this.argumentsPattern = "[]"; - this.description = "Prints a list of import paths for the project and its dependencies"; - this.helpText = [ - "Prints a list of imports for the root package an all of their dependencies. This can be useful for build tools needing to know where to find the imports." - "All usual options that are also used for build/run/generate apply." - ]; - } + if (m_importPaths) { + dub.listImportPaths(m_buildPlatform, config); + } else if (m_stringImportPaths) { + dub.listStringImportPaths(m_buildPlatform, config); + } else { + dub.describeProject(m_buildPlatform, config); + } - override void prepare(scope CommandArgs args) - { - super.prepare(args); - } - - override int execute(Dub dub, string[] free_args, string[] app_args) - { - // disable all log output and use "writeln" to output the import paths. - auto ll = getLogLevel(); - setLogLevel(LogLevel.none); - scope (exit) setLogLevel(ll); - - string package_name; - enforceUsage(free_args.length <= 1, "Expected one or zero arguments."); - if (free_args.length >= 1) package_name = free_args[0]; - setupPackage(dub, package_name); - - m_defaultConfig = dub.project.getDefaultConfiguration(m_buildPlatform); - - dub.listImportPaths(m_buildPlatform, m_buildConfig.length ? m_buildConfig : m_defaultConfig); return 0; } } @@ -1671,3 +1671,4 @@ { logWarn("The '%s' Command was renamed to '%s'. Please update your scripts.", prev, curr); } + diff --git a/source/dub/dub.d b/source/dub/dub.d index 6a4a813..77abea4 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -422,11 +422,11 @@ write(dst.toPrettyString()); } - void listImportPaths(BuildPlatform platform, string config) + private void listPaths(string methodName)(BuildPlatform platform, string config) { string[] importPaths; - m_project.listImportPaths(importPaths, platform, config); + __traits(getMember, m_project, methodName)(importPaths, platform, config); import std.stdio; @@ -435,6 +435,16 @@ } } + void listImportPaths(BuildPlatform platform, string config) + { + listPaths!"listImportPaths"(platform, config); + } + + void listStringImportPaths(BuildPlatform platform, string config) + { + listPaths!"listStringImportPaths"(platform, config); + } + /// Cleans intermediate/cache files of the given package void cleanPackage(Path path) { diff --git a/source/dub/project.d b/source/dub/project.d index dc7c023..a5bb2cc 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -582,16 +582,18 @@ } } - /// Outputs the import paths for the project, including its dependencies. - void listImportPaths(ref string[] list, BuildPlatform platform, string config) + private void listPaths(string attributeName)(ref string[] list, BuildPlatform platform, string config) { auto configs = getPackageConfigs(platform, config); - import std.path : buildPath; + import std.path : buildPath, dirSeparator; auto fullPackagePaths(Package pack) { - return pack.getBuildSettings(platform, config).importPaths - .map!(importPath => buildPath(pack.path.toString(), importPath)); + // Return full paths for the import paths, making sure a + // directory separator is on the end of each path. + return __traits(getMember, pack.getBuildSettings(platform, config), attributeName) + .map!(importPath => buildPath(pack.path.toString(), importPath)) + .map!(path => path.endsWith(dirSeparator) ? path : path ~ dirSeparator); } foreach(path; fullPackagePaths(m_rootPackage)) { @@ -605,6 +607,19 @@ } } + /// Outputs the import paths for the project, including its dependencies. + void listImportPaths(ref string[] list, BuildPlatform platform, string config) + { + listPaths!"importPaths"(list, platform, config); + + } + + /// Outputs the string import paths for the project, including its dependencies. + void listStringImportPaths(ref string[] list, BuildPlatform platform, string config) + { + listPaths!"stringImportPaths"(list, platform, config); + } + void saveSelections() { assert(m_selections !is null, "Cannot save selections for non-disk based project (has no selections)."); diff --git a/test/4-describe-import-paths.sh b/test/4-describe-import-paths.sh new file mode 100755 index 0000000..9bf7a28 --- /dev/null +++ b/test/4-describe-import-paths.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +cd "$CURR_DIR"/describe-project + +temp_file=`mktemp` + +function cleanup { + rm $temp_file +} + +$DUB describe --compiler=$COMPILER --import-paths > "$temp_file" + +if (( $? )); then + cleanup + die 'Printing import paths failed!' +fi + +if ! diff -q "$CURR_DIR"/expected-import-path-output "$temp_file"; then + cleanup + die 'The import paths did not match the expected output!' +fi + +cleanup +exit 0 diff --git a/test/4-describe-json.sh b/test/4-describe-json.sh new file mode 100755 index 0000000..254ac84 --- /dev/null +++ b/test/4-describe-json.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +cd "$CURR_DIR"/describe-project + +$DUB describe --compiler=$COMPILER > /dev/null + +if (( $? )); then + die 'Printing describe JSON failed!' +fi + +exit 0 diff --git a/test/4-describe-string-importh-paths.sh b/test/4-describe-string-importh-paths.sh new file mode 100755 index 0000000..ab7a34f --- /dev/null +++ b/test/4-describe-string-importh-paths.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +cd "$CURR_DIR"/describe-project + +temp_file=`mktemp` + +function cleanup { + rm $temp_file +} + +$DUB describe --compiler=$COMPILER --string-import-paths > "$temp_file" + +if (( $? )); then + cleanup + die 'Printing string import paths failed!' +fi + +if ! diff -q "$CURR_DIR"/expected-string-import-path-output "$temp_file"; then + cleanup + die 'The string import paths did not match the expected output!' +fi + +cleanup +exit 0 + diff --git a/test/describe-dependency-1/.no_build b/test/describe-dependency-1/.no_build new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/test/describe-dependency-1/.no_build @@ -0,0 +1 @@ + diff --git a/test/describe-dependency-1/dub.json b/test/describe-dependency-1/dub.json new file mode 100644 index 0000000..239e6b1 --- /dev/null +++ b/test/describe-dependency-1/dub.json @@ -0,0 +1,9 @@ +{ + "name": "describe-dependency-1", + "targetType": "sourceLibrary", + "description": "A test describe project", + "authors": ["nobody"], + "homepage": "fake.com", + "license": "BSD 2-clause", + "copyright": "Copyright © 2015, nobody" +} diff --git a/test/describe-dependency-2/.no_build b/test/describe-dependency-2/.no_build new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/test/describe-dependency-2/.no_build @@ -0,0 +1 @@ + diff --git a/test/describe-dependency-2/dub.json b/test/describe-dependency-2/dub.json new file mode 100644 index 0000000..0b62a92 --- /dev/null +++ b/test/describe-dependency-2/dub.json @@ -0,0 +1,11 @@ +{ + "name": "describe-dependency-2", + "targetType": "sourceLibrary", + "description": "A test describe project", + "authors": ["nobody"], + "homepage": "fake.com", + "license": "BSD 2-clause", + "copyright": "Copyright © 2015, nobody", + "importPaths": ["some-path"], + "stringImportPaths": ["some-extra-string-import-path"], +} diff --git a/test/describe-project/.no_build b/test/describe-project/.no_build new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/test/describe-project/.no_build @@ -0,0 +1 @@ + diff --git a/test/describe-project/dub.json b/test/describe-project/dub.json new file mode 100644 index 0000000..8adf13f --- /dev/null +++ b/test/describe-project/dub.json @@ -0,0 +1,19 @@ +{ + "name": "describe-project", + "targetType": "sourceLibrary", + "description": "A test describe project", + "authors": ["nobody"], + "homepage": "fake.com", + "license": "BSD 2-clause", + "copyright": "Copyright © 2015, nobody", + "dependencies": { + "describe-dependency-1": { + "version": "1.0", + "path": "../describe-dependency-1" + }, + "describe-dependency-2": { + "version": "1.0", + "path": "../describe-dependency-2" + } + } +} diff --git a/test/expected-import-path-output b/test/expected-import-path-output new file mode 100644 index 0000000..62f1eed --- /dev/null +++ b/test/expected-import-path-output @@ -0,0 +1,3 @@ +/home/w0rp/git/personal/dub/test/describe-project/src/ +/home/w0rp/git/personal/dub/test/describe-dependency-1/source/ +/home/w0rp/git/personal/dub/test/describe-dependency-2/some-path/ diff --git a/test/expected-string-import-path-output b/test/expected-string-import-path-output new file mode 100644 index 0000000..dcb8e56 --- /dev/null +++ b/test/expected-string-import-path-output @@ -0,0 +1,2 @@ +/home/w0rp/git/personal/dub/test/describe-project/views/ +/home/w0rp/git/personal/dub/test/describe-dependency-2/some-extra-string-import-path/ diff --git a/test/run-unittest.sh b/test/run-unittest.sh index ad0a219..ccd0831 100755 --- a/test/run-unittest.sh +++ b/test/run-unittest.sh @@ -5,10 +5,14 @@ exit 1 } +export -f die + function log() { echo -e "\033[0;33m[INFO] "$@"\033[0m" } +export -f log + if [ -z ${DUB} ]; then die 'Error: Variable $DUB must be defined to run the tests.' fi @@ -23,7 +27,7 @@ for script in $(ls $CURR_DIR/*.sh); do if [ "$script" = "$(readlink -f ${BASH_SOURCE[0]})" ]; then continue; fi log "Running $script..." - DUB=$DUB COMPILER=$COMPILER $script || die "Script failure." + DUB=$DUB COMPILER=$COMPILER CURR_DIR="$CURR_DIR" $script || die "Script failure." done for pack in $(ls -d $CURR_DIR/*/); do