README.md (5756B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2021 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # resolveParentPathBy 22 23 > Resolve a path according to a predicate function by walking parent directories. 24 25 <section class="usage"> 26 27 ## Usage 28 29 ```javascript 30 var resolveParentPathBy = require( '@stdlib/fs/resolve-parent-path-by' ); 31 ``` 32 33 <a name="resolve-parent-path-by"></a> 34 35 #### resolveParentPathBy( path\[, options], predicate, clbk ) 36 37 Asynchronously resolves a path according to a `predicate` function by walking parent directories. 38 39 ```javascript 40 resolveParentPathBy( 'package.json', predicate, onPath ); 41 42 function predicate( path, next ) { 43 var bool = ( /\/test\//.test( path ) === false ); 44 next( null, bool ); 45 } 46 47 function onPath( error, path ) { 48 if ( error ) { 49 throw error; 50 } 51 console.log( path ); 52 // e.g., => '...' 53 } 54 ``` 55 56 The function accepts the following `options`: 57 58 - **dir**: base directory from which to begin walking. May be either an absolute path or a path relative to the current working directory. 59 60 By default, the function begins walking from the current working directory. To specify an alternative directory, set the `dir` option. 61 62 ```javascript 63 var opts = { 64 'dir': __dirname 65 }; 66 resolveParentPathBy( 'package.json', opts, predicate, onPath ); 67 68 function predicate( path, next ) { 69 var bool = ( /\/test\//.test( path ) === false ); 70 next( null, bool ); 71 } 72 73 function onPath( error, path ) { 74 if ( error ) { 75 throw error; 76 } 77 console.log( path ); 78 // e.g., => '...' 79 } 80 ``` 81 82 When invoked, the `predicate` function is provided two arguments: 83 84 - `path`: a resolved path. 85 - `next`: a callback which should be called once the `predicate` function has finished processing a resolved path. 86 87 If a `predicate` function calls the `next` callback with a truthy second argument, the function stops processing any additional paths and returns the resolved path as the test result. 88 89 If unable to resolve a path, the function returns `null` as the path result. 90 91 #### resolveParentPathBy.sync( path\[, options], predicate ) 92 93 Synchronously resolves a path according to a `predicate` function by walking parent directories. 94 95 ```javascript 96 function predicate( path ) { 97 return ( /\/test\//.test( path ) === false ); 98 } 99 100 var path = resolveParentPathBy.sync( 'package.json', predicate ); 101 // e.g., returns '...' 102 ``` 103 104 The function accepts the same `options` as [`resolveParentPathBy()`](#resolve-parent-path-by). 105 106 When invoked, the `predicate` function is provided one argument: 107 108 - `path`: a resolved path. 109 110 The function immediately returns upon encountering a truthy `predicate` function return value. 111 112 If unable to resolve a path, the function returns `null` as the path result. 113 114 </section> 115 116 <!-- /.usage --> 117 118 <section class="notes"> 119 120 ## Notes 121 122 - If a provided `predicate` function calls the `next` callback with a truthy `error` argument, the function suspends execution and immediately calls the `done` callback for subsequent `error` handling. 123 - For `resolveParentPathBy`, execution is **not** guaranteed to be asynchronous. To guarantee asynchrony, wrap the `done` callback in a function which either executes at the end of the current stack (e.g., `nextTick`) or during a subsequent turn of the event loop (e.g., `setImmediate`, `setTimeout`). 124 - This implementation is **not** similar in functionality to core [`path.resolve`][node-core-path-resolve]. The latter performs string manipulation to generate a full path. This implementation walks parent directories to perform a **search**, thereby touching the file system. Accordingly, this implementation resolves a _real_ absolute file path and is intended for use when a target's location in a parent directory is unknown relative to a child directory; e.g., when wanting to find a package root from deep within a package directory. 125 126 </section> 127 128 <!-- /.notes --> 129 130 <section class="examples"> 131 132 ## Examples 133 134 <!-- eslint no-undef: "error" --> 135 136 <!-- eslint-disable stdlib/no-dynamic-require --> 137 138 ```javascript 139 var resolveParentPathBy = require( '@stdlib/fs/resolve-parent-path-by' ); 140 141 var opts = { 142 'dir': __dirname 143 }; 144 145 /* Sync */ 146 147 function predicateSync( path ) { 148 var pkg = require( path ); 149 if ( pkg.name !== '@stdlib/stdlib' ) { 150 return false; 151 } 152 return true; 153 } 154 155 var out = resolveParentPathBy.sync( 'package.json', opts, predicateSync ); 156 console.log( out ); 157 // e.g., => '...' 158 159 out = resolveParentPathBy.sync( 'non_existent_basename/package.json', predicateSync ); 160 console.log( out ); 161 // => null 162 163 /* Async */ 164 165 function predicateAsync( path, next ) { 166 setTimeout( onTimeout, 0 ); 167 168 function onTimeout() { 169 var pkg = require( path ); 170 if ( pkg.name !== '@stdlib/stdlib' ) { 171 return next( null, false ); 172 } 173 next( null, true ); 174 } 175 } 176 177 function onPath( error, path ) { 178 if ( error ) { 179 throw error; 180 } 181 console.log( path ); 182 } 183 184 resolveParentPathBy( 'package.json', opts, predicateAsync, onPath ); 185 resolveParentPathBy( './../non_existent_path/package.json', predicateAsync, onPath ); 186 ``` 187 188 </section> 189 190 <!-- /.examples --> 191 192 <section class="links"> 193 194 [node-core-path-resolve]: https://nodejs.org/api/path.html#path_path_resolve_paths 195 196 </section> 197 198 <!-- /.links -->