gemkeeper 0.1.0 → 0.2.1

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.
@@ -0,0 +1,287 @@
1
+ # Spec 20260518-154733: Gemkeeper Contractor Support
2
+
3
+ ## Overview
4
+ Contractors need to install internal Ruby gems that are normally served from a private gem
5
+ server they cannot reach without VPN.
6
+ This spec defines the features needed to make gemkeeper a reliable, self-service solution for
7
+ this use case: a project setup command, lockfile-aware sync, correct server binding, and
8
+ accurate documentation of the full setup sequence.
9
+ The companion CLI tool that delivers the gem manifest is specified separately.
10
+
11
+ ## Goals
12
+ - Let a contractor configure gemkeeper for a specific project without knowing the internal
13
+ gem inventory
14
+ - Make `gemkeeper sync` idempotent against a `Gemfile.lock` with no redundant builds
15
+ - Document the end-to-end contractor setup sequence in the gemkeeper README
16
+ - Harden the server and sync commands against the most common failure modes
17
+
18
+ ---
19
+
20
+ ## Feature 1: Project Setup Command
21
+
22
+ **Who & why:** A contractor has just installed gemkeeper and has a `Gemfile.lock` in front
23
+ of them.
24
+ They should not need to know the names of internal gems, their GitHub URLs, or how to
25
+ construct a `gemkeeper.yml` by hand.
26
+ `gemkeeper setup` reads the lockfile, cross-references the org gem manifest, and
27
+ produces a ready-to-use config.
28
+
29
+ ### Functional Requirements
30
+
31
+ #### FR-1.1: Setup Command
32
+ `gemkeeper setup <path-to-gemfile-lock>` reads the `GEM` section of the lockfile,
33
+ cross-references the manifest at `~/.config/gemkeeper/manifest.yml` (override:
34
+ `--manifest <path>`), and writes a `gemkeeper.yml` in the current directory.
35
+
36
+ Each matched gem entry uses `version: "from_lockfile"` so subsequent sync calls read the
37
+ current lockfile version rather than requiring setup to be re-run on every lockfile change.
38
+
39
+ **Behavior when `gemkeeper.yml` already exists:** the command merges — it adds or updates
40
+ only entries for gems found in the manifest, leaving all other keys (port, repos_path,
41
+ gems_path, unrelated gem entries) untouched.
42
+ Pass `--force` to overwrite the file entirely.
43
+
44
+ **Error cases:**
45
+ - Manifest not found at default or `--manifest` path → fail with message directing the user
46
+ to install the org's gem manifest
47
+ - Gem appears in lockfile with a name matching an internal pattern but absent from manifest →
48
+ warn and skip, do not fail
49
+
50
+ **Verify:** Running `gemkeeper setup /path/to/Gemfile.lock` in a directory with no prior
51
+ config produces a `gemkeeper.yml` listing only the internal gems the lockfile references, each
52
+ with `version: "from_lockfile"`.
53
+
54
+ #### FR-1.2: Bundler Configuration Output
55
+ After setup completes, the command prints the `bundle config` command the developer
56
+ must run to redirect their project's internal gem source to the local Geminabox.
57
+ If the manifest includes a `source_url` field, that URL is used as the mirror key.
58
+ Otherwise, the command prints a generic placeholder the developer must fill in.
59
+ Example output:
60
+ ```
61
+ To point Bundler at your local Geminabox, run:
62
+ bundle config set --local mirror.<private-gem-source-url> http://localhost:9292
63
+ ```
64
+ The port in the command matches the configured port in `gemkeeper.yml` (default: 9292).
65
+ `git:` source declarations in the Gemfile are unaffected and require no mirror config.
66
+
67
+ **Verify:** After running the printed command, `bundle install` resolves internal gems from
68
+ the local Geminabox and public gems from rubygems.org without modifying any tracked file.
69
+
70
+ ---
71
+
72
+ ## Feature 2: Lockfile-Aware Sync
73
+
74
+ **Who & why:** With `version: "from_lockfile"` in the config, sync must read the lockfile,
75
+ resolve the correct git checkout ref, skip versions already cached, and handle partial
76
+ failures gracefully.
77
+ A sync that rebuilds everything on every run, or that fails entirely on one bad gem, is not
78
+ usable in practice.
79
+
80
+ ### Functional Requirements
81
+
82
+ #### FR-2.1: `from_lockfile` Version Resolution
83
+ When a gem entry specifies `version: "from_lockfile"`, `gemkeeper sync`:
84
+ 1. Walks up from the current directory to find the nearest `Gemfile.lock`
85
+ 2. Reads the gem's locked version from the `GEM` section
86
+ 3. Attempts to check out git tag `v{version}`, then `{version}`, in that order
87
+ 4. Fails with a named error if neither tag exists in the repo (naming the gem and version)
88
+
89
+ If no `Gemfile.lock` is found in the directory walk, sync fails with a message naming the
90
+ gem and the search path traversed.
91
+
92
+ `version: "latest"` and explicit version tags continue to work as before.
93
+
94
+ **Verify:** `gemkeeper sync` for a gem with `version: "from_lockfile"` checks out the git tag
95
+ corresponding to the version pinned in the nearest `Gemfile.lock`.
96
+ When no lockfile is found, the command exits non-zero with a descriptive message.
97
+
98
+ #### FR-2.2: Skip Already-Cached Versions
99
+ Before cloning, fetching, building, or uploading, `gemkeeper sync` checks whether the `.gem`
100
+ file for the resolved version is already present in the Geminabox cache at
101
+ `File.join(gems_path, "gems", "#{name}-#{version}.gem")`.
102
+ If present, the gem is skipped entirely — no clone, no build, no upload.
103
+ Re-running sync with no lockfile change is a no-op.
104
+
105
+ **Verify:** First sync builds and uploads gem X at version 1.2.3.
106
+ Second sync with no lockfile change produces no git, build, or upload activity.
107
+ Updating the lockfile to version 1.3.0 causes sync to build and upload only that version.
108
+
109
+ #### FR-2.3: Partial Failure Handling
110
+ If one gem's clone, build, or upload fails, sync continues with the remaining gems.
111
+ At the end of the run, sync reports all failures (gem name + error message) and exits
112
+ non-zero if any gem failed.
113
+ A fully successful sync exits zero.
114
+ **Verify:** A sync with one gem that fails to build still attempts all other configured gems
115
+ and exits non-zero with a summary of the failure.
116
+
117
+ #### FR-2.4: Git Authentication Failure Handling
118
+ When `git clone` or `git fetch` returns an authentication error, sync exits non-zero with a
119
+ message that includes the failed repo URL and a pointer to GitHub credential setup
120
+ documentation (`https://docs.github.com/en/authentication`).
121
+ The raw git error may be included but the failure type must be identified specifically.
122
+ Clone URLs must not use the embedded-token format (`https://token@github.com/...`); the
123
+ README must warn against this pattern.
124
+ **Verify:** Running sync against a repo with no configured GitHub credentials produces a
125
+ message containing "authentication" and the docs URL.
126
+
127
+ ---
128
+
129
+ ## Feature 3: Server and Security Hardening
130
+
131
+ **Who & why:** Geminabox runs without authentication.
132
+ Binding to `0.0.0.0` would expose an unauthenticated gem push endpoint to LAN peers, allowing
133
+ a malicious gem to be silently installed by `bundle install`.
134
+ Ref validation prevents argument injection from crafted manifest entries.
135
+
136
+ ### Functional Requirements
137
+
138
+ #### FR-3.1: Localhost-Only Server Binding
139
+ `gemkeeper server start` (and `server start --foreground`) must bind Geminabox to `127.0.0.1`
140
+ only.
141
+ **Verify:** After `gemkeeper server start`, `lsof -i :9292` shows the process bound to
142
+ `127.0.0.1`, not `0.0.0.0`.
143
+
144
+ ### Architectural Requirements
145
+
146
+ #### AR-3.1: `--host 127.0.0.1` Passed to Rackup
147
+ The `start_server` and `start_server_foreground` methods in `ServerManager` must pass
148
+ `"--host", "127.0.0.1"` in the rackup command array.
149
+ This applies to both daemonized and foreground start.
150
+
151
+ #### AR-3.2: Manifest Ref Validation
152
+ Before passing any manifest-derived or lockfile-derived value to `git checkout`, gemkeeper
153
+ validates the value against `/\A[a-zA-Z0-9._\-]+\z/`.
154
+ Values that do not match are rejected with an error naming the offending entry.
155
+ The existing `run_git` method uses `Open3.capture3(*cmd)` array form and is already safe from
156
+ shell injection; this validation prevents argument injection (e.g., `--upload-pack=...`).
157
+
158
+ ---
159
+
160
+ ## Feature 4: Documentation
161
+
162
+ **Who & why:** A contractor following the gemkeeper README must be able to complete setup
163
+ independently.
164
+ The current README does not document the contractor workflow or the full sequence
165
+ of commands needed to get `bundle install` working.
166
+
167
+ ### Functional Requirements
168
+
169
+ #### FR-4.1: Contractor Setup Sequence
170
+ The gemkeeper README must document the full setup sequence as a numbered checklist:
171
+ 1. Install gemkeeper (`gem install gemkeeper`)
172
+ 2. Install the org's gem manifest (mechanism provided by the org)
173
+ 3. Run `gemkeeper setup <path/to/Gemfile.lock>` in the project directory
174
+ 4. Run `gemkeeper sync` to build and cache internal gems
175
+ 5. Start the local server (`gemkeeper server start`)
176
+ 6. Configure Bundler with the command printed by step 3
177
+
178
+ The checklist must note that GitHub credentials must be configured before step 4 (link to
179
+ `https://docs.github.com/en/authentication`).
180
+
181
+ **Verify:** A new contractor with no prior gemkeeper knowledge can follow the checklist and
182
+ reach a passing `bundle install` without assistance.
183
+
184
+ #### FR-4.2: HTTPS Git URL Documentation
185
+ Config examples and the README must document HTTPS GitHub URLs
186
+ (`https://github.com/org/repo`) as the recommended format for contractors who have not
187
+ configured SSH keys.
188
+ SSH URLs (`git@github.com:org/repo.git`) must be noted as an alternative.
189
+ **Verify:** The README config examples use HTTPS URLs.
190
+
191
+ ---
192
+
193
+ ## Architectural Requirements (Cross-Cutting)
194
+
195
+ #### AR-4.1: `from_lockfile` Schema in Configuration
196
+ `from_lockfile` is a new reserved string in `Configuration::GemDefinition`, validated
197
+ alongside `"latest"`.
198
+ The existing `latest?` predicate is joined by a `from_lockfile?` predicate.
199
+ `gemkeeper.yml` validation rejects any `version` value that is not `"latest"`,
200
+ `"from_lockfile"`, or a string matching `/\A[a-zA-Z0-9._\-]+\z/`.
201
+
202
+ #### AR-4.2: No Geminabox Patching
203
+ All sync logic, idempotency tracking, and version resolution lives in gemkeeper code.
204
+ Geminabox is used as a Rack dependency without modification.
205
+ `rubygems_proxy = true` is already set in the generated `config.ru` and requires no change.
206
+
207
+ #### AR-4.3: Bundler Mirror over Source Block
208
+ `gemkeeper setup` prints a `bundle config set --local mirror.X Y` instruction rather than
209
+ suggesting a Gemfile source block, because the mirror approach requires no change to the
210
+ committed `Gemfile` or `Gemfile.lock`.
211
+
212
+ ---
213
+
214
+ ## Integration Points
215
+
216
+ - gemkeeper setup → `~/.config/gemkeeper/manifest.yml` (written by the org's manifest installer)
217
+ - gemkeeper sync → GitHub (HTTPS or SSH clone; no private gem server required)
218
+ - gemkeeper server → Geminabox (Rack app, localhost only)
219
+ - gemkeeper → Bundler (mirror config, local scope, printed by setup)
220
+
221
+ ## Related Specs
222
+
223
+ The companion CLI tool that delivers `~/.config/gemkeeper/manifest.yml` is out of scope for this repo.
224
+
225
+ ## Constraints
226
+ - Geminabox is used as a dependency, not modified
227
+ - Ruby >= 3.1.0 (existing gemspec requirement)
228
+
229
+ ## Out of Scope
230
+ - Automating manifest updates on gem release
231
+ - Centrally hosted gem mirror
232
+ - Windows support
233
+ - Gems declared via `git:` source blocks (these already resolve via GitHub; no caching needed)
234
+ - CI/CD pipeline support (contractors and local dev only for this spec)
235
+
236
+ ---
237
+
238
+ ## Spec Completeness Checklist
239
+
240
+ - [x] **Scope & acceptance criteria** — FR-1.1 through FR-4.2 have Verify: lines; Out of
241
+ Scope names exclusions; `git:` source blocks explicitly excluded
242
+ - [x] **Testing strategy** — new commands (setup, FR-1.1; manifest-aware sync, FR-2.1–2.4)
243
+ follow the pattern in `test/` with unit tests per class and integration tests for CLI
244
+ commands; manifest loading tested with fixture YAML; lockfile parsing tested with fixture
245
+ lockfiles covering `GEM` and `GIT` sections; FR-3.1 server binding tested via `lsof` in
246
+ integration test; ref validation (AR-3.2) tested with crafted inputs
247
+ - [x] **Existing patterns** — spec extends `Configuration::GemDefinition` (AR-4.1),
248
+ `GemBuilder`/`GemUploader`/`GitRepository` (sync FRs), `ServerManager` (FR-3.1);
249
+ `run_git` array form confirmed safe from shell injection
250
+ - [x] **Dependencies** — no new runtime gems required; `bundler` gem used for lockfile
251
+ parsing if not already available (it is, as a development dependency); no other additions
252
+ - [x] **Architecture & interfaces** — `from_lockfile` schema defined in AR-4.1; lockfile
253
+ search and version-to-tag mapping defined in FR-2.1; idempotency check path defined in
254
+ FR-2.2; server binding defined in AR-3.1; manifest interface defined in Integration Points
255
+ - [x] **Error handling & failure modes** — FR-2.1 covers missing lockfile and missing tag;
256
+ FR-2.3 covers partial sync failure; FR-2.4 covers git auth failure; FR-1.1 covers missing
257
+ manifest; AR-3.2 covers invalid refs; known limitation: disk-present ≠ upload-confirmed
258
+ (see Assumptions & Risks #3)
259
+ - [x] **Security review** — `run_git` uses `Open3.capture3(*cmd)` array form (safe); AR-3.2
260
+ adds ref validation; AR-3.1 binds to localhost; FR-2.4 prohibits embedded-token URLs;
261
+ no credentials stored by gemkeeper
262
+ - [x] **Performance impact** — idempotency check (FR-2.2) skips entire clone/build/upload
263
+ pipeline when version is cached; Geminabox proxies public gems via `rubygems_proxy = true`;
264
+ no production system impact
265
+ - [N/A] **Rollout & migration** — additive; existing `gemkeeper.yml` files without
266
+ `from_lockfile` continue to work; server binding change is transparent to users
267
+ - [x] **Assumptions & risks** — see below
268
+
269
+ ### Assumptions & Risks
270
+
271
+ 1. **Assumption:** All contractors have HTTPS GitHub access to the internal gem repos listed
272
+ in the manifest.
273
+ The contractor setup checklist (FR-4.1) must state this as a prerequisite.
274
+
275
+ 2. **Assumption:** Internal gem `gemspec` files can be evaluated locally without proprietary
276
+ build tooling.
277
+ If a gem requires a non-standard build step, `gemkeeper sync` will fail.
278
+ Mitigation: verify `gemkeeper sync` succeeds for each gem before adding it to the manifest.
279
+
280
+ 3. **Known limitation:** The idempotency check (FR-2.2) confirms a `.gem` file exists on
281
+ disk, not that it was successfully uploaded to the running Geminabox instance.
282
+ A build whose upload failed will be silently skipped on re-run.
283
+ Mitigation: `gemkeeper list` can be used to verify what the running server holds.
284
+
285
+ 4. **Risk:** Gems containing native extensions produce platform-specific `.gem` files.
286
+ A gem cache is not portable across machines with different CPU architectures.
287
+ Each developer must run `gemkeeper sync` on their own machine.
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemkeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Brubaker Horst
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-05-19 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: dry-cli
@@ -88,25 +89,17 @@ executables:
88
89
  extensions: []
89
90
  extra_rdoc_files: []
90
91
  files:
91
- - ".env.example"
92
- - ".envrc"
93
- - ".rubocop.yml"
94
- - AGENTS.md
95
92
  - CHANGELOG.md
96
- - CLAUDE.md
97
- - CODE_OF_CONDUCT.md
98
93
  - LICENSE
99
- - Makefile
100
94
  - README.md
101
- - Rakefile
102
95
  - exe/gemkeeper
103
- - gemkeeper.yml.example
104
96
  - lib/gemkeeper.rb
105
97
  - lib/gemkeeper/cli.rb
106
98
  - lib/gemkeeper/cli/commands/list.rb
107
99
  - lib/gemkeeper/cli/commands/server/start.rb
108
100
  - lib/gemkeeper/cli/commands/server/status.rb
109
101
  - lib/gemkeeper/cli/commands/server/stop.rb
102
+ - lib/gemkeeper/cli/commands/setup.rb
110
103
  - lib/gemkeeper/cli/commands/sync.rb
111
104
  - lib/gemkeeper/cli/commands/version.rb
112
105
  - lib/gemkeeper/configuration.rb
@@ -114,9 +107,15 @@ files:
114
107
  - lib/gemkeeper/gem_builder.rb
115
108
  - lib/gemkeeper/gem_uploader.rb
116
109
  - lib/gemkeeper/git_repository.rb
110
+ - lib/gemkeeper/lockfile_parser.rb
111
+ - lib/gemkeeper/manifest_reader.rb
112
+ - lib/gemkeeper/output.rb
117
113
  - lib/gemkeeper/server_manager.rb
118
114
  - lib/gemkeeper/version.rb
115
+ - mise.toml
119
116
  - sig/gemkeeper.rbs
117
+ - specs/20260518-154733-gemkeeper-contractor-support/implementation-summary.md
118
+ - specs/20260518-154733-gemkeeper-contractor-support/spec.md
120
119
  homepage: https://github.com/danhorst/gemkeeper
121
120
  licenses:
122
121
  - MIT
@@ -125,6 +124,7 @@ metadata:
125
124
  source_code_uri: https://github.com/danhorst/gemkeeper
126
125
  changelog_uri: https://github.com/danhorst/gemkeeper/blob/main/CHANGELOG.md
127
126
  rubygems_mfa_required: 'true'
127
+ post_install_message:
128
128
  rdoc_options: []
129
129
  require_paths:
130
130
  - lib
@@ -139,7 +139,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubygems_version: 3.6.8
142
+ rubygems_version: 3.5.22
143
+ signing_key:
143
144
  specification_version: 4
144
145
  summary: Manage offline development with private gem dependencies
145
146
  test_files: []
data/.env.example DELETED
@@ -1 +0,0 @@
1
- RUBYGEMS_PROXY=true
data/.envrc DELETED
@@ -1,3 +0,0 @@
1
- dotenv
2
-
3
- PATH_add bin
data/.rubocop.yml DELETED
@@ -1,30 +0,0 @@
1
- plugins:
2
- - rubocop-performance
3
-
4
- AllCops:
5
- TargetRubyVersion: 3.1
6
- NewCops: enable
7
- SuggestExtensions: false
8
- Exclude:
9
- - cache/**/*
10
- - vendor/**/*
11
-
12
- Style/StringLiterals:
13
- EnforcedStyle: double_quotes
14
-
15
- Style/StringLiteralsInInterpolation:
16
- EnforcedStyle: double_quotes
17
-
18
- Style/Documentation:
19
- Enabled: false
20
-
21
- Metrics/MethodLength:
22
- Max: 30
23
-
24
- Metrics/AbcSize:
25
- Max: 40
26
-
27
- Metrics/ClassLength:
28
- Max: 120
29
- Exclude:
30
- - test/**/*
data/AGENTS.md DELETED
@@ -1,52 +0,0 @@
1
- # Gemkeeper
2
-
3
- A Ruby CLI tool for managing offline development with private gem dependencies.
4
-
5
- ## Purpose
6
-
7
- Automate building internal gems from source and caching them in a local Geminabox server for offline Rails development when disconnected from VPN.
8
-
9
- ## Architecture
10
-
11
- - Ruby gem with CLI executable (`exe/gemkeeper`)
12
- - YAML config for gem repository definitions
13
- - Git operations to clone/pull internal repos
14
- - Build gems at specified versions/tags
15
- - Upload to local Geminabox server
16
- - Geminabox proxies public gems from RubyGems.org
17
-
18
- ## Config Example
19
-
20
- ```yaml
21
- port: 9292
22
- repos_path: ./cache/repos
23
- gems_path: ./cache/gems
24
-
25
- gems:
26
- - repo: git@github.com:company/internal-gem-1.git
27
- version: latest
28
- - repo: git@github.com:company/internal-gem-2.git
29
- version: v2.3.1
30
- ```
31
-
32
- ## CLI Commands
33
-
34
- - `gemkeeper version` - Print version
35
- - `gemkeeper server start` - Start Geminabox server
36
- - `gemkeeper server stop` - Stop Geminabox server
37
- - `gemkeeper server status` - Check server status
38
- - `gemkeeper sync` - Build and upload all configured gems
39
- - `gemkeeper sync <gem-name>` - Sync specific gem
40
- - `gemkeeper list` - Show locally uploaded gems
41
-
42
- ## Development
43
-
44
- ```bash
45
- bundle install
46
- bundle exec rake test # Run tests
47
- bundle exec rubocop # Run linter
48
- ```
49
-
50
- ## Current Status
51
-
52
- v1 complete - all core functionality implemented
data/CLAUDE.md DELETED
@@ -1 +0,0 @@
1
- AGENTS.md
data/CODE_OF_CONDUCT.md DELETED
@@ -1,132 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- We as members, contributors, and leaders pledge to make participation in our
6
- community a harassment-free experience for everyone, regardless of age, body
7
- size, visible or invisible disability, ethnicity, sex characteristics, gender
8
- identity and expression, level of experience, education, socio-economic status,
9
- nationality, personal appearance, race, caste, color, religion, or sexual
10
- identity and orientation.
11
-
12
- We pledge to act and interact in ways that contribute to an open, welcoming,
13
- diverse, inclusive, and healthy community.
14
-
15
- ## Our Standards
16
-
17
- Examples of behavior that contributes to a positive environment for our
18
- community include:
19
-
20
- * Demonstrating empathy and kindness toward other people
21
- * Being respectful of differing opinions, viewpoints, and experiences
22
- * Giving and gracefully accepting constructive feedback
23
- * Accepting responsibility and apologizing to those affected by our mistakes,
24
- and learning from the experience
25
- * Focusing on what is best not just for us as individuals, but for the overall
26
- community
27
-
28
- Examples of unacceptable behavior include:
29
-
30
- * The use of sexualized language or imagery, and sexual attention or advances of
31
- any kind
32
- * Trolling, insulting or derogatory comments, and personal or political attacks
33
- * Public or private harassment
34
- * Publishing others' private information, such as a physical or email address,
35
- without their explicit permission
36
- * Other conduct which could reasonably be considered inappropriate in a
37
- professional setting
38
-
39
- ## Enforcement Responsibilities
40
-
41
- Community leaders are responsible for clarifying and enforcing our standards of
42
- acceptable behavior and will take appropriate and fair corrective action in
43
- response to any behavior that they deem inappropriate, threatening, offensive,
44
- or harmful.
45
-
46
- Community leaders have the right and responsibility to remove, edit, or reject
47
- comments, commits, code, wiki edits, issues, and other contributions that are
48
- not aligned to this Code of Conduct, and will communicate reasons for moderation
49
- decisions when appropriate.
50
-
51
- ## Scope
52
-
53
- This Code of Conduct applies within all community spaces, and also applies when
54
- an individual is officially representing the community in public spaces.
55
- Examples of representing our community include using an official email address,
56
- posting via an official social media account, or acting as an appointed
57
- representative at an online or offline event.
58
-
59
- ## Enforcement
60
-
61
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
- reported to the community leaders responsible for enforcement at
63
- [INSERT CONTACT METHOD].
64
- All complaints will be reviewed and investigated promptly and fairly.
65
-
66
- All community leaders are obligated to respect the privacy and security of the
67
- reporter of any incident.
68
-
69
- ## Enforcement Guidelines
70
-
71
- Community leaders will follow these Community Impact Guidelines in determining
72
- the consequences for any action they deem in violation of this Code of Conduct:
73
-
74
- ### 1. Correction
75
-
76
- **Community Impact**: Use of inappropriate language or other behavior deemed
77
- unprofessional or unwelcome in the community.
78
-
79
- **Consequence**: A private, written warning from community leaders, providing
80
- clarity around the nature of the violation and an explanation of why the
81
- behavior was inappropriate. A public apology may be requested.
82
-
83
- ### 2. Warning
84
-
85
- **Community Impact**: A violation through a single incident or series of
86
- actions.
87
-
88
- **Consequence**: A warning with consequences for continued behavior. No
89
- interaction with the people involved, including unsolicited interaction with
90
- those enforcing the Code of Conduct, for a specified period of time. This
91
- includes avoiding interactions in community spaces as well as external channels
92
- like social media. Violating these terms may lead to a temporary or permanent
93
- ban.
94
-
95
- ### 3. Temporary Ban
96
-
97
- **Community Impact**: A serious violation of community standards, including
98
- sustained inappropriate behavior.
99
-
100
- **Consequence**: A temporary ban from any sort of interaction or public
101
- communication with the community for a specified period of time. No public or
102
- private interaction with the people involved, including unsolicited interaction
103
- with those enforcing the Code of Conduct, is allowed during this period.
104
- Violating these terms may lead to a permanent ban.
105
-
106
- ### 4. Permanent Ban
107
-
108
- **Community Impact**: Demonstrating a pattern of violation of community
109
- standards, including sustained inappropriate behavior, harassment of an
110
- individual, or aggression toward or disparagement of classes of individuals.
111
-
112
- **Consequence**: A permanent ban from any sort of public interaction within the
113
- community.
114
-
115
- ## Attribution
116
-
117
- This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
- version 2.1, available at
119
- [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120
-
121
- Community Impact Guidelines were inspired by
122
- [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
123
-
124
- For answers to common questions about this code of conduct, see the FAQ at
125
- [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
126
- [https://www.contributor-covenant.org/translations][translations].
127
-
128
- [homepage]: https://www.contributor-covenant.org
129
- [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
130
- [Mozilla CoC]: https://github.com/mozilla/diversity
131
- [FAQ]: https://www.contributor-covenant.org/faq
132
- [translations]: https://www.contributor-covenant.org/translations
data/Makefile DELETED
@@ -1,26 +0,0 @@
1
- .PHONY: all build test fmt clean
2
-
3
- # Find all tool directories under cmd/
4
- TOOLS := $(wildcard cmd/*)
5
- BINARIES := $(notdir $(TOOLS))
6
-
7
- all: build
8
-
9
- build:
10
- @for tool in $(BINARIES); do \
11
- if [ -d "cmd/$$tool" ] && [ -f "cmd/$$tool/main.go" ]; then \
12
- echo "Building $$tool..."; \
13
- go build -o bin/$$tool ./cmd/$$tool; \
14
- fi \
15
- done
16
-
17
- test:
18
- go test .
19
-
20
- fmt:
21
- gofmt -w .
22
-
23
- clean:
24
- rm -f bin/*
25
- @# Preserve agent-setup script
26
- @git checkout bin/agent-setup 2>/dev/null || true
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "minitest/test_task"
5
-
6
- Minitest::TestTask.create
7
-
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[test rubocop]
@@ -1,26 +0,0 @@
1
- # Gemkeeper configuration file
2
- # Copy this to gemkeeper.yml and modify as needed
3
-
4
- # Server port (default: 9292)
5
- port: 9292
6
-
7
- # Path for cloned repositories (default: ./cache/repos)
8
- repos_path: ./cache/repos
9
-
10
- # Path for Geminabox gem storage (default: ./cache/gems)
11
- gems_path: ./cache/gems
12
-
13
- # List of internal gems to sync
14
- gems:
15
- # Sync the latest version from the main/master branch
16
- - repo: git@github.com:company/internal-gem.git
17
- version: latest
18
-
19
- # Sync a specific tag or branch
20
- - repo: git@github.com:company/another-gem.git
21
- version: v2.3.1
22
-
23
- # Override the gem name if it differs from the repo name
24
- - repo: git@github.com:company/ruby-mylib.git
25
- name: mylib
26
- version: latest