ficha 0.1.0 → 0.2.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: 3ac8590b6ab46f565f13b1bb959e55c790f8ecebb62a7946b47be7e3acd94a88
4
- data.tar.gz: 6290916d3e12018298de9343a6d4803ce2b7beb5d983c19a9f26c1b32993426f
3
+ metadata.gz: 496e19f7e52e61e225538dea7b4c30c8381d8687b226355ba5912847c08b7a12
4
+ data.tar.gz: af98dadc7f8a44cb987cda56a07f07d28fa9082d486dd3092eead7715112cbc3
5
5
  SHA512:
6
- metadata.gz: 68dbe337310fa333176a6b7341d479dec441af04de24dc1e811307631432c3d459b4aaf31fbbf5272148e2b9cef6971aeb9f43e6703f129b2c9314d66236a4d7
7
- data.tar.gz: b5216fd9da5ed299891069e10101af2598a3a68c36cdd31ef2b02b7d59e42be5a1d32dd596d8aaf963418c57e752718d44fa5167371362aa15b8c9f7a1c8fe07
6
+ metadata.gz: 959e3c3e460f16cc0f507c23c23ab5817320e3524066bb7fb87d9ba1113bc26ba4c0bfb484f43e6cfaae4794eb32167096b1e4c991a94ad10cb67d2f24d915a0
7
+ data.tar.gz: e717d46c80e33f9990c7fad060764a05adaed236e3996d294dcde16dbba1c3f7ef71c35269920ffa5342ffa15cbeb88eafc076a75c5e93c0951c36b9b7bdb083
data/CHANGELOG.md CHANGED
@@ -1,23 +1,32 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to `ficha` will be documented in this file.
4
-
3
+ All notable changes to `ficha` will be documented in this file.
5
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
6
 
8
- ## [Unreleased]
7
+ ## [0.2.0] - 2025-12-09
8
+
9
+ ### Added
10
+
11
+ - Support for **global configuration** via `~/.ficha.yml` (used when no local `.ficha.yml` or `ficha.yml` is present).
12
+ - **Strategy composition**: define composite strategies using the `compose` key (e.g. `user-plus-session: { compose: [by-model:User, by-model:Session] }`).
13
+ - Built-in `Style/NoComments` RuboCop cop (disabled by default) for minimal-comment style enforcement.
9
14
 
10
15
  ### Changed
11
16
 
12
- - Refactored `Ficha::CLI#run` into smaller private methods to improve readability and comply with RuboCop metrics (ABC size, method length).
17
+ - Refactored `Ficha::CLI` and `Ficha::Engine` internals to improve readability and testability.
18
+ - Updated README examples to use correct config key `include_paths` (was incorrectly shown as `include`).
19
+ - Improved query parsing and strategy resolution logic.
13
20
 
14
21
  ### Fixed
15
22
 
16
- - Auto-corrected code style with RuboCop.
23
+ - Corrected GitHub repository URI in gemspec metadata.
17
24
 
18
25
  ### Internal
19
26
 
20
- - Added RuboCop linting to GitHub Actions CI.
27
+ - Added end-to-end tests for composed strategies and global config loading.
28
+ - Enforced RuboCop in GitHub Actions CI.
29
+ - Excluded test files from `Metrics/*` RuboCop checks.
21
30
 
22
31
  ## [0.1.0] - 2025-12-09
23
32
 
data/README.md CHANGED
@@ -131,6 +131,36 @@ excludes:
131
131
 
132
132
  ---
133
133
 
134
+ ## Global Configuration
135
+
136
+ If you don’t want to add `.ficha.yml` to every project, you can create a **global config** at `~/.ficha.yml`.
137
+
138
+ `ficha` will use it **only when no local `.ficha.yml` or `ficha.yml` is found**.
139
+
140
+ This is useful for defining your personal strategies (e.g. `by-model`, `by-job`) once and reusing them everywhere.
141
+
142
+ > 🔒 Sensitive or project-specific paths (like `output`, `excludes`) should still go into local config.
143
+
144
+ Example `~/.ficha.yml`:
145
+
146
+ ```yaml
147
+ version: "1"
148
+ strategies:
149
+ by-model:
150
+ params: [name]
151
+ include_paths:
152
+ - "app/models/{{name | underscore}}.rb"
153
+ - "app/controllers/{{name | pluralize | underscore}}_controller.rb"
154
+ by-job:
155
+ params: [name]
156
+ include_paths:
157
+ - "app/jobs/{{name | underscore}}.rb"
158
+ ```
159
+
160
+ Now you can run ficha by-model:User in any Ruby project — even without a local config!
161
+
162
+ ---
163
+
134
164
  ## 🎯 Built-in Strategies
135
165
 
136
166
  | Strategy | Purpose |
data/bin/console CHANGED
@@ -4,8 +4,5 @@
4
4
  require "bundler/setup"
5
5
  require "ficha"
6
6
 
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
7
  require "irb"
11
8
  IRB.start(__FILE__)
data/bin/ficha CHANGED
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # bin/ficha
5
-
6
4
  $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
5
  require "ficha/cli"
8
6
 
data/exe/ficha CHANGED
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # exe/ficha
5
-
6
4
  $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
5
  require "ficha"
8
6
 
data/ficha.gemspec CHANGED
@@ -34,9 +34,9 @@ Gem::Specification.new do |spec|
34
34
 
35
35
  spec.metadata = {
36
36
  "homepage_uri" => spec.homepage,
37
- "source_code_uri" => "https://github.com/ilmir/ficha",
38
- "changelog_uri" => "https://github.com/ilmir/ficha/blob/main/CHANGELOG.md",
39
- "bug_tracker_uri" => "https://github.com/ilmir/ficha/issues",
37
+ "source_code_uri" => "https://github.com/it1ro/ficha",
38
+ "changelog_uri" => "https://github.com/it1ro/ficha/blob/main/CHANGELOG.md",
39
+ "bug_tracker_uri" => "https://github.com/it1ro/ficha/issues",
40
40
  "rubygems_mfa_required" => "true"
41
41
  }
42
42
  end
data/lib/ficha/config.rb CHANGED
@@ -6,6 +6,10 @@ module Ficha
6
6
  class Config
7
7
  DEFAULT_CONFIG_PATH = File.expand_path("../../data/base.ficha.yml", __dir__)
8
8
 
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
9
13
  def self.load(config_path = nil)
10
14
  config_path ||= find_config
11
15
  if config_path && File.exist?(config_path)
@@ -17,8 +21,15 @@ module Ficha
17
21
  new(raw)
18
22
  end
19
23
 
20
- def initialize(data)
21
- @data = data
24
+ def self.find_config
25
+ local_candidates = ["./.ficha.yml", "./ficha.yml"]
26
+ local = local_candidates.find { |f| File.exist?(f) }
27
+ return local if local
28
+
29
+ global = File.expand_path("~/.ficha.yml")
30
+ return global if File.exist?(global)
31
+
32
+ nil
22
33
  end
23
34
 
24
35
  def strategies
@@ -28,9 +39,5 @@ module Ficha
28
39
  def defaults
29
40
  @data.fetch("defaults", {})
30
41
  end
31
-
32
- def self.find_config
33
- ["./.ficha.yml", "./ficha.yml"].find { |f| File.exist?(f) }
34
- end
35
42
  end
36
43
  end
data/lib/ficha/engine.rb CHANGED
@@ -31,12 +31,28 @@ module Ficha
31
31
  strategy_name = parsed[:name]
32
32
  params = parsed[:params]
33
33
 
34
- strategy = @config.strategies[strategy_name]
35
- raise "strategy '#{strategy_name}' not found in .ficha.yml" unless strategy
34
+ strategy = find_strategy!(strategy_name)
36
35
 
37
- param_hash = build_param_hash(strategy["params"] || [], params)
36
+ if strategy.key?("compose")
37
+ resolve_composed_query(strategy["compose"])
38
+ else
39
+ resolve_simple_query(strategy, params)
40
+ end
41
+ end
42
+
43
+ def find_strategy!(name)
44
+ strategy = @config.strategies[name]
45
+ raise "strategy '#{name}' not found in .ficha.yml" unless strategy
46
+
47
+ strategy
48
+ end
49
+
50
+ def resolve_composed_query(sub_queries)
51
+ sub_queries.flat_map { |sub_query| resolve_query(sub_query) }
52
+ end
38
53
 
39
- # Раскрываем include_paths через шаблоны и glob
54
+ def resolve_simple_query(strategy, given_params)
55
+ param_hash = build_param_hash(strategy["params"] || [], given_params)
40
56
  strategy["include_paths"].flat_map do |pattern|
41
57
  rendered = Template.render(pattern, param_hash)
42
58
  Dir.glob(rendered)
@@ -75,7 +91,6 @@ module Ficha
75
91
  excludes = @overrides[:exclude_paths] || []
76
92
  files.reject do |path|
77
93
  excludes.any? do |exclude_glob|
78
- # Если glob не содержит *, **, ? — считаем, что это директория → добавляем /**
79
94
  glob = exclude_glob.include?("*") || exclude_glob.include?("?") ? exclude_glob : "#{exclude_glob}/**/*"
80
95
  File.fnmatch(glob, path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
81
96
  end
data/lib/ficha/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ficha
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ficha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilmir Karimov
@@ -56,9 +56,9 @@ licenses:
56
56
  - AGPL-3.0-or-later
57
57
  metadata:
58
58
  homepage_uri: https://github.com/ilmir/ficha
59
- source_code_uri: https://github.com/ilmir/ficha
60
- changelog_uri: https://github.com/ilmir/ficha/blob/main/CHANGELOG.md
61
- bug_tracker_uri: https://github.com/ilmir/ficha/issues
59
+ source_code_uri: https://github.com/it1ro/ficha
60
+ changelog_uri: https://github.com/it1ro/ficha/blob/main/CHANGELOG.md
61
+ bug_tracker_uri: https://github.com/it1ro/ficha/issues
62
62
  rubygems_mfa_required: 'true'
63
63
  rdoc_options: []
64
64
  require_paths: