ace-support-config 0.10.2 → 0.11.2
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 +31 -0
- data/README.md +12 -0
- data/docs/demo/ace-config-bootstrap-root-files.tape.yml +29 -0
- data/docs/usage.md +16 -1
- data/lib/ace/support/config/molecules/project_config_scanner.rb +1 -1
- data/lib/ace/support/config/organisms/config_initializer.rb +84 -3
- data/lib/ace/support/config/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33ca9302021e76335a714f27321b3075dd172056154ed5d1769b6f7b9ea7d6c7
|
|
4
|
+
data.tar.gz: e06462886d8d07fa3104367a96d129957b8554b8ac4419651f51c220dcd09167
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f6377fe1c334cdf394a619c0548966317167789dd3214c87d7cbef778fe069d7e059af7db77d53fcc86aeb0acb445ef4eb644cbfb29e1f2006f73f74aa671ef
|
|
7
|
+
data.tar.gz: d21e340eb555a7457aabcf55e7ea26120b54b9ed282f7227658810377274501e5fac8ce1b1d0519f8a9868330502a8d0dbae4e2b69afd8805f8b37ac033de699
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.11.2] - 2026-04-13
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Made bootstrap `.gitignore` detection line-aware so commented or negated `.ace-local/` mentions no longer suppress appending the real ignore rule.
|
|
14
|
+
|
|
15
|
+
### Technical
|
|
16
|
+
- Added regression coverage for commented and negated `.gitignore` mentions during bootstrap merges.
|
|
17
|
+
|
|
18
|
+
## [0.11.1] - 2026-04-13
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Preserve existing `.gitignore` rules even when `ace-config init --force` refreshes bootstrap files.
|
|
22
|
+
- Anchor project-root bootstrap files (`.gitignore`, `AGENTS.md`, `CLAUDE.md`) to the detected repository root so subdirectory runs do not seed them into the wrong location.
|
|
23
|
+
|
|
24
|
+
## [0.11.0] - 2026-04-13
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **ace-support-config v0.11.0**: Taught `ace-config init` to bootstrap project-root guidance files, include dotfile defaults, and append `.ace-local/` to existing `.gitignore` files without overwriting user-owned `AGENTS.md` or `CLAUDE.md`.
|
|
28
|
+
|
|
29
|
+
## [0.10.4] - 2026-04-13
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- **ace-support-config v0.10.4**: Standardized shared package tests to the fast-only layout and updated testing flow defaults.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## [0.10.3] - 2026-04-11
|
|
36
|
+
|
|
37
|
+
### Technical
|
|
38
|
+
- Migrated package tests to the `fast`/`feat` layout by moving deterministic ATOM coverage to `test/fast/` and former `test/integration/` suites to `test/feat/`.
|
|
39
|
+
- Updated package docs to publish the `ace-test ace-support-config` (`fast`), `feat`, and `all` contract and keep package scope deterministic-only.
|
|
40
|
+
|
|
10
41
|
## [0.10.2] - 2026-03-31
|
|
11
42
|
|
|
12
43
|
### Technical
|
data/README.md
CHANGED
|
@@ -29,6 +29,18 @@ ace-config version
|
|
|
29
29
|
ace-config help
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
## Testing
|
|
33
|
+
|
|
34
|
+
`ace-support-config` uses the ACE deterministic test taxonomy:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ace-test ace-support-config # fast (default)
|
|
38
|
+
ace-test ace-support-config feat # deterministic feature coverage
|
|
39
|
+
ace-test ace-support-config all # fast + feat
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This package does not define a package-owned `e2e` layer in this migration.
|
|
43
|
+
|
|
32
44
|
## How It Works
|
|
33
45
|
|
|
34
46
|
1. A resolver builds a configuration cascade from the nearest `.ace` directory up to user-home and gem-default layers.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Showcase ace-config init bootstrapping project-root guidance files from a subdirectory
|
|
3
|
+
tags:
|
|
4
|
+
- ace-config
|
|
5
|
+
- ace-support-config
|
|
6
|
+
- bootstrap
|
|
7
|
+
settings:
|
|
8
|
+
font_size: 16
|
|
9
|
+
width: 1200
|
|
10
|
+
height: 700
|
|
11
|
+
format: gif
|
|
12
|
+
scenes:
|
|
13
|
+
- name: Initialize config from a nested working directory
|
|
14
|
+
commands:
|
|
15
|
+
- type: mkdir -p repo/subdir && cd repo && git init
|
|
16
|
+
sleep: 3s
|
|
17
|
+
- type: cd subdir && ace-config init support-core
|
|
18
|
+
sleep: 5s
|
|
19
|
+
- name: Verify bootstrap files landed at the repository root
|
|
20
|
+
commands:
|
|
21
|
+
- type: cd ../ && find . -maxdepth 2 \\( -name '.gitignore' -o -name 'AGENTS.md' -o -name 'CLAUDE.md' \\) | sort
|
|
22
|
+
sleep: 4s
|
|
23
|
+
- type: printf '\n.gitignore contents:\n' && cat .gitignore
|
|
24
|
+
sleep: 4s
|
|
25
|
+
setup:
|
|
26
|
+
- sandbox
|
|
27
|
+
- copy-fixtures
|
|
28
|
+
teardown:
|
|
29
|
+
- cleanup
|
data/docs/usage.md
CHANGED
|
@@ -25,6 +25,21 @@ ace-config version
|
|
|
25
25
|
ace-config help
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
## Testing Contract
|
|
29
|
+
|
|
30
|
+
`ace-support-config` follows the ACE deterministic package targets:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ace-test ace-support-config
|
|
34
|
+
ace-test ace-support-config feat
|
|
35
|
+
ace-test ace-support-config all
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- `fast` (default) runs isolated deterministic package tests under `test/fast/`.
|
|
39
|
+
- `feat` runs deterministic feature tests under `test/feat/`.
|
|
40
|
+
- `all` runs `fast` then `feat`.
|
|
41
|
+
- This package does not publish a package-owned `e2e` target in this migration.
|
|
42
|
+
|
|
28
43
|
### Cascade Priority (highest to lowest)
|
|
29
44
|
|
|
30
45
|
1. **Project level** - `<project_root>/.ace/`
|
|
@@ -197,4 +212,4 @@ Ace::Support::Config.reset_config!
|
|
|
197
212
|
This clears:
|
|
198
213
|
- Project root cache
|
|
199
214
|
- Thread-local test mode state
|
|
200
|
-
- Thread-local mock data
|
|
215
|
+
- Thread-local mock data
|
|
@@ -21,7 +21,7 @@ module Ace
|
|
|
21
21
|
class ProjectConfigScanner
|
|
22
22
|
# Directories to skip during traversal
|
|
23
23
|
SKIP_DIRS = %w[.git .cache vendor node_modules tmp coverage
|
|
24
|
-
.bundle _legacy .ace-local .ace-tasks .ace-
|
|
24
|
+
.bundle _legacy .ace-local .ace-tasks .ace-task].freeze
|
|
25
25
|
|
|
26
26
|
# @param project_root [String, nil] Root directory to scan (default: Dir.pwd)
|
|
27
27
|
# @param config_dir [String] Config folder name (default: ".ace")
|
|
@@ -9,6 +9,9 @@ module Ace
|
|
|
9
9
|
module Config
|
|
10
10
|
module Organisms
|
|
11
11
|
class ConfigInitializer
|
|
12
|
+
PROJECT_ROOT_DIR = "project-root"
|
|
13
|
+
GITIGNORE_ACE_LOCAL_ENTRY = ".ace-local/"
|
|
14
|
+
|
|
12
15
|
def initialize(force: false, dry_run: false, global: false, verbose: false)
|
|
13
16
|
@force = force
|
|
14
17
|
@dry_run = dry_run
|
|
@@ -57,7 +60,9 @@ module Ace
|
|
|
57
60
|
end
|
|
58
61
|
|
|
59
62
|
def target_directory
|
|
60
|
-
|
|
63
|
+
return File.expand_path("~/.ace") if @global
|
|
64
|
+
|
|
65
|
+
File.join(project_root, ".ace")
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
def show_config_docs_if_needed(gem_name, target_dir)
|
|
@@ -71,17 +76,27 @@ module Ace
|
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
def copy_config_files(source_dir, target_dir)
|
|
74
|
-
|
|
79
|
+
glob_pattern = File.join(source_dir, "**", "*")
|
|
80
|
+
|
|
81
|
+
Dir.glob(glob_pattern, File::FNM_DOTMATCH).each do |source_file|
|
|
82
|
+
basename = File.basename(source_file)
|
|
83
|
+
next if basename == "." || basename == ".."
|
|
75
84
|
next if File.directory?(source_file)
|
|
76
85
|
|
|
77
86
|
relative_path = Pathname.new(source_file).relative_path_from(Pathname.new(source_dir))
|
|
78
|
-
target_file =
|
|
87
|
+
target_file = target_file_for(relative_path, target_dir)
|
|
88
|
+
next unless target_file
|
|
79
89
|
|
|
80
90
|
copy_file(source_file, target_file)
|
|
81
91
|
end
|
|
82
92
|
end
|
|
83
93
|
|
|
84
94
|
def copy_file(source, target)
|
|
95
|
+
if File.basename(target) == ".gitignore"
|
|
96
|
+
merge_gitignore(source, target)
|
|
97
|
+
return
|
|
98
|
+
end
|
|
99
|
+
|
|
85
100
|
if File.exist?(target) && !@force
|
|
86
101
|
@skipped_files << target
|
|
87
102
|
puts " Skipped: #{target} (already exists)" if @verbose
|
|
@@ -98,6 +113,72 @@ module Ace
|
|
|
98
113
|
end
|
|
99
114
|
end
|
|
100
115
|
|
|
116
|
+
def target_file_for(relative_path, target_dir)
|
|
117
|
+
relative_str = relative_path.to_s
|
|
118
|
+
|
|
119
|
+
if relative_str.start_with?("#{PROJECT_ROOT_DIR}/")
|
|
120
|
+
return nil if @global
|
|
121
|
+
|
|
122
|
+
return File.join(project_root, relative_str.delete_prefix("#{PROJECT_ROOT_DIR}/"))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
File.join(target_dir, relative_str)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def merge_gitignore(source, target)
|
|
129
|
+
target_exists = File.exist?(target)
|
|
130
|
+
|
|
131
|
+
if target_exists
|
|
132
|
+
merge_gitignore_entry_if_missing(source, target)
|
|
133
|
+
return
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if @dry_run
|
|
137
|
+
puts " Would copy: #{source} -> #{target}"
|
|
138
|
+
else
|
|
139
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
140
|
+
FileUtils.cp(source, target)
|
|
141
|
+
@copied_files << target
|
|
142
|
+
puts " Copied: #{target}" if @verbose
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def merge_gitignore_entry_if_missing(source, target)
|
|
147
|
+
existing_content = File.read(target)
|
|
148
|
+
return if gitignore_entry_present?(existing_content, GITIGNORE_ACE_LOCAL_ENTRY)
|
|
149
|
+
|
|
150
|
+
line = File.readlines(source, chomp: true).find do |entry|
|
|
151
|
+
entry == GITIGNORE_ACE_LOCAL_ENTRY
|
|
152
|
+
end
|
|
153
|
+
return unless line
|
|
154
|
+
|
|
155
|
+
if @dry_run
|
|
156
|
+
puts " Would append: #{line} -> #{target}"
|
|
157
|
+
return
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
File.open(target, "a") do |file|
|
|
161
|
+
file.write("\n") unless existing_content.end_with?("\n") || existing_content.empty?
|
|
162
|
+
file.puts line
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
@copied_files << target
|
|
166
|
+
puts " Appended: #{line} -> #{target}" if @verbose
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def gitignore_entry_present?(content, entry)
|
|
170
|
+
content.each_line.any? do |line|
|
|
171
|
+
normalized = line.strip
|
|
172
|
+
next false if normalized.empty? || normalized.start_with?("#")
|
|
173
|
+
|
|
174
|
+
normalized == entry
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def project_root
|
|
179
|
+
@project_root ||= Ace::Support::Config.find_project_root(start_path: Dir.pwd) || Dir.pwd
|
|
180
|
+
end
|
|
181
|
+
|
|
101
182
|
def print_summary
|
|
102
183
|
return if @dry_run
|
|
103
184
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-support-config
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-04-
|
|
10
|
+
date: 2026-04-20 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-support-fs
|
|
@@ -66,6 +66,7 @@ files:
|
|
|
66
66
|
- LICENSE
|
|
67
67
|
- README.md
|
|
68
68
|
- Rakefile
|
|
69
|
+
- docs/demo/ace-config-bootstrap-root-files.tape.yml
|
|
69
70
|
- docs/demo/ace-config-getting-started.tape.yml
|
|
70
71
|
- docs/usage.md
|
|
71
72
|
- exe/ace-config
|