{"id":18879716,"url":"https://github.com/loilo/find-up","last_synced_at":"2025-06-10T22:37:57.587Z","repository":{"id":62518795,"uuid":"197177175","full_name":"loilo/find-up","owner":"loilo","description":"📁 Find a file by walking up ancestor directories","archived":false,"fork":false,"pushed_at":"2020-12-23T23:07:54.000Z","size":22,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-11T13:15:09.081Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loilo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-16T10:59:25.000Z","updated_at":"2022-05-04T18:34:43.000Z","dependencies_parsed_at":"2022-11-02T10:31:42.342Z","dependency_job_id":null,"html_url":"https://github.com/loilo/find-up","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Ffind-up","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Ffind-up/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Ffind-up/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Ffind-up/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loilo","download_url":"https://codeload.github.com/loilo/find-up/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248943520,"owners_count":21186978,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T06:39:00.835Z","updated_at":"2025-04-14T19:23:34.045Z","avatar_url":"https://github.com/loilo.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg alt=\"FindUp logo: a folder icon with an upwards arrow in front\" src=\"find-up.svg\" width=\"220\" height=\"189\"\u003e\n\u003c/div\u003e\n\n# FindUp\n[![Tests](https://badgen.net/github/checks/loilo/find-up/master)](https://github.com/loilo/find-up/actions)\n[![Version on packagist.org](https://badgen.net/packagist/v/loilo/find-up)](https://packagist.org/packages/loilo/find-up)\n\nFind a file by walking up ancestor directories (e.g. a `composer.json` from inside a project).\n\n## Installation\n```bash\ncomposer require loilo/find-up\n```\n\n## Usage\n### Basic Example\n```\n/var/www\n└── project\n    ├── composer.json\n    └── src\n        └── foo\n            ├── bar\n            └── example.php\n```\n\n`example.php`:\n```php\nuse Loilo\\FindUp\\Up;\n\n// Get the project's composer.json's path by\n// walking up from /var/www/project/src/foo\nUp::find('composer.json') === '/var/www/project/composer.json';\n```\n\nThis is the most basic example how to use this package. The finder will look for a `composer.json` file, starting at the directory where `Up::find()` was called (which is `/var/www/project/src/foo`).\n\n\u003e **Note:** If there was no `composer.json` on the way up, the `find` method would return `null`.\n\n### Starting Directory\nAs can be seen in the basic example above, the default starting directory is the one from where `Up::find()` is called. Alternatively, a starting directory can be passed to the `find` method as a second argument:\n\n```php\n// Start from the current working directory\nUp::find('composer.json', getcwd());\n```\n\n### Advanced Matching\nInstead of a file name to search for, a (non-string) callable may be passed as the `find` method's first argument. It will receive each encountered file on the way up and decides whether it is the searched file.\n\nAssuming we're starting in the `example.php` from the basic example directory tree above, we can find the path to the `composer.json` with the following call:\n\n```php\nUp::find(function ($file, $directory) {\n  return $file === 'composer.json';\n});\n```\n\n#### Stop Searching Prematurely\nYou can stop the search before reaching the filesystem root by returning an `Up::stop()` call. For example, if you know that your `composer.json` is not found upwards from the `/var/www` folder, you can break out of the search:\n\n```php\nUp::find(function ($file, $directory) {\n  if ($directory === '/var/www') {\n    return Up::stop();\n  }\n\n  return $file === 'composer.json';\n});\n```\n\nWhen returning `Up::stop()`, the `Up::find()` method will return `null` by default.\n\nYou may however pass a path to the `stop()` method that will be used as the result. If the path is not absolute, it will be resolved against the current `$directory`:\n\n```php\nUp::find(function ($file, $directory) {\n  if ($directory === '/var/www') {\n    return Up::stop('stop.txt');\n  }\n\n  return false;\n}) === '/var/www/stop.txt';\n```\n\n\u003e **Note:** In previous versions, the way to stop searching was to return the `Up::STOP` constant.\n\u003e\n\u003e This technique still works, but it's deprecated and it's recommended to use `Up::stop()` instead.\n\n#### Skip Folder\nIf you are in a directory of which you're sure it does not contain the searched file, you may avoid walking through all its files by returning `Up::skip()`:\n\n```php\nUp::find(function ($file, $directory) {\n  // Skip \"src\" directories\n  if (basename($directory) === 'src') {\n    return Up::skip();\n  }\n\n  return $file === 'composer.json';\n});\n```\n\nBy default, the `Up::skip()` method will only skip the currently scanned directory. You may however pass a (positive) number that indicates how many levels of directories should be skipped.\n\n```php\n...\n\n// skip the current directory and its parent directory,\n// continue with grandparent directory\nreturn Up::skip(2)\n```\n\n\u003e **Note:** In previous versions, the way to skip scanning a folder was to return the `Up::SKIP` constant.\n\u003e\n\u003e This technique still works, but it's deprecated and it's recommended to use `Up::skip()` instead.\n\n#### Jump to Other Folder\nIf you want to stop searching the current directory tree altogether and continue from another path, you can return an `Up::jump()` call:\n\n```php\nUp::find(function ($file, $directory) {\n  if ($directory === '/var/www/project') {\n    return Up::jump('/var/www/other-project');\n  }\n\n  return $file === 'composer.json';\n});\n```\n\n\u003e **Note:** You can only jump to a directory you have not previously visited in the current search. This serves to avoid infinite loops.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floilo%2Ffind-up","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floilo%2Ffind-up","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floilo%2Ffind-up/lists"}