diff --git a/.travis.yml b/.travis.yml index 97fee437..e56fa343 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ # # Using sudo-false/container-based tests for greater (linux) test responsiveness. This doesn't seem -# to effect the queing time for OSX tests. +# to effect the queueing time for OSX tests. # dist: trusty diff --git a/CHANGELOG.md b/CHANGELOG.md index 757ff1fd..f361d133 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v2.9.7 - 2018-08-14 + +This is a minor bugfix update from v2.9.6. + +### Fixed +- Preserve softlinks in input reference fasta file paths (STREL-976) + ## v2.9.6 - 2018-07-17 This is a minor bugfix update from v2.9.5. diff --git a/src/c++/lib/applications/GetChromDepth/ChromDepthOptions.cpp b/src/c++/lib/applications/GetChromDepth/ChromDepthOptions.cpp index 233417b7..5a9a411e 100644 --- a/src/c++/lib/applications/GetChromDepth/ChromDepthOptions.cpp +++ b/src/c++/lib/applications/GetChromDepth/ChromDepthOptions.cpp @@ -58,8 +58,8 @@ parseOptions( ChromDepthOptions& opt, std::string& errorMsg) { - if (checkStandardizeInputFile(opt.alignmentFilename, "alignment", errorMsg)) return true; - if (checkStandardizeInputFile(opt.referenceFilename, "reference fasta", errorMsg)) return true; + if (checkAndStandardizeRequiredInputFilePath(opt.alignmentFilename, "alignment", errorMsg)) return true; + if (checkAndStandardizeRequiredInputFilePath(opt.referenceFilename, "reference fasta", errorMsg)) return true; if (vm.count("chrom")) { diff --git a/src/c++/lib/applications/GetRegionDepth/RegionDepthOptions.cpp b/src/c++/lib/applications/GetRegionDepth/RegionDepthOptions.cpp index 8d7041de..ddf50451 100644 --- a/src/c++/lib/applications/GetRegionDepth/RegionDepthOptions.cpp +++ b/src/c++/lib/applications/GetRegionDepth/RegionDepthOptions.cpp @@ -58,8 +58,8 @@ parseOptions( RegionDepthOptions& opt, std::string& errorMsg) { - if (checkStandardizeInputFile(opt.alignmentFilename, "alignment", errorMsg)) return true; - if (checkStandardizeInputFile(opt.referenceFilename, "reference fasta", errorMsg)) return true; + if (checkAndStandardizeRequiredInputFilePath(opt.alignmentFilename, "alignment", errorMsg)) return true; + if (checkAndStandardizeRequiredInputFilePath(opt.referenceFilename, "reference fasta", errorMsg)) return true; if (vm.count("region")) { diff --git a/src/c++/lib/blt_util/compat_util.cpp b/src/c++/lib/blt_util/compat_util.cpp index 9d33218d..2ad96d23 100644 --- a/src/c++/lib/blt_util/compat_util.cpp +++ b/src/c++/lib/blt_util/compat_util.cpp @@ -27,28 +27,6 @@ #include -#ifdef _MSC_VER -#include "compat_util_win32_realpath.c" -#endif - - - -bool -compat_realpath(std::string& path) -{ - errno=0; - const char* newpath(realpath(path.c_str(),nullptr)); - if ((nullptr==newpath) || (errno!=0)) - { - if (nullptr!=newpath) free((void*)newpath); - return false; - } - path = newpath; - free((void*)newpath); - return true; -} - - double compat_round(const double x) diff --git a/src/c++/lib/blt_util/compat_util.hh b/src/c++/lib/blt_util/compat_util.hh index aff5772c..ba2f9bbd 100644 --- a/src/c++/lib/blt_util/compat_util.hh +++ b/src/c++/lib/blt_util/compat_util.hh @@ -42,9 +42,3 @@ compat_round(const double x); const char* compat_basename(const char* s); - - -// gets canonical name of paths, but only when these refer to existing items -// returns false on error. -bool -compat_realpath(std::string& path); diff --git a/src/c++/lib/blt_util/compat_util_win32_realpath.c b/src/c++/lib/blt_util/compat_util_win32_realpath.c deleted file mode 100644 index 2d25f25c..00000000 --- a/src/c++/lib/blt_util/compat_util_win32_realpath.c +++ /dev/null @@ -1,95 +0,0 @@ -/* realpath.c - * $Id$ - * - * Provides an implementation of the "realpath" function, conforming - * approximately to SUSv3, and adapted for use on native Microsoft(R) - * Win32 platforms. - * - * Written by Keith Marshall - * - * This is free software. You may redistribute and/or modify it as you - * see fit, without restriction of copyright. - * - * This software is provided "as is", in the hope that it may be useful, - * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of - * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no - * time will the author accept any form of liability for any damages, - * however caused, resulting from the use of this software. - * - */ - -#ifdef _WIN32 -#include -#include -#include - -char* __cdecl -realpath( const char * name, char * resolved ) -{ - char *retname = NULL; /* we will return this, if we fail */ - - /* SUSv3 says we must set `errno = EINVAL', and return NULL, - * if `name' is passed as a NULL pointer. - */ - - if( name == NULL ) - errno = EINVAL; - - /* Otherwise, `name' must refer to a readable filesystem object, - * if we are going to resolve its absolute path name. - */ - - else if( _access( name, 4 ) == 0 ) - { - /* If `name' didn't point to an existing entity, - * then we don't get to here; we simply fall past this block, - * returning NULL, with `errno' appropriately set by `access'. - * - * When we _do_ get to here, then we can use `_fullpath' to - * resolve the full path for `name' into `resolved', but first, - * check that we have a suitable buffer, in which to return it. - */ - - if( (retname = resolved) == NULL ) - { - /* Caller didn't give us a buffer, so we'll exercise the - * option granted by SUSv3, and allocate one. - * - * `_fullpath' would do this for us, but it uses `malloc', and - * Microsoft's implementation doesn't set `errno' on failure. - * If we don't do this explicitly ourselves, then we will not - * know if `_fullpath' fails on `malloc' failure, or for some - * other reason, and we want to set `errno = ENOMEM' for the - * `malloc' failure case. - */ - - retname =(char*) malloc( _MAX_PATH ); - } - - /* By now, we should have a valid buffer. - * If we don't, then we know that `malloc' failed, - * so we can set `errno = ENOMEM' appropriately. - */ - - if( retname == NULL ) - errno = ENOMEM; - - /* Otherwise, when we do have a valid buffer, - * `_fullpath' should only fail if the path name is too long. - */ - - else if( (retname = _fullpath( retname, name, _MAX_PATH )) == NULL ) - errno = ENAMETOOLONG; - } - - /* By the time we get to here, - * `retname' either points to the required resolved path name, - * or it is NULL, with `errno' set appropriately, either of which - * is our required return condition. - */ - - return retname; -} - -/* $RCSfile$: end of file */ -#endif diff --git a/src/c++/lib/options/AlignmentFileOptionsParser.cpp b/src/c++/lib/options/AlignmentFileOptionsParser.cpp index 21aa2d60..2de2acb9 100644 --- a/src/c++/lib/options/AlignmentFileOptionsParser.cpp +++ b/src/c++/lib/options/AlignmentFileOptionsParser.cpp @@ -68,7 +68,7 @@ checkOptions( std::set nameCheck; for (std::string& afile : opt.alignmentFilenames) { - if (checkStandardizeInputFile(afile,"alignment file",errorMsg)) break; + if (checkAndStandardizeRequiredInputFilePath(afile, "alignment file", errorMsg)) break; if (nameCheck.count(afile)) { std::ostringstream oss; diff --git a/src/c++/lib/options/optionsUtil.cpp b/src/c++/lib/options/optionsUtil.cpp index 8069578d..895155d3 100644 --- a/src/c++/lib/options/optionsUtil.cpp +++ b/src/c++/lib/options/optionsUtil.cpp @@ -26,7 +26,7 @@ bool -checkStandardizeInputFile( +checkAndStandardizeRequiredInputFilePath( std::string& filename, const char* fileLabel, std::string& errorMsg) diff --git a/src/c++/lib/options/optionsUtil.hh b/src/c++/lib/options/optionsUtil.hh index 32825487..f4295e34 100644 --- a/src/c++/lib/options/optionsUtil.hh +++ b/src/c++/lib/options/optionsUtil.hh @@ -22,13 +22,11 @@ #include -/// check if input file exists and is usable as -/// input, if so canonicalize the name +/// Check if input path exists and is usable as input, if so, convert the input filename to an absolute path. /// -/// In case of error return true and provide error -/// message +/// In case of error return true and provide error message bool -checkStandardizeInputFile( +checkAndStandardizeRequiredInputFilePath( std::string& filename, const char* fileLabel, std::string& errorMsg); diff --git a/src/c++/lib/starling_common/starling_base_option_parser.cpp b/src/c++/lib/starling_common/starling_base_option_parser.cpp index 3574604f..6268c696 100644 --- a/src/c++/lib/starling_common/starling_base_option_parser.cpp +++ b/src/c++/lib/starling_common/starling_base_option_parser.cpp @@ -21,6 +21,7 @@ #include "blt_common/blt_arg_validate.hh" #include "blt_util/compat_util.hh" +#include "options/optionsUtil.hh" #include "starling_common/Tier2OptionsParser.hh" #include "boost/filesystem.hpp" @@ -169,13 +170,15 @@ finalize_starling_base_options( pinfo.usage("Must specify a fasta reference file"); } - // canonicalize the reference sequence path: - /// TODO: replace this with the same thing from boost? - if (! compat_realpath(opt.referenceFilename)) + // Convert reference sequence path to an absolute path. Just like for BAM/CRAM files, we want absolute but not + // canonical path in this case, because following softlinks to the canonical path will often cause us to miss the + // sidecar index file. { - std::ostringstream oss; - oss << "can't resolve reference path: " << opt.referenceFilename << "\n"; - pinfo.usage(oss.str().c_str()); + std::string errorMsg; + if (checkAndStandardizeRequiredInputFilePath(opt.referenceFilename, "reference fasta", errorMsg)) + { + pinfo.usage(errorMsg.c_str()); + } } // set analysis regions: @@ -226,12 +229,15 @@ finalize_starling_base_options( { checkOptionalInputFile(pinfo, indelErrorModelFilename, "indel error models"); } - /// tier2 options are not parsed by starling_base, but need to live up here for now, - /// so validate them together with the rest of starling_base - std::string errorMsg; - if (parseTier2Options(vm,opt.tier2,errorMsg)) + + // tier2 options are not parsed by starling_base, but need to live up here for now, + // so validate them together with the rest of starling_base { - pinfo.usage(errorMsg.c_str()); + std::string errorMsg; + if (parseTier2Options(vm, opt.tier2, errorMsg)) + { + pinfo.usage(errorMsg.c_str()); + } } if (opt.useTier2Evidence)