agent-lock 0.2.1 → 2.1.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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +15 -4
- data/lib/agent/lock/cli.rb +28 -0
- data/lib/agent/lock/launcher.rb +0 -30
- data/lib/agent/lock/store/redis_store.rb +54 -6
- data/lib/agent/lock/store.rb +4 -2
- data/lib/agent/lock/version.rb +1 -1
- metadata +50 -11
- data/.envrc +0 -2
- data/.rubocop_todo.yml +0 -90
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d1f106a6394f81598c390390a2d83aeb051b9e22d799c23129eeed6aba0f0822
|
|
4
|
+
data.tar.gz: d31b63c4c1469eee913e33ca102dcb35f108d7b1aabb24408ec8bdd8b92958d4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a947455256070a8bc2eb2211f63fdcc970b64e25d479ed57724ac17dbd39a28c4317fcf28465fa91b58942f4a24231af72190c34519640c905c4e04a254b38a
|
|
7
|
+
data.tar.gz: ce09be390c7cbbd93315e7b359fd30efbb53fb064d8b98b849fcb8e3fa59756fb85eec0c46b0c23d837aa87aa5d815d726c152bf4be56f44d48163eaa402310d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [2.1.0]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Help screens come from `dry-cli-help`: `alock -h` now opens with the gem's title and a description of what it does and how the two backends are chosen, lists commands in registration order, and wraps everything at 85 columns. The hand-written backend banner that used to print above dry-cli's own help is gone.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Finding a Redis now cascades: `REDIS_URL` is tried first when it is set, then `redis://127.0.0.1:6379/0`, and only when neither answers does a virgin tree default to the file store. Previously `REDIS_URL` replaced the local default rather than preceding it, so a shared Redis being down sent the tree straight to the filesystem even with one running locally. `RedisStore.url` now reports the URL that actually answered.
|
|
14
|
+
|
|
5
15
|
## [0.2.0]
|
|
6
16
|
|
|
7
17
|
### Added
|
data/README.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
# Agent::Lock (
|
|
1
|
+
# Agent::Lock (v2.0.1)
|
|
2
2
|
|
|
3
3
|
[](https://github.com/kigster/agent-lock/actions/workflows/main.yml)
|
|
4
4
|
|
|
5
|
-
Advisory file
|
|
5
|
+
Advisory locks on files and folders with pluggable backends (redis and file-system provided out the box, with redis being the default if it's available locally). This locking tool is meant to be used by the coding agents that share a checkout.
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
>
|
|
9
|
+
> Please note that `agent-lock` is part of a three-part system:
|
|
10
|
+
>
|
|
11
|
+
> 1. `agentilda` is the Ruby Gem, which is a CLI tool that creates and manages the `.plans` folder, and comes with eight or so specialized agents that take a spec.md file and work through it until it's a set of PRs open, reviewed, and passing on your CI. It does not automatically merge anything.
|
|
12
|
+
> 2. [`agentilda-ai-setup`](https://kigster/agentilda-ai-setup) is the GitHub repo that's a mixture of BASH and Ruby installers. It's comes with the [`configuration.yml`](https://github.com/kigster/agentilda-ai-setup/blob/main/configuration.example.yml) file, which lists the installation commands for the coding agents you'd like to install locally, any other executables you might want (for instance, it installs `bt` — braintrust's CLI utility), and then you can list any number of Github Repos and use them to install skills, plugins, commands from them, specifying exactly which you want to install and which you want to exclude. Moreover you can specify a sub-directory of a github repo to install from.
|
|
13
|
+
>
|
|
14
|
+
> Together, the three repos, after installation provide you with the consistent way to replicate your `~/.agents` and `~/.claude` folders on multiple computers, and to also replicate a consistent agentic software team workflow across many projects.
|
|
6
15
|
|
|
7
16
|
## What it is
|
|
8
17
|
|
|
@@ -316,11 +325,13 @@ Names every command and flag `alock` currently knows, since the script is genera
|
|
|
316
325
|
| `AGENT_LOCK_MUTEX_TIMEOUT` | `15` | Seconds a claim waits for the store's mutex before giving up with exit 2 |
|
|
317
326
|
| `AGENT_LOCK_BACKEND` | `redis` if one answers, else `file` | `file` or `redis` |
|
|
318
327
|
| `AGENT_LOCK_TTL_SECONDS` | `0` | Redis expiry. `0` means no TTL |
|
|
319
|
-
| `REDIS_URL` | `redis://127.0.0.1:6379/0`
|
|
328
|
+
| `REDIS_URL` | unset | A shared Redis, tried before `redis://127.0.0.1:6379/0` |
|
|
320
329
|
|
|
321
330
|
## Backends
|
|
322
331
|
|
|
323
|
-
Redis stores the same documents as the file store, and buys two things a filesystem cannot: its mutex holds across machines, and a TTL expires an abandoned lock without anybody having to reason about liveness. A tree defaults to Redis when one answers
|
|
332
|
+
Redis stores the same documents as the file store, and buys two things a filesystem cannot: its mutex holds across machines, and a TTL expires an abandoned lock without anybody having to reason about liveness. A tree defaults to Redis when one answers, and falls back to the file store, which needs nothing installed, when none does.
|
|
333
|
+
|
|
334
|
+
The search for a Redis runs in a fixed order: `REDIS_URL` first, when it is set, then `redis://127.0.0.1:6379/0`. A `REDIS_URL` nobody answers on is not the end of it, since the usual reason to set one is a shared instance that is occasionally down, and a local Redis is still a better lock store than the filesystem. Only when neither answers does the tree land on the file store. `alock list` names the store in use, so it is never a guess which one you are on.
|
|
324
335
|
|
|
325
336
|
```bash
|
|
326
337
|
AGENT_LOCK_BACKEND=redis alock acquire workflow/** # force it, rather than autodetect
|
data/lib/agent/lock/cli.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "manager"
|
|
4
|
+
require_relative "version"
|
|
4
5
|
require "dry/cli"
|
|
6
|
+
require "dry/cli/help"
|
|
5
7
|
|
|
6
8
|
module Agent
|
|
7
9
|
module Lock
|
|
@@ -15,6 +17,32 @@ module Agent
|
|
|
15
17
|
# line, so guessing it wrong is not a cosmetic mistake.
|
|
16
18
|
PROGRAM_NAME = "alock"
|
|
17
19
|
|
|
20
|
+
# What `alock -h` says before it lists the commands. Wrapped by
|
|
21
|
+
# dry-cli-help at HELP_WIDTH rather than the terminal's width, so the
|
|
22
|
+
# screen reads the same in a wide terminal, a narrow one, and a log.
|
|
23
|
+
HELP_WIDTH = 85
|
|
24
|
+
|
|
25
|
+
DESCRIPTION = <<~TEXT
|
|
26
|
+
Advisory locks for AI coding agents working concurrently in one checkout.
|
|
27
|
+
An agent claims the file or directory it is about to write, and every other
|
|
28
|
+
agent that checks sees who holds it and why. Nothing is enforced: the locks
|
|
29
|
+
work because every agent checks before it writes.
|
|
30
|
+
|
|
31
|
+
Locks live in one of two backends. Redis, when one answers on REDIS_URL or
|
|
32
|
+
on localhost:6379, holds across machines and can expire an abandoned lock.
|
|
33
|
+
The file store, used when no Redis answers, needs nothing installed. The
|
|
34
|
+
first process in a tree records which backend it chose, and every later
|
|
35
|
+
process in that tree stays on it. Set AGENT_LOCK_BACKEND to `redis` or
|
|
36
|
+
`file` to choose one yourself.
|
|
37
|
+
TEXT
|
|
38
|
+
|
|
39
|
+
Dry::CLI::Help.configure do
|
|
40
|
+
title "Agent Lock, Version #{Agent::Lock::VERSION}"
|
|
41
|
+
description DESCRIPTION
|
|
42
|
+
epilogue "Documentation: https://github.com/kigster/agent-lock"
|
|
43
|
+
width HELP_WIDTH
|
|
44
|
+
end
|
|
45
|
+
|
|
18
46
|
# A registry whose commands are already bound to this launcher, so a
|
|
19
47
|
# command writes to the streams it was given rather than to the process's.
|
|
20
48
|
#
|
data/lib/agent/lock/launcher.rb
CHANGED
|
@@ -70,8 +70,6 @@ module Agent
|
|
|
70
70
|
# @return [void] always exits, with 0 unless something said otherwise
|
|
71
71
|
# rubocop:disable-next Metrics/AbcSize
|
|
72
72
|
def execute!
|
|
73
|
-
backend_banner if %w[-h --help].intersect?(argv)
|
|
74
|
-
|
|
75
73
|
code = 0
|
|
76
74
|
Dry::CLI.new(CLI.registry_for(self)).call(arguments: argv, out: stdout, err: stderr)
|
|
77
75
|
rescue SystemExit => e
|
|
@@ -93,34 +91,6 @@ module Agent
|
|
|
93
91
|
def p(msg = "")
|
|
94
92
|
stdout.puts(msg)
|
|
95
93
|
end
|
|
96
|
-
|
|
97
|
-
# The two backends, ahead of dry-cli's own `--help` for each command, so
|
|
98
|
-
# a reader learns the shape of the choice before any subcommand's flags.
|
|
99
|
-
#
|
|
100
|
-
# @return [void]
|
|
101
|
-
# rubocop:disable-next Metrics/AbcSize
|
|
102
|
-
def backend_banner
|
|
103
|
-
p(bold(yellow("Agent Lock, Version #{green(Agent::Lock::VERSION)}")))
|
|
104
|
-
p
|
|
105
|
-
p(bold(blue("Usage:")))
|
|
106
|
-
p(" alock [command [ subcommand ]] [options]")
|
|
107
|
-
p
|
|
108
|
-
p(bold(blue("Description:")))
|
|
109
|
-
p(" This is a CLI utility aimed at the agents working concurrently in the same")
|
|
110
|
-
p(" environment, sharing filesystem, worktrees, etc. Agent Lock allows fine-grained")
|
|
111
|
-
p(" and effective locking, and can use multiple backends to store and maintain locks.")
|
|
112
|
-
p
|
|
113
|
-
p(cyan(" • Redis-Based Locking"))
|
|
114
|
-
p(" This mechanism uses locally running Redis instance to coordinate access to shared")
|
|
115
|
-
p(" resources (default, if Redis is available and accessible).")
|
|
116
|
-
p
|
|
117
|
-
p(cyan(" • File System Locking"))
|
|
118
|
-
p(" This mechanism uses file system locks to coordinate access to shared resources.")
|
|
119
|
-
p
|
|
120
|
-
p(" You can set the environment variable #{yellow("AGENT_LOCK_BACKEND")} to either")
|
|
121
|
-
p(" 'redis' or 'file' to override the default.")
|
|
122
|
-
p
|
|
123
|
-
end
|
|
124
94
|
end
|
|
125
95
|
end
|
|
126
96
|
end
|
|
@@ -20,10 +20,14 @@ module Agent
|
|
|
20
20
|
# markdown document either way.
|
|
21
21
|
#
|
|
22
22
|
# Picked with AGENT_LOCK_BACKEND=redis, or by default when one answers on
|
|
23
|
-
# REDIS_URL
|
|
23
|
+
# REDIS_URL, or failing that on the local default. See Store's moduledoc
|
|
24
|
+
# for how that default is decided.
|
|
24
25
|
class RedisStore
|
|
25
26
|
NAMESPACE = "agent-lock"
|
|
26
27
|
|
|
28
|
+
# Tried after REDIS_URL, or alone when it is unset.
|
|
29
|
+
LOCAL_URL = "redis://127.0.0.1:6379/0"
|
|
30
|
+
|
|
27
31
|
# How long the store mutex outlives a holder that died holding it. A
|
|
28
32
|
# claim's critical section is a SCAN and one SET, so ten seconds is
|
|
29
33
|
# somebody gone, not somebody busy.
|
|
@@ -206,15 +210,59 @@ module Agent
|
|
|
206
210
|
end
|
|
207
211
|
|
|
208
212
|
class << self
|
|
209
|
-
|
|
213
|
+
# The URL of the Redis actually in use, once one has answered, or
|
|
214
|
+
# the first one that will be tried before then.
|
|
215
|
+
#
|
|
216
|
+
# @return [String]
|
|
217
|
+
def url = @url || candidate_urls.first
|
|
218
|
+
|
|
219
|
+
# Where to look, in order: `REDIS_URL` when set, then the local
|
|
220
|
+
# default. A `REDIS_URL` that nobody answers on is not the end of
|
|
221
|
+
# the search, because the usual reason it is set is a shared
|
|
222
|
+
# instance that is sometimes down, and a local one is still better
|
|
223
|
+
# than falling all the way back to the filesystem.
|
|
224
|
+
#
|
|
225
|
+
# @return [Array<String>]
|
|
226
|
+
def candidate_urls
|
|
227
|
+
configured = ENV["REDIS_URL"].to_s.strip
|
|
228
|
+
[configured.empty? ? nil : configured, LOCAL_URL].compact.uniq
|
|
229
|
+
end
|
|
210
230
|
|
|
231
|
+
# Tries each candidate URL in turn and keeps the first that answers.
|
|
232
|
+
#
|
|
211
233
|
# @return Array[RedisClient,NilClass,Exception] the client if it could be created,
|
|
212
|
-
# or the error that prevented it
|
|
234
|
+
# or the error that prevented it (the last one tried)
|
|
213
235
|
def create_client
|
|
214
|
-
@client
|
|
215
|
-
|
|
236
|
+
return [@client, nil] if @client
|
|
237
|
+
|
|
238
|
+
error = nil
|
|
239
|
+
candidate_urls.each do |candidate|
|
|
240
|
+
client, error = connect(candidate)
|
|
241
|
+
next unless client
|
|
242
|
+
|
|
243
|
+
@url = candidate
|
|
244
|
+
@client = client
|
|
245
|
+
return [@client, nil]
|
|
216
246
|
end
|
|
217
|
-
[
|
|
247
|
+
[nil, error]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Drops the memoized client, so the next `create_client` probes again.
|
|
251
|
+
#
|
|
252
|
+
# @return [void]
|
|
253
|
+
def reset!
|
|
254
|
+
@client = nil
|
|
255
|
+
@url = nil
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
private
|
|
259
|
+
|
|
260
|
+
# @param candidate [String]
|
|
261
|
+
# @return Array[RedisClient,NilClass,Exception]
|
|
262
|
+
def connect(candidate)
|
|
263
|
+
client = ::Redis.new(url: candidate)
|
|
264
|
+
client.info["redis_version"]
|
|
265
|
+
[client, nil]
|
|
218
266
|
rescue Redis::CannotConnectError, Redis::BaseError, Errno::ECONNREFUSED, SocketError => e
|
|
219
267
|
[nil, e]
|
|
220
268
|
end
|
data/lib/agent/lock/store.rb
CHANGED
|
@@ -12,7 +12,8 @@ module Agent
|
|
|
12
12
|
#
|
|
13
13
|
# AGENT_LOCK_BACKEND wins when set. Otherwise a tree that already has a
|
|
14
14
|
# marker keeps using it. A virgin tree defaults to Redis when one answers
|
|
15
|
-
#
|
|
15
|
+
# on REDIS_URL or, failing that, on the local default; file when neither
|
|
16
|
+
# does.
|
|
16
17
|
#
|
|
17
18
|
# That default is still never a runtime auto-*switch*: once a marker
|
|
18
19
|
# exists, every later process in that tree is bound to it regardless of
|
|
@@ -90,7 +91,8 @@ module Agent
|
|
|
90
91
|
|
|
91
92
|
def marker_path(tree) = File.join(tree.store_dir, MARKER)
|
|
92
93
|
|
|
93
|
-
# @return [String] "redis" when one answers on REDIS_URL,
|
|
94
|
+
# @return [String] "redis" when one answers on REDIS_URL or, failing
|
|
95
|
+
# that, on RedisStore::LOCAL_URL; "file" when neither does
|
|
94
96
|
def default_backend
|
|
95
97
|
local_redis_available? ? "redis" : "file"
|
|
96
98
|
end
|
data/lib/agent/lock/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: agent-lock
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Gredeskoul
|
|
@@ -29,14 +29,42 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0.
|
|
32
|
+
version: '0.5'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0.
|
|
39
|
+
version: '0.5'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: dry-cli-help
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.5'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.5'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: dry-cli-ui
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.5'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.5'
|
|
40
68
|
- !ruby/object:Gem::Dependency
|
|
41
69
|
name: pastel
|
|
42
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -65,10 +93,22 @@ dependencies:
|
|
|
65
93
|
- - "~>"
|
|
66
94
|
- !ruby/object:Gem::Version
|
|
67
95
|
version: '5.0'
|
|
68
|
-
description: '
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
96
|
+
description: 'This compact ruby gem is purely CLI utility: it''s meant to be used
|
|
97
|
+
by a team of AI agentsexecuting along one or more the plans in a given repo. Using
|
|
98
|
+
worktrees and parallelism it''s easy to 10x the speed of develpoment of software
|
|
99
|
+
development compared to even a single agent working on it. Plus each agent can specialize.
|
|
100
|
+
Such agents require globsl shared locking mechanism to ensure they are not working
|
|
101
|
+
on the same directory, or the same files in same worktree. That is exactly what
|
|
102
|
+
this gem does. The CLI binary you invoke is called ''alock''which comes with sub-command
|
|
103
|
+
''completion'' which you can load for BASH or ZSH. However, you are not very likely
|
|
104
|
+
going toinvoke this gem directly. It''s used by an Agentic Workflow gem ''agentilda''
|
|
105
|
+
to protect shared resources. To try the entire system, it''s recommended to download
|
|
106
|
+
the repo https://github.com/kigster/agentilda-ai-setup which both installs the two
|
|
107
|
+
gems, and offers a configuration file that installs a set of coding agents, skills,
|
|
108
|
+
plugins, commands, from various guthub folders, or via running commands, and so
|
|
109
|
+
on. In other words the repo''s purpose is to ensure your agentic setup is identical
|
|
110
|
+
from machine to machine, and by modifying the config file you can pick and choose
|
|
111
|
+
your skills, your AGENT.md/CLAUDE.md file and so on.'
|
|
72
112
|
email:
|
|
73
113
|
- kigster@gmail.com
|
|
74
114
|
executables:
|
|
@@ -78,8 +118,6 @@ extensions: []
|
|
|
78
118
|
extra_rdoc_files: []
|
|
79
119
|
files:
|
|
80
120
|
- ".claude/CLAUDE.md"
|
|
81
|
-
- ".envrc"
|
|
82
|
-
- ".rubocop_todo.yml"
|
|
83
121
|
- ".ruby-version"
|
|
84
122
|
- AGENTS.md
|
|
85
123
|
- CHANGELOG.md
|
|
@@ -144,7 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
144
182
|
- !ruby/object:Gem::Version
|
|
145
183
|
version: '0'
|
|
146
184
|
requirements: []
|
|
147
|
-
rubygems_version: 4.0.
|
|
185
|
+
rubygems_version: 4.0.21
|
|
148
186
|
specification_version: 4
|
|
149
|
-
summary: Advisory locks
|
|
187
|
+
summary: Advisory locks to prevent race conditions and general mayhem when multiple
|
|
188
|
+
AI agents unknowinly modify the same souce three.
|
|
150
189
|
test_files: []
|
data/.envrc
DELETED
data/.rubocop_todo.yml
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# This configuration was generated by
|
|
2
|
-
# `rubocop --auto-gen-config --no-auto-gen-timestamp`
|
|
3
|
-
# using RuboCop version 1.91.0.
|
|
4
|
-
# The point is for the user to remove these configuration records
|
|
5
|
-
# one by one as the offenses are removed from the code base.
|
|
6
|
-
# Note that changes in the inspected code, or installation of new
|
|
7
|
-
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
-
|
|
9
|
-
# Offense count: 1
|
|
10
|
-
Gemspec/RequiredRubyVersion:
|
|
11
|
-
Exclude:
|
|
12
|
-
- 'agent-lock.gemspec'
|
|
13
|
-
|
|
14
|
-
# Offense count: 3
|
|
15
|
-
# Configuration parameters: Prefixes, AllowedPatterns.
|
|
16
|
-
# Prefixes: when, with, without
|
|
17
|
-
RSpec/ContextWording:
|
|
18
|
-
Exclude:
|
|
19
|
-
- 'spec/agent/lock/tree_spec.rb'
|
|
20
|
-
- 'spec/support/aruba.rb'
|
|
21
|
-
- 'spec/support/checkout.rb'
|
|
22
|
-
|
|
23
|
-
# Offense count: 3
|
|
24
|
-
# Configuration parameters: IgnoredMetadata.
|
|
25
|
-
RSpec/DescribeClass:
|
|
26
|
-
Exclude:
|
|
27
|
-
- '**/spec/features/**/*'
|
|
28
|
-
- '**/spec/requests/**/*'
|
|
29
|
-
- '**/spec/routing/**/*'
|
|
30
|
-
- '**/spec/system/**/*'
|
|
31
|
-
- '**/spec/views/**/*'
|
|
32
|
-
- 'spec/agent/lock/concurrency_spec.rb'
|
|
33
|
-
- 'spec/agent/lock/loading_spec.rb'
|
|
34
|
-
- 'spec/agent/lock/manager_spec.rb'
|
|
35
|
-
|
|
36
|
-
# Offense count: 1
|
|
37
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
38
|
-
# Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
|
|
39
|
-
# SupportedStyles: described_class, explicit
|
|
40
|
-
RSpec/DescribedClass:
|
|
41
|
-
Exclude:
|
|
42
|
-
- 'spec/agent/lock/manager_spec.rb'
|
|
43
|
-
|
|
44
|
-
# Offense count: 46
|
|
45
|
-
# Configuration parameters: CountAsOne.
|
|
46
|
-
RSpec/ExampleLength:
|
|
47
|
-
Max: 20
|
|
48
|
-
|
|
49
|
-
# Offense count: 2
|
|
50
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
51
|
-
RSpec/IncludeExamples:
|
|
52
|
-
Exclude:
|
|
53
|
-
- 'spec/agent/lock/concurrency_spec.rb'
|
|
54
|
-
|
|
55
|
-
# Offense count: 5
|
|
56
|
-
# Configuration parameters: AssignmentOnly.
|
|
57
|
-
RSpec/InstanceVariable:
|
|
58
|
-
Exclude:
|
|
59
|
-
- 'spec/agent/lock/tree_spec.rb'
|
|
60
|
-
- 'spec/support/checkout.rb'
|
|
61
|
-
|
|
62
|
-
# Offense count: 2
|
|
63
|
-
RSpec/LeakyLocalVariable:
|
|
64
|
-
Exclude:
|
|
65
|
-
- 'spec/agent/lock/loading_spec.rb'
|
|
66
|
-
|
|
67
|
-
# Offense count: 2
|
|
68
|
-
# Configuration parameters: EnforcedStyle.
|
|
69
|
-
# SupportedStyles: have_received, receive
|
|
70
|
-
RSpec/MessageSpies:
|
|
71
|
-
Exclude:
|
|
72
|
-
- 'spec/agent/lock/freeze_spec.rb'
|
|
73
|
-
- 'spec/agent/lock/store_spec.rb'
|
|
74
|
-
|
|
75
|
-
# Offense count: 1
|
|
76
|
-
RSpec/MultipleDescribes:
|
|
77
|
-
Exclude:
|
|
78
|
-
- 'spec/agent/lock/manager_spec.rb'
|
|
79
|
-
|
|
80
|
-
# Offense count: 6
|
|
81
|
-
RSpec/MultipleExpectations:
|
|
82
|
-
Max: 2
|
|
83
|
-
|
|
84
|
-
# Offense count: 1
|
|
85
|
-
# Configuration parameters: AllowedClasses.
|
|
86
|
-
Style/OneClassPerFile:
|
|
87
|
-
Exclude:
|
|
88
|
-
- 'spec/**/*'
|
|
89
|
-
- 'test/**/*'
|
|
90
|
-
- 'lib/agent/lock/cli.rb'
|