Skip to content

Commit

Permalink
simplify project definitions
Browse files Browse the repository at this point in the history
update readme
raise exception in case config malformed
  • Loading branch information
zhisme authored Feb 19, 2024
1 parent 1152868 commit 706a759
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .lazy_names.tt.project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
definitions:
'Models::Users::CreditCard': 'MUCC'
4 changes: 1 addition & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
PATH
remote: .
specs:
lazy_names (0.0.1)
lazy_names (0.1.1)

GEM
remote: https://rubygems.org/
specs:
coderay (1.1.3)
diff-lcs (1.3)
fakefs (1.2.1)
method_source (1.0.0)
pry (0.13.1)
coderay (~> 1.1)
Expand All @@ -33,7 +32,6 @@ PLATFORMS

DEPENDENCIES
bundler (~> 1.16)
fakefs (~> 1.2)
lazy_names!
pry (~> 0.13)
rake (~> 10.0)
Expand Down
38 changes: 27 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ $ bundle exec rails c # or bin/console
```

## Configuration

### Global definition

Take a look onto `lazy_names.tt.yml` it has very basic template for you to start.

```yml
Expand All @@ -69,14 +72,14 @@ So consider this example:
$ pwd
/Users/name/my_awesome_project
```
The last folder name of you ruby project must match the same one in your configuration.
After **definitions** sections you can actually redefine your long constants.
So in this example `Models::Users::CreditCard` is your real project constant and
`MUCC` will be your short variant of it, so you can access `Models::Users::CreditCard`
from `MUCC`. `MUCC` and any other right hand side can be any value, you define the best-suitable names.

You can define as many constants as you want. The same rule applies for projects.
Your config can have multiple constant definitions per namespace.
The last folder name of you ruby project must match the same one in your configuration.
After **definitions** sections you can actually redefine your long constants.
So in this example `Models::Users::CreditCard` is your real project constant and
`MUCC` will be your short variant of it, so you can access `Models::Users::CreditCard`
from `MUCC`. `MUCC` and any other right hand side can be any value, you define the best-suitable names.

You can define as many constants as you want. The same rule applies for projects.
Your config can have multiple constant definitions per namespace.
```yml
---
my_awesome_project:
Expand All @@ -87,9 +90,22 @@ my_another_project:
'OtherLongConst': 'Short'
```

However you can put your `.lazy_names.yml` config directly to project folder, it will be looked up firstly from project.
Just do not forget to put in your `.gitignore`. I believe every developer defines shorter versions of constants by his own opinion.
If project folder doesn't contain any `.lazy_names.yml`, it will fallback to home directory.
### Project definitions

In the meantime you can put your `.lazy_names.yml` config directly to project folder, it will be looked up firstly from project.
Just do not forget to put in your `.gitignore`. I believe every developer defines shorter versions of constants by his own opinion.
```sh
echo '.lazy_names.yml' >> .gitignore
```
If project folder doesn't contain any `.lazy_names.yml`, it will fallback to home directory.

Configuration per project a bit different: you don't need to specify global scope `my_awesome_project`, you can skip forward to definitions
```yml
---
definitions:
'Models::Users::CreditCard: 'MUCC'
```
Example config can be found in `.lazy_names.tt.project.yml`

## Development

Expand Down
29 changes: 22 additions & 7 deletions lib/lazy_names/config_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class ConfigLoader
class NoConfig < StandardError; end
class ConfigNotResolved < StandardError; end
class NamespaceNotFound < StandardError; end
class NoDefinitions < StandardError; end

class << self
BasicConfig = Struct.new(:path, :definitions)
Expand All @@ -13,7 +14,7 @@ class << self
def call(namespace:, path: nil)
return read_from_path(namespace, path) if path

config = read_from_project(namespace)
config = read_from_project if config_in_project_path?
config ||= read_from_home_dir(namespace)

config
Expand All @@ -38,19 +39,33 @@ def read_from_home_dir(namespace)
'Create ~/.lazy_names.yml'
end

def read_from_project(namespace)
return false unless config_in_project_path?

definitions = find_definitions(project_path, namespace)
def read_from_project
definitions = find_project_definitions

BasicConfig.new(project_path, definitions)
end

def find_project_definitions
read_config(project_path)['definitions'].to_hash

rescue NoMethodError
raise NoDefinitions, "No definitions found in #{project_path}. " \
'See config example .lazy_names.tt.project.yml'
end

def find_definitions(path, namespace)
read_config(path)[namespace]['definitions'].to_h
find_namespace_contents(path, namespace)['definitions'].to_hash

rescue NoMethodError
raise NoDefinitions, "No definitions found in #{path}. " \
'See config example in .lazy_names.tt.yml'
end

def find_namespace_contents(path, namespace)
read_config(path)[namespace].to_hash
rescue NoMethodError
raise NamespaceNotFound
raise NamespaceNotFound, "No namespace found in #{path}. " \
'See config example in .lazy_names.tt.yml and check README'
end

def config_in_project_path?
Expand Down
30 changes: 25 additions & 5 deletions spec/lazy_names/config_loader_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'spec_helper'
require 'lazy_names/config_loader'
require 'support/shared_examples/expected_path'
require 'support/shared_examples/no_definitions'
require 'support/shared_context/with_paths'
require 'support/shared_context/with_config_contents'

Expand All @@ -9,7 +10,7 @@
subject { described_class.call(namespace: namespace, path: path) }

include_context 'with paths'
include_context 'with valid contents'
include_context 'with valid namespaced contents'

let(:path) { nil }

Expand All @@ -22,8 +23,9 @@

context 'when namespace' do
context 'matches config' do
it { should be_a(Struct) }
it { expect { subject }.to_not raise_error }
context 'with no definitions found' do
include_examples 'raises NoDefinitions error'
end
end

context 'not matches config' do
Expand All @@ -50,6 +52,16 @@
let(:path) { invalid_path }

it { expect { subject }.to raise_error(described_class::NoConfig) }

context 'with no definitions found' do
include_context 'with malformed contents'

let(:path) { valid_path }

before { allow(described_class).to receive(:read_config).with(path).and_return(config_contents) }

include_examples 'raises NoDefinitions error'
end
end
end

Expand All @@ -60,9 +72,9 @@
allow(described_class).to receive(:read_config).with(project_path).and_return(config_contents)
end

it { expect(subject).to be_a(Struct) }

context 'when valid' do
include_context 'with valid project contents'

let(:expected_path) { project_path }

include_examples 'returns expected path'
Expand All @@ -78,6 +90,14 @@
end

include_examples 'returns expected path'

context 'when config contents malformed' do
before do
allow(described_class).to receive(:config_in_project_path?).and_return(true)
end

include_examples 'raises NoDefinitions error'
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/lazy_names/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

RSpec.describe LazyNames::Config do
include_context 'with paths'
include_context 'with valid contents'
include_context 'with valid namespaced contents'

let(:config) { described_class.new(definitions, project_path) }

Expand Down
7 changes: 6 additions & 1 deletion spec/support/shared_context/with_config_contents.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
RSpec.shared_context 'with valid contents' do
RSpec.shared_context 'with valid namespaced contents' do
let(:config_contents) { YAML.safe_load("---\nlazy_names:\n definitions:\n 'User::CreditCard': 'UCC'") }
let(:already_defined_contents) { YAML.safe_load("---\nlazy_names:\n definitions:\n 'User::CreditCard': UCC\n 'User::CreditCard': UsCard\n") }
let(:definitions) { config_contents[namespace]['definitions'] }
let(:namespace) { 'lazy_names' }
end

RSpec.shared_context 'with valid project contents' do
let(:config_contents) { YAML.safe_load("---\ndefinitions:\n 'User::CreditCard': 'UCC'") }
let(:definitions) { config_contents['definitions'] }
end

RSpec.shared_context 'with already defined contents' do
let(:config_contents) { YAML.safe_load("---\nlazy_names:\n definitions:\n 'User::CreditCard': UCC\n 'User::CompanyCredit': UCC\n") }
let(:definitions) { config_contents[namespace]['definitions'] }
Expand Down
3 changes: 3 additions & 0 deletions spec/support/shared_examples/no_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RSpec.shared_examples 'raises NoDefinitions error' do
it { expect { subject }.to raise_error(described_class::NoDefinitions) }
end

0 comments on commit 706a759

Please sign in to comment.