{"id":21275694,"url":"https://github.com/halimath/globwatch","last_synced_at":"2026-05-18T18:41:24.931Z","repository":{"id":64297747,"uuid":"565255530","full_name":"halimath/globwatch","owner":"halimath","description":"Recursive glob watches of filesystems for go(lang)","archived":false,"fork":false,"pushed_at":"2022-11-12T20:22:31.000Z","size":18,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T03:27:31.231Z","etag":null,"topics":["filesystem","go","golang","watcher"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/halimath.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":"2022-11-12T20:21:05.000Z","updated_at":"2023-02-22T08:10:29.000Z","dependencies_parsed_at":"2023-01-15T09:01:38.691Z","dependency_job_id":null,"html_url":"https://github.com/halimath/globwatch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halimath%2Fglobwatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halimath%2Fglobwatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halimath%2Fglobwatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halimath%2Fglobwatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/halimath","download_url":"https://codeload.github.com/halimath/globwatch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243732303,"owners_count":20338839,"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":["filesystem","go","golang","watcher"],"created_at":"2024-11-21T09:36:12.703Z","updated_at":"2025-12-30T18:13:06.905Z","avatar_url":"https://github.com/halimath.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# globwatch\n\nA file system glob watcher for golang. \n\n![CI Status][ci-img-url] \n[![Go Report Card][go-report-card-img-url]][go-report-card-url] \n[![Package Doc][package-doc-img-url]][package-doc-url] \n[![Releases][release-img-url]][release-url]\n\n[ci-img-url]: https://github.com/halimath/globwatch/workflows/CI/badge.svg\n[go-report-card-img-url]: https://goreportcard.com/badge/github.com/halimath/globwatch\n[go-report-card-url]: https://goreportcard.com/report/github.com/halimath/globwatch\n[package-doc-img-url]: https://img.shields.io/badge/GoDoc-Reference-blue.svg\n[package-doc-url]: https://pkg.go.dev/github.com/halimath/globwatch\n[release-img-url]: https://img.shields.io/github/v/release/halimath/globwatch.svg\n[release-url]: https://github.com/halimath/globwatch/releases\n\n`globwatch` provides a file system watcher that detects changes recursively for\nfiles that match a glob pattern.\n\n# Installation\n\n`globwatch` is provided as a go module and requires go \u003e= 1.18.\n\n```shell\ngo get github.com/halimath/globwatch@main\n```\n\n# Usage\n\n## Creating a Watcher\n\n`globwatch` provides a `Watcher` that can be created using the `New` function.\nThe function receives a `fs.FS` handle to watch, a pattern (see below) and\na check interval.\n\nOnce a `Watcher` has been created, you can start the watch routine by invoking\n`Start` or `StartContext`. The second function expects a `context.Context`\nthat - when done - causes the watcher to terminate. Otherwise you can invoke\n`Close` to finish watching. Once finished a `Watcher` cannot be restarted.\n\n```go\nwatcher, err := globwatch.New(fsys, \"**/*_test.go\", time.Millisecond)\nif err != nil {\n    // ...\n}\n\nif err := watcher.Start(); err != nil {\n    // ...\n}\n\n// ..\n\nwatcher.Close()\n```\n\n## Receiving changes\n\nA `Watcher` communicates changes via a channel. The channel is available via\nthe `C` method.\n\n```go\nfor e := range watcher.C() {\n    fmt.Printf(\"%8s %s\\n\", e.Type, e.Path)\n}\n```\n\nIn addition you can subscribe for errors by reading from an `error`s channel\navailable via the `ErrorsChan` method.\n\n## Pattern format\n\nThe pattern format used by `globwatch` works similar to the \n[pattern format of `.gitignore`](https://git-scm.com/docs/gitignore). It is\ncompletely compatible with the pattern format used by `os.Glob` or `fs.Glob`\nand extends it.\n\nThe format is specified as the following EBNF:\n\n```ebnf\npattern = term, { '/', term };\n\nterm        = '**' | name;\nname        = { charSpecial | group | escapedChar | '*' | '?' };\ncharSpecial = (* any unicode rune except '/', '*', '?', '[' and '\\' *);\nchar        = (* any unicode rune *);\nescapedChar = '\\\\', char;\ngroup       = '[', [ '^' ] { escapedChar | groupChar | range } ']';\ngroupChar   = (* any unicode rune except '-' and ']' *);\nrange       = ( groupChar | escapedChar ), '-', (groupChar | escapedChar);\n```\n\nThe format operators have the following meaning:\n\n* any character (rune) matches the exactly this rune - with the following\n  exceptions\n* `/` works as a directory separator. It matches directory boundarys of the\n  underlying system independently of the separator char used by the OS.\n* `?` matches exactly one non-separator char\n* `*` matches any number of non-separator chars - including zero\n* `\\` escapes a character's special meaning allowing `*` and `?` to be used\n  as regular characters.\n* `**` matches any number of nested directories. If anything is matched it\n  always extends until a separator or the end of the name.\n* Groups can be defined using the `[` and `]` characters. Inside a group the\n  special meaning of the characters mentioned before is disabled but the\n  following rules apply\n    * any character used as part of the group acts as a choice to pick from\n    * if the group's first character is a `^` the whole group is negated\n    * a range can be defined using `-` matching any rune between low and high\n      inclusive\n    * Multiple ranges can be given. Ranges can be combined with choices.\n    * The meaning of `-` and `]` can be escacped using `\\`\n\n# Performance\n\n`globwatch` separates pattern parsing and matching. This can create a \nperformance benefit when applied repeatedly. When reusing a precompiled pattern\nto match filenames `globwatch` outperforms `filepath.Match` with both simple\nand complex patterns. When not reusing the parsed pattern, `filepath` works\nmuch faster (but lacks the additional features).\n\nTest | Execution time `[ns/op]` | Memory usage `[B/op]` | Allocations per op\n-- | --: | --: | --:\n`filepath` simple pattern                        |   15.5 | 0    | 0\n`globwatch` simple pattern (reuse)               |    3.9 | 0    | 0\n`globwatch` simple pattern (noreuse)             |  495.0 | 1112 | 5\n`filepath` complex pattern                       |  226.2 |    0 | 0\n`globwatch` complex pattern (reuse)              |  108.1 |    0 | 0\n`globwatch` complex pattern (noreuse)            | 1103.0 | 2280 | 8\n`globwatch` directory wildcard pattern (reuse)   |  111.7 |    0 | 0\n`globwatch` directory wildcard pattern (noreuse) | 1229.0 | 2280 | 8\n\n# License\n\nCopyright 2022 Alexander Metzner.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhalimath%2Fglobwatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhalimath%2Fglobwatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhalimath%2Fglobwatch/lists"}