file-tail 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2cf544dbe9b55dc5369593f301c270154af027cdafa4ebfe69425f0384fcc320
4
- data.tar.gz: 877cb588d7acd10fbe1c59672fc609c17dc1fd29eda5b3091c79f2f1791bc96f
3
+ metadata.gz: 8fcbea1582da9d2d6ce23fc0826608abf44625e90577916288001461593c2e0a
4
+ data.tar.gz: '0780cfca7c7d53f9a005ac2e1035daa249a758eab32a3b29aefb4142bd624127'
5
5
  SHA512:
6
- metadata.gz: dbef35840950052d1a944812a0fc161f8a9bad1111d8062091a4b0098408eb34b051fb3dce02a0c44c0f2a4e5ff2b4e88aeefd1301f56e6084cc70a6a578e9f2
7
- data.tar.gz: e7fa4e45186734548b327177d3fa44cbc2b214a02cf716f2de589e6d6bf6b83d4fba5e229b765c127d11a9cad87fd92d4f1dcf4813ebd82ea7b2ec6c1acedfa0
6
+ metadata.gz: adeee1b62fe358f4e8f3ae1f13127b6b94e741e9520f94611bff8e4f1083f5ccbb5a0fbb3e8d9a6e68281e12231304b8cb24de644b7c062c3db76e9062ca4589
7
+ data.tar.gz: a9057bdfb9b771c1ee58cda13ea0f7639b2ff1b599b5628f5815060f52063d1ee354cd2dfd2368b96add7da4a0cdad3447c6622ed45bcc95a7f8926c8168fd46
data/.all_images.yml CHANGED
@@ -1,27 +1,19 @@
1
1
  dockerfile: |-
2
- RUN apk add --no-cache build-base git bash
3
- RUN bash <<NUR
4
- if [[ "$(ruby -e 'print RUBY_VERSION')" > '3' ]]
5
- then
6
- gem update --system
7
- gem install gem_hadar bundler
8
- else
9
- gem install gem_hadar
10
- gem install bundler -v 2.4.22
11
- fi
12
- NUR
2
+ RUN apk add --no-cache build-base yaml-dev git openssl-dev
3
+
13
4
  fail_fast: true
5
+
14
6
  script: &script |-
15
7
  echo -e "\e[1m"
16
8
  ruby -v
17
9
  echo -e "\e[0m"
18
- bundle install
10
+ bundle update --all
11
+ bundle install --jobs=$(getconf _NPROCESSORS_ONLN)
19
12
  rake test
20
13
 
21
14
  images:
15
+ ruby:4.0-alpine: *script
16
+ ruby:3.4-alpine: *script
22
17
  ruby:3.3-alpine: *script
23
18
  ruby:3.2-alpine: *script
24
19
  ruby:3.1-alpine: *script
25
- ruby:3.0-alpine: *script
26
- ruby:2.7-alpine: *script
27
- ruby:2.6-alpine: *script
@@ -0,0 +1,51 @@
1
+ # Simple workflow for deploying static content to GitHub Pages
2
+ name: Deploy static content to Pages
3
+
4
+ on:
5
+ # Runs on pushes targeting the default branch
6
+ push:
7
+ branches: [ "master" ]
8
+
9
+ # Allows you to run this workflow manually from the Actions tab
10
+ workflow_dispatch:
11
+
12
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13
+ permissions:
14
+ contents: read
15
+ pages: write
16
+ id-token: write
17
+
18
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19
+ # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20
+ concurrency:
21
+ group: "pages"
22
+ cancel-in-progress: false
23
+
24
+ jobs:
25
+ # Single deploy job since we're just deploying
26
+ deploy:
27
+ environment:
28
+ name: github-pages
29
+ url: ${{ steps.deployment.outputs.page_url }}
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Checkout
33
+ uses: actions/checkout@v4
34
+ - name: Setup Pages
35
+ uses: actions/configure-pages@v5
36
+ - name: Setup Ruby
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: '3.4'
40
+ - name: Generate Documentation
41
+ run: |
42
+ gem install gem_hadar
43
+ bundle install
44
+ rake doc
45
+ - name: Upload artifact
46
+ uses: actions/upload-pages-artifact@v3
47
+ with:
48
+ path: 'doc'
49
+ - name: Deploy to GitHub Pages
50
+ id: deployment
51
+ uses: actions/deploy-pages@v4
data/.gitignore CHANGED
@@ -4,7 +4,9 @@
4
4
  .bundle
5
5
  .rbx
6
6
  .utilsrc
7
+ .yardoc
7
8
  Gemfile.lock
8
9
  coverage
9
10
  errors.lst
10
11
  pkg
12
+ tmp
data/CHANGES.md CHANGED
@@ -1,33 +1,63 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-01-02 v1.4.0
4
+
5
+ - Enhanced file reopening logic to handle `Errno::ENOENT` and `Errno::ESTALE`
6
+ errors separately, preventing line skipping during file rotation
7
+ - Fixed buffer size parameter passing and cleaned up the close block
8
+ - Added nil safety check for `@out.path` before removing temporary files
9
+ - Updated gemspec to include the `LICENSE` file and added a GitHub Actions
10
+ workflow
11
+ - Replaced the old documentation in README with a comprehensive architecture
12
+ overview, usage examples, and debugging sections
13
+ - Added automated documentation deployment workflow using GitHub Actions with
14
+ Ruby **3.4** environment
15
+ - Removed unnecessary `t =` assignment for thread in `rtail` binary
16
+ - Removed support for Ruby **3.0** Alpine image in CI configuration
17
+ - Renamed `COPYING` file to `LICENSE` for better standard compliance
18
+ - Added `.yardoc` to gitignore and rake ignore list
19
+ - Updated test file path to use the `tmp` directory for better test
20
+ organization
21
+ - Added `tmp` directory to gitignore, gemspec, and git tracking with
22
+ `tmp/.gitkeep`
23
+ - Updated CI image configuration to support Ruby **4.0** with `yaml-dev` and
24
+ `openssl-dev` dependencies
25
+ - Updated gem metadata and dependencies, including `rubygems_version` to
26
+ **4.0.2** and `gem_hadar` development dependency to **>= 2.16.3**
27
+ - Added changelog generation support to the Rakefile for automated changelog
28
+ management
29
+ - Updated Dockerfile dependencies for Ruby version detection and added Ruby
30
+ **3.4**-alpine image support
31
+ - Fixed typos in the codebase
32
+
3
33
  ## 2024-09-13 v1.3.0
4
34
 
5
35
  ### Significant Changes
6
36
 
7
37
  * **Improved waiting for log output by counting lines**
8
- + Increased timeout from 2 seconds to 10 seconds in multiple places
38
+ + Increased timeout from 2 seconds to 10 seconds in multiple places
9
39
  * **Added Ruby version check in Dockerfile**
10
- + Update `gem update --system` and installation to be conditional on Ruby version
11
- + Replace `bundle` with `bundle install` in script section
40
+ + Update `gem update --system` and installation to be conditional on Ruby version
41
+ + Replace `bundle` with `bundle install` in script section
12
42
  * **Convert CHANGES file to CHANGES\.md**
13
43
 
14
44
  ### Bug Fixes
15
45
 
16
46
  * **Add exit handler to delete temporary file**
17
- - Added at_exit block to delete test file created in setup method.
47
+ - Added at_exit block to delete test file created in setup method.
18
48
  * **Refactor File class for debugging**
19
- - Remove hardcoded `$DEBUG` variable usage in reopen_file and output_debug_information methods
20
- - Introduce debug? method to check if `FILE_TAIL_DEBUG` environment variable is set to 1.
49
+ - Remove hardcoded `$DEBUG` variable usage in reopen_file and output_debug_information methods
50
+ - Introduce debug? method to check if `FILE_TAIL_DEBUG` environment variable is set to 1.
21
51
 
22
52
  ### Dependency Updates
23
53
 
24
54
  * **Update Ruby dependencies and add new development dependencies**
25
- + Added `.all_images.yml` file with Dockerfile configuration
26
- + Updated Gemfile to use Ruby **3.5.18** instead of **2.7.8**
27
- + Updated Rakefile to ignore additional files
28
- + Updated `file-tail.gemspec` to include `.all_images.yml` in the list of files
29
- + Updated `tests/file_tail_test.rb` to use absolute path for test file
30
- + Added new development dependencies: `all_images`, `simplecov`, and `debug`
55
+ + Added `.all_images.yml` file with Dockerfile configuration
56
+ + Updated Gemfile to use Ruby **3.5.18** instead of **2.7.8**
57
+ + Updated Rakefile to ignore additional files
58
+ + Updated `file-tail.gemspec` to include `.all_images.yml` in the list of files
59
+ + Updated `tests/file_tail_test.rb` to use absolute path for test file
60
+ + Added new development dependencies: `all_images`, `simplecov`, and `debug`
31
61
  + Updated dependency versions: `gem_hadar` to **1.17.1**, `test-unit` to
32
62
  **3.0**, and `tins` to **1.0**
33
63
 
data/README.md CHANGED
@@ -5,69 +5,308 @@
5
5
  This is a small ruby library that allows it to "tail" files in Ruby, including
6
6
  following a file, that still is growing like the unix command 'tail -f' can.
7
7
 
8
- ## Download
8
+ ## Documentation
9
9
 
10
- The latest version of *File::Tail* (file-tail) can be found at
10
+ Complete API documentation is available at: [GitHub.io](https://flori.github.io/file-tail/)
11
+
12
+ ## Architecture Overview
13
+
14
+ File::Tail follows a well-defined architectural pattern with clear
15
+ separation of concerns between several key components:
11
16
 
17
+ ### Core Components
12
18
 
13
- http://flori.github.com/file-tail
19
+ **File::Tail Module**
20
+ - The central hub extending File objects with tailing capabilities 🔄
21
+ - Provides core methods for forward/backward traversal and tailing 📊
22
+ - Handles file system events like rotation, truncation, and deletion 🔁
23
+
24
+ **File::Tail::Logfile**
25
+ - A convenience class that simplifies opening and tailing files with options 🚀
26
+ - Includes File::Tail module for direct file access 🧠
27
+ - Supports various initialization patterns for flexible usage 🔄
28
+
29
+ **File::Tail::Group**
30
+ - Manages multiple files to be tailed together 🔄
31
+ - Uses ThreadGroup to coordinate multiple tailing threads ⏳
32
+ - Provides batch operations for concurrent file monitoring 📊
33
+
34
+ **File::Tail::Tailer**
35
+ - A Thread subclass that supervises a single file's tailing 🧠
36
+ - Uses queues for line buffering and thread-safe communication 📦
37
+ - Implements method_missing for thread-local variable access ⚡
38
+
39
+ ### Component Interactions
40
+
41
+ ```mermaid
42
+ graph LR
43
+ A[File::Tail] --> B[File::Tail::Logfile]
44
+ A --> C[File::Tail::Group]
45
+ C --> D[File::Tail::Tailer]
46
+ D --> E[Thread]
47
+ A --> F[File::Tail::LineExtension]
48
+ F --> G[Lines from tailers]
49
+ ```
50
+
51
+ The File::Tail module acts as the foundation, providing core functionality that
52
+ is extended by Logfile and Group classes. The Group class coordinates multiple
53
+ Tailer threads, each managing a single file's tailing process.
54
+
55
+ ### Loading Mechanism
56
+
57
+ File::Tail supports two primary access patterns:
58
+
59
+ 1. **Direct File Extension** - Extending File objects directly with File::Tail:
60
+ ```ruby
61
+ File.open(filename) do |log|
62
+ log.extend(File::Tail)
63
+ log.backward(10)
64
+ log.tail { |line| puts line }
65
+ end
66
+ ```
67
+
68
+ 2. **Logfile Convenience Class** - Using the Logfile wrapper for simpler usage:
69
+ ```ruby
70
+ File::Tail::Logfile.tail('app.log', :backward => 10) do |line|
71
+ puts line
72
+ end
73
+ ```
14
74
 
15
75
  ## Installation
16
76
 
17
77
  To install file-tail via its gem type:
18
78
 
19
- # gem install file-tail
79
+ ```bash
80
+ gem install file-tail
81
+ ```
82
+
83
+ You can also put this line into your Gemfile:
84
+
85
+ ```ruby
86
+ gem 'file-tail'
87
+ ```
88
+
89
+ and bundle. This will make the File::Tail module available for extending File objects.
20
90
 
21
91
  ## Usage
22
92
 
23
93
  File::Tail is a module in the File class. A lightweight class interface for
24
94
  logfiles can be seen under File::Tail::Logfile.
25
95
 
26
- Direct extension of File objects with File::Tail works like that:
96
+ ### Direct Extension of File Objects
97
+
98
+ ```ruby
99
+ File.open(filename) do |log|
100
+ log.extend(File::Tail)
101
+ log.interval # 10
102
+ log.backward(10)
103
+ log.tail { |line| puts line }
104
+ end
105
+ ```
106
+
107
+ It's also possible to mix File::Tail in your own File classes (see also File::Tail::Logfile):
27
108
 
28
- File.open(filename) do |log|
29
- log.extend(File::Tail)
30
- log.interval # 10
31
- log.backward(10)
32
- log.tail { |line| puts line }
33
- end
109
+ ```ruby
110
+ class MyFile < File
111
+ include File::Tail
112
+ end
113
+ log = MyFile.new("myfile")
114
+ log.interval # 10
115
+ log.backward(10)
116
+ log.tail { |line| print line }
117
+ ```
34
118
 
35
- It's also possible to mix File::Tail in your own File classes
36
- (see also File::Tail::Logfile):
119
+ The forward/backward method returns self, so it's possible to chain methods together like that:
37
120
 
38
- class MyFile < File
39
- include File::Tail
40
- end
41
- log # MyFile.new("myfile")
42
- log.interval # 10
43
- log.backward(10)
44
- log.tail { |line| print line }
121
+ ```ruby
122
+ log.backward(10).tail { |line| puts line }
123
+ ```
45
124
 
46
- The forward/backward method returns self, so it's possible to chain
47
- methods together like that:
125
+ ### Multiple File Tailing with Group
48
126
 
49
- log.backward(10).tail { |line| puts line }
127
+ ```ruby
128
+ group = File::Tail::Group.new
129
+ group.add_filename('app.log')
130
+ group.add_filename('error.log')
131
+ group.tail { |line| puts line }
132
+ ```
50
133
 
51
- A command line utility named rtail, that uses File::Tail is provided as well.
134
+ ### Advanced Usage with Callbacks
135
+
136
+ ```ruby
137
+ log = File::Tail::Logfile.open('app.log')
138
+ log.after_reopen { |file| puts "File reopened: #{file.path}" }
139
+ log.tail { |line| puts line }
140
+ ```
141
+
142
+ ### Backward Traversal
143
+
144
+ ```ruby
145
+ # Tail last 10 lines of file
146
+ File::Tail::Logfile.open('app.log', :backward => 10) do |log|
147
+ log.tail { |line| puts line }
148
+ end
149
+
150
+ # Skip first 5 lines and tail
151
+ File::Tail::Logfile.open('app.log', :forward => 5) do |log|
152
+ log.tail { |line| puts line }
153
+ end
154
+ ```
52
155
 
53
156
  ## Documentation
54
157
 
55
158
  To create the documentation of this module, type
56
159
 
57
- ```
160
+ ```bash
58
161
  $ rake doc
59
162
  ```
60
163
 
61
164
  and the API documentation is generated.
62
165
 
63
- In the examples direcotry is a small example of tail and
166
+ In the examples directory is a small example of tail and
64
167
  pager program that use this module. You also may want look
65
168
  at the end of examples/tail.rb for a little example.
66
169
 
170
+ ## Debugging and Troubleshooting
171
+
172
+ File::Tail provides built-in debugging capabilities through environment variables:
173
+
174
+ ### Enabling Debug Output
175
+
176
+ Set the `FILE_TAIL_DEBUG` environment variable to enable detailed debugging information:
177
+
178
+ ```bash
179
+ export FILE_TAIL_DEBUG=1
180
+ ruby your_tail_script.rb
181
+ ```
182
+
183
+ This will output information about:
184
+ - File paths being tailed
185
+ - Line counts and intervals
186
+ - Reopening events
187
+ - Sleep intervals and timing
188
+
189
+ ### Exception Handling
190
+
191
+ File::Tail defines several specific exceptions for different failure scenarios:
192
+
193
+ ```ruby
194
+ begin
195
+ log.tail { |line| puts line }
196
+ rescue File::Tail::DeletedException
197
+ # Handle file deletion
198
+ rescue File::Tail::ReopenException
199
+ # Handle file rotation/reopening
200
+ rescue File::Tail::BreakException
201
+ # Handle end-of-file with break_if_eof set
202
+ rescue File::Tail::ReturnException
203
+ # Internal exception for controlling tailing behavior
204
+ end
205
+ ```
206
+
207
+ ## Configuration
208
+
209
+ ### Key Attributes
210
+
211
+ File::Tail provides several configurable attributes for fine-tuning behavior:
212
+
213
+ ```ruby
214
+ log = File::Tail::Logfile.open('app.log')
215
+ log.interval = 1.0 # Initial sleep interval (default: 10)
216
+ log.max_interval = 5.0 # Maximum sleep interval (default: 10)
217
+ log.reopen_deleted = true # Reopen deleted files (default: true)
218
+ log.reopen_suspicious = true # Reopen on suspicious events (default: true)
219
+ log.suspicious_interval = 60 # Interval before suspicious event detection (default: 60)
220
+ log.break_if_eof = false # Break on EOF (default: false)
221
+ log.return_if_eof = false # Return on EOF (default: false)
222
+ ```
223
+
224
+ ### Advanced Configuration
225
+
226
+ ```ruby
227
+ # Configure for high-traffic logs
228
+ log.interval = 0.1
229
+ log.max_interval = 1.0
230
+ log.suspicious_interval = 30
231
+
232
+ # Configure for low-traffic logs
233
+ log.interval = 5.0
234
+ log.max_interval = 30.0
235
+ log.suspicious_interval = 120
236
+ ```
237
+
238
+ ## Performance Considerations
239
+
240
+ ### Thread Safety
241
+
242
+ File::Tail uses thread-safe mechanisms for concurrent file monitoring:
243
+ - ThreadGroup for managing tailer threads
244
+ - Mutex and ConditionVariable for synchronization
245
+ - Queue-based line buffering for thread communication
246
+
247
+ ### Memory Management
248
+
249
+ The library implements efficient memory usage:
250
+ - Lines are buffered in queues per tailer
251
+ - Exponential backoff reduces CPU usage when files are quiet
252
+ - Proper thread lifecycle management prevents resource leaks
253
+
254
+ ### File System Event Handling
255
+
256
+ File::Tail gracefully handles various file system events:
257
+ - File rotation (log rotation)
258
+ - File truncation
259
+ - File deletion
260
+ - File reopening after deletion
261
+
262
+ ## Error Handling
263
+
264
+ File::Tail provides comprehensive error handling for common file system scenarios:
265
+
266
+ ### File::Tail Exception Hierarchy
267
+
268
+ ```mermaid
269
+ classDiagram
270
+ class TailException {
271
+ <<abstract>>
272
+ +message
273
+ }
274
+
275
+ class DeletedException
276
+ class ReturnException
277
+ class BreakException
278
+ class ReopenException
279
+
280
+ TailException <|-- DeletedException
281
+ TailException <|-- ReturnException
282
+ TailException <|-- BreakException
283
+ TailException <|-- ReopenException
284
+ ```
285
+
286
+ ### Safe Usage Pattern
287
+
288
+ ```ruby
289
+ def safe_tail(filename)
290
+ File::Tail::Logfile.open(filename) do |log|
291
+ log.tail { |line| puts line }
292
+ rescue File::Tail::DeletedException
293
+ puts "File was deleted, stopping tailing"
294
+ rescue File::Tail::ReopenException
295
+ puts "File reopened, continuing tailing"
296
+ end
297
+ end
298
+ ```
299
+
300
+ ## Download
301
+
302
+ The latest version of *File::Tail* (file-tail) can be found at
303
+
304
+ https://github.com/flori/file-tail
305
+
67
306
  ## Author
68
307
 
69
308
  Florian Frank mailto:flori@ping.de
70
309
 
71
310
  ## License
72
311
 
73
- Apache License, Version 2.0 See the COPYING file in the source archive.
312
+ This software is licensed under the [Apache 2.0 license](LICENSE).
data/Rakefile CHANGED
@@ -12,10 +12,18 @@ GemHadar do
12
12
  description 'Library to tail files in Ruby'
13
13
  test_dir 'tests'
14
14
  ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '*.rbc', '.rbx',
15
- '.AppleDouble', '.bundle', 'errors.lst', '.utilsrc'
15
+ '.AppleDouble', '.bundle', 'errors.lst', '.utilsrc', 'tmp', '.yardoc'
16
16
  readme 'README.md'
17
17
  licenses << 'Apache-2.0'
18
18
 
19
+ changelog do
20
+ filename 'CHANGES.md'
21
+ end
22
+
23
+ github_workflows(
24
+ 'static.yml' => {}
25
+ )
26
+
19
27
  dependency 'tins', '~>1.0'
20
28
 
21
29
  development_dependency 'test-unit', '~>3.0'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.4.0
data/bin/rtail CHANGED
@@ -39,7 +39,7 @@ end
39
39
 
40
40
  add_logfiles logfiles
41
41
 
42
- t = Thread.new do
42
+ Thread.new do
43
43
  $logfiles.tail do |line|
44
44
  if $opt['M']
45
45
  puts "#{line.file.path}: #{line}"
data/file-tail.gemspec CHANGED
@@ -1,28 +1,28 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: file-tail 1.3.0 ruby lib
2
+ # stub: file-tail 1.4.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "file-tail".freeze
6
- s.version = "1.3.0".freeze
6
+ s.version = "1.4.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Florian Frank".freeze]
11
- s.date = "2024-09-13"
11
+ s.date = "1980-01-02"
12
12
  s.description = "Library to tail files in Ruby".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.extra_rdoc_files = ["README.md".freeze, "lib/file-tail.rb".freeze, "lib/file/tail.rb".freeze, "lib/file/tail/group.rb".freeze, "lib/file/tail/line_extension.rb".freeze, "lib/file/tail/logfile.rb".freeze, "lib/file/tail/tailer.rb".freeze, "lib/file/tail/version.rb".freeze]
15
- s.files = [".all_images.yml".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/rtail".freeze, "examples/pager.rb".freeze, "examples/tail.rb".freeze, "file-tail.gemspec".freeze, "lib/file-tail.rb".freeze, "lib/file/tail.rb".freeze, "lib/file/tail/group.rb".freeze, "lib/file/tail/line_extension.rb".freeze, "lib/file/tail/logfile.rb".freeze, "lib/file/tail/tailer.rb".freeze, "lib/file/tail/version.rb".freeze, "tests/file_tail_group_test.rb".freeze, "tests/file_tail_test.rb".freeze, "tests/test_helper.rb".freeze]
15
+ s.files = [".all_images.yml".freeze, ".github/workflows/static.yml".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/rtail".freeze, "examples/pager.rb".freeze, "examples/tail.rb".freeze, "file-tail.gemspec".freeze, "lib/file-tail.rb".freeze, "lib/file/tail.rb".freeze, "lib/file/tail/group.rb".freeze, "lib/file/tail/line_extension.rb".freeze, "lib/file/tail/logfile.rb".freeze, "lib/file/tail/tailer.rb".freeze, "lib/file/tail/version.rb".freeze, "tests/file_tail_group_test.rb".freeze, "tests/file_tail_test.rb".freeze, "tests/test_helper.rb".freeze, "tmp/.gitkeep".freeze]
16
16
  s.homepage = "http://github.com/flori/file-tail".freeze
17
17
  s.licenses = ["Apache-2.0".freeze]
18
18
  s.rdoc_options = ["--title".freeze, "File-tail - File::Tail for Ruby".freeze, "--main".freeze, "README.md".freeze]
19
- s.rubygems_version = "3.5.18".freeze
19
+ s.rubygems_version = "4.0.2".freeze
20
20
  s.summary = "File::Tail for Ruby".freeze
21
21
  s.test_files = ["tests/file_tail_group_test.rb".freeze, "tests/file_tail_test.rb".freeze, "tests/test_helper.rb".freeze]
22
22
 
23
23
  s.specification_version = 4
24
24
 
25
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.17.1".freeze])
25
+ s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.16.3".freeze])
26
26
  s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.0".freeze])
27
27
  s.add_development_dependency(%q<all_images>.freeze, [">= 0".freeze])
28
28
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
@@ -51,7 +51,7 @@ class File
51
51
  end
52
52
  if backward = opts[:backward] || opts[:rewind]
53
53
  (args = []) << backward
54
- args << opt[:bufsiz] if opts[:bufsiz]
54
+ args << opts[:bufsiz] if opts[:bufsiz]
55
55
  file.backward(*args)
56
56
  elsif forward = opts[:forward] || opts[:wind]
57
57
  file.forward(forward)
@@ -64,7 +64,6 @@ class File
64
64
  block.call file
65
65
  ensure
66
66
  file.close
67
- nil
68
67
  end
69
68
  else
70
69
  file
@@ -1,6 +1,6 @@
1
1
  module File::Tail
2
2
  # File::Tail version
3
- VERSION = '1.3.0'
3
+ VERSION = '1.4.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/lib/file/tail.rb CHANGED
@@ -17,7 +17,7 @@ class File
17
17
  class DeletedException < TailException; end
18
18
 
19
19
  # The ReturnException is raised and caught
20
- # internally to implement "tail -10" behaviour.
20
+ # internally to implement "tail -10" behavior.
21
21
  class ReturnException < TailException; end
22
22
 
23
23
  # The BreakException is raised if the <code>break_if_eof</code>
@@ -26,7 +26,7 @@ class File
26
26
  class BreakException < TailException; end
27
27
 
28
28
  # The ReopenException is raised internally if File::Tail
29
- # gets suspicious something unusual has happend to
29
+ # gets suspicious something unusual has happened to
30
30
  # the tailed file, e. g., it was rotated away. The exception
31
31
  # is caught and an attempt to reopen it is made.
32
32
  class ReopenException < TailException
@@ -66,14 +66,14 @@ class File
66
66
  attr_accessor :reopen_suspicious
67
67
 
68
68
  # The callback is called with _self_ as an argument after a reopen has
69
- # occured. This allows a tailing script to find out, if a logfile has been
70
- # rotated.
69
+ # occurred. This allows a tailing script to find out, if a logfile has
70
+ # been rotated.
71
71
  def after_reopen(&block)
72
72
  @after_reopen = block
73
73
  end
74
74
 
75
- # This attribute is the invterval in seconds before File::Tail
76
- # gets suspicious that something has happend to it's tailed file
75
+ # This attribute is the interval in seconds before File::Tail
76
+ # gets suspicious that something has happened to it's tailed file
77
77
  # and an attempt to reopen it is made.
78
78
  #
79
79
  # If the attribute <code>reopen_suspicious</code> is
@@ -241,16 +241,18 @@ class File
241
241
  if @stat
242
242
  if stat.ino != @stat.ino or stat.dev != @stat.dev
243
243
  @stat = nil
244
- raise ReopenException.new(:top)
244
+ raise ReopenException.new(:top) # File ino/dev has changed, start from top
245
245
  end
246
246
  if stat.size < @stat.size
247
247
  @stat = nil
248
- raise ReopenException.new(:top)
248
+ raise ReopenException.new(:top) # File shrunk, start from top
249
249
  end
250
250
  end
251
251
  @stat = stat
252
- rescue Errno::ENOENT, Errno::ESTALE
253
- raise ReopenException
252
+ rescue Errno::ENOENT
253
+ raise ReopenException.new(:top) # File was missing, maybe it has been rotated, start from top
254
+ rescue Errno::ESTALE
255
+ raise ReopenException # File is stale let's try opening again with same mo
254
256
  end
255
257
 
256
258
  def sleep_interval
@@ -12,8 +12,8 @@ class FileTailTest < Test::Unit::TestCase
12
12
  include FileUtils
13
13
 
14
14
  def setup
15
- @out = File.new(File.join(__dir__, "test.#$$"), "wb")
16
- at_exit { rm_f File.expand_path(@out.path) }
15
+ @out = File.new(File.join('tmp', "test.#$$"), "wb")
16
+ at_exit { path = @out&.path and rm_f File.expand_path(path) }
17
17
  append(@out, 100)
18
18
  @in = File.new(@out.path, "rb")
19
19
  @in.extend(File::Tail)
data/tmp/.gitkeep ADDED
File without changes
metadata CHANGED
@@ -1,29 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: file-tail
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-09-13 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: gem_hadar
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - "~>"
16
+ - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 1.17.1
18
+ version: 2.16.3
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
- - - "~>"
23
+ - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: 1.17.1
25
+ version: 2.16.3
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: test-unit
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -109,11 +108,12 @@ extra_rdoc_files:
109
108
  - lib/file/tail/version.rb
110
109
  files:
111
110
  - ".all_images.yml"
111
+ - ".github/workflows/static.yml"
112
112
  - ".gitignore"
113
113
  - ".travis.yml"
114
114
  - CHANGES.md
115
- - COPYING
116
115
  - Gemfile
116
+ - LICENSE
117
117
  - README.md
118
118
  - Rakefile
119
119
  - VERSION
@@ -131,11 +131,11 @@ files:
131
131
  - tests/file_tail_group_test.rb
132
132
  - tests/file_tail_test.rb
133
133
  - tests/test_helper.rb
134
+ - tmp/.gitkeep
134
135
  homepage: http://github.com/flori/file-tail
135
136
  licenses:
136
137
  - Apache-2.0
137
138
  metadata: {}
138
- post_install_message:
139
139
  rdoc_options:
140
140
  - "--title"
141
141
  - File-tail - File::Tail for Ruby
@@ -154,8 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  - !ruby/object:Gem::Version
155
155
  version: '0'
156
156
  requirements: []
157
- rubygems_version: 3.5.18
158
- signing_key:
157
+ rubygems_version: 4.0.2
159
158
  specification_version: 4
160
159
  summary: File::Tail for Ruby
161
160
  test_files:
File without changes