Skip to content

Commit e77e46b

Browse files
committed
Provided service-based architecture, wrote readme
1 parent 8740b89 commit e77e46b

14 files changed

+423
-72
lines changed

README.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Git User Services ![GitHubCat](https://github.com/favicon.ico)
2+
3+
Small application with own service-based architecture.
4+
5+
### Main purpose:
6+
Changing git user in .gitconfig by round-robin.
7+
8+
### Usage:
9+
1. Separate user configuration lines must be commented in _<.gitconfig>_:
10+
```bash
11+
[user]
12+
13+
# name = Sample User 1
14+
15+
name = Sample User 2
16+
17+
# name = Sample User 3
18+
```
19+
20+
2. Execute by
21+
```bash
22+
ruby actions/change.rb
23+
```
24+
3. After successful execution you will receive information about current user:
25+
```bash
26+
## Email was replaced to [email protected] ##
27+
## Name was replaced to Sample User 3 ##
28+
## <.gitconfig> was changed successfully! ##
29+
```
30+
Also you can execute code in silent mode - just pass `silent: true` to `Change::Process` service.
31+
4. Current user will be changed to next in order:
32+
```bash
33+
[user]
34+
35+
# name = Sample User 1
36+
37+
# name = Sample User 2
38+
39+
name = Sample User 3
40+
```
41+
### Script-usage:
42+
Simplified version of application is placed in `script` folder.
43+
1. Move to `script` folder:
44+
```bash
45+
cd script
46+
```
47+
2. Run shell script using
48+
```bash
49+
./guser.sh
50+
```

actions/change.rb

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
require '../application'
1+
require_relative '../application'
22

3-
params = {}
4-
5-
Change::Perform.(params)
3+
Change::Process.()

application.rb

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
require_relative 'lib/loader'
1+
ROOT_PATH = File.dirname(__FILE__)
22

3-
Lib::Loader.()
4-
Change::Process.()
3+
require File.join(ROOT_PATH, 'lib/loader')
4+
5+
Lib::Loader.(ROOT_PATH)

lib/README.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Application skeleton
2+
3+
### Loader
4+
Service that load all skeleton services and classes.
5+
6+
### OperatingSystem
7+
Class for detecting current OS.
8+
9+
### Service
10+
Base service that provides functional-way execution and params validations.
11+
12+
### Concerns::StateMachine
13+
Module that provides common state machine and state machine with multiple field states.
14+
15+
### Error
16+
Base class for errors implementation. Errors requires:
17+
- `column` - service attribute name;
18+
- `error_type` - type of error;
19+
- `options` - related to `error_type`.
20+
21+
### Error::Collection
22+
Collection for errors that provides some additional methods.
23+
24+
### Error::Type
25+
Class that contains constants of types of errors. Additional options for errors with different error types:
26+
27+
|Type |Options |
28+
|------------|--------------------------|
29+
|BLANK |--- |
30+
|INVALID_TYPE|`class_name` - valid class|
31+
|NOT_INCLUDED|`in` - valid collection |
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
44+

lib/concerns/state_machine.rb

+18-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Lib
22
module Concerns
33
module StateMachine
44
def state_machine(column, states)
5-
assign_reader!(column)
5+
assign_reader!(column, states[0])
66

77
states.each do |key|
88
define_method("#{key}!") { instance_variable_set(column, key) }
@@ -11,7 +11,8 @@ def state_machine(column, states)
1111
end
1212

1313
def multi_state_machine(column, states)
14-
assign_reader!(column)
14+
assign_reader!(column, Hash.new)
15+
assign_initializing!(column, states[0])
1516

1617
states.each do |key|
1718
define_method "#{key}!" do |field|
@@ -22,6 +23,10 @@ def multi_state_machine(column, states)
2223
instance_variable_get("@#{column}")[field] == key
2324
end
2425

26+
define_method "not_#{key}?" do |field|
27+
instance_variable_get("@#{column}")[field] != key
28+
end
29+
2530
define_method "has_#{key}?" do
2631
instance_variable_get("@#{column}").values.any? { |state| state == key }
2732
end
@@ -30,9 +35,17 @@ def multi_state_machine(column, states)
3035

3136
private
3237

33-
def assign_reader!(column)
34-
define_method(column) do
35-
eval("@#{column} ||= #{Hash.new}")
38+
def assign_reader!(column, state)
39+
define_method("#{column}") do
40+
eval("@#{column} ||= #{state}")
41+
end
42+
end
43+
44+
def assign_initializing!(column, state)
45+
define_method "init_#{column}!" do |fields|
46+
init_states = Hash[fields.map { |field| [field, state] }]
47+
48+
instance_variable_set("@#{column}", init_states)
3649
end
3750
end
3851
end

lib/loader.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
module Lib
22
class Loader
33
class << self
4-
def call
4+
def call(root_path)
5+
@root_path = root_path
6+
57
require!
68
end
79

810
private
911

12+
attr_reader :root_path
13+
1014
def require!
1115
app_folders.each { |folder| require_folder(folder) }
1216
end
@@ -20,7 +24,7 @@ def app_folders
2024
end
2125

2226
def path(folder)
23-
File.join('.', "#{folder}/**/*.rb")
27+
File.join(root_path, "#{folder}/**/*.rb")
2428
end
2529
end
2630
end

lib/operating_system.rb

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Lib
2+
class OperatingSystem
3+
class << self
4+
def windows?
5+
!(RUBY_PLATFORM =~ WINDOWS_REGEXP).nil?
6+
end
7+
8+
def mac?
9+
!(RUBY_PLATFORM =~ MAC_REGEXP).nil?
10+
end
11+
12+
def unix?
13+
!windows?
14+
end
15+
16+
def linux?
17+
unix? && !mac?
18+
end
19+
20+
private
21+
22+
WINDOWS_REGEXP = /cygwin|mswin|mingw|bccwin|wince|emx/
23+
MAC_REGEXP = /darwin/
24+
end
25+
end
26+
end

lib/service.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ def run
1414
@errors = Error::Collection.new
1515

1616
validate!
17-
return invalid_params! unless valid?
17+
return invalid_params! unless service_valid?
1818

1919
call
2020
end
2121

2222
def validate!; end
2323

24-
def valid?
24+
def service_valid?
2525
errors.empty?
2626
end
2727

script/guser.rb

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
class ChangeGitUser
2+
def self.call(args = {})
3+
new(args).call
4+
end
5+
6+
def initialize(params = {})
7+
@silent = params[:silent]
8+
9+
prepare!
10+
end
11+
12+
def call
13+
read!
14+
return unless valid?
15+
16+
change!
17+
write!
18+
end
19+
20+
private
21+
22+
STATES = [:initialized, :commented, :replaced]
23+
FIELDS = [:name, :email]
24+
FILE_NAME = "#{ENV['HOME']}/.gitconfig"
25+
26+
attr_reader :config, :silent, :left_border, :right_border, :field_states
27+
28+
STATES.each do |key|
29+
define_method "#{key}!" do |field|
30+
@field_states[field] = key
31+
end
32+
33+
define_method "#{key}?" do |field|
34+
field_states[field] == key
35+
end
36+
37+
define_method "has_#{key}?" do
38+
field_states.values.any? { |state| state == key }
39+
end
40+
end
41+
42+
def prepare!
43+
@field_states = Hash.new
44+
FIELDS.each { |field| initialized!(field) }
45+
end
46+
47+
def read!
48+
@config = File.read(FILE_NAME).split("\n")
49+
end
50+
51+
def valid?
52+
@left_border = config.find_index{ |row| row.include? '[user]' }
53+
return echo('## There is not user configurations section! ##') if left_border.nil?
54+
55+
@left_border += 1
56+
set_right_border!
57+
58+
return echo('## User configurations section is empty! ##') if left_border >= right_border
59+
true
60+
end
61+
62+
def change!
63+
begin
64+
(left_border..right_border).each { |index| change_row!(index) }
65+
end while has_commented?
66+
end
67+
68+
def write!
69+
File.open(FILE_NAME, "w") { |file| file.puts(config) }
70+
echo('## Config was changed successfully! ##')
71+
rescue
72+
echo('## Read-only access! ##')
73+
end
74+
75+
def set_right_border!
76+
local_right_border = config[left_border..-1].find_index{ |row| row.match(/\A[\[].*[\]]/) }
77+
@right_border = local_right_border.nil? ? config.size - 1 : local_right_border + left_border
78+
end
79+
80+
def change_row!(index)
81+
FIELDS.each { |field| replace(index, field) }
82+
end
83+
84+
def replace(index, field)
85+
patterns = patterns(field)
86+
87+
case
88+
when config[index].include?(patterns[:commented]) && commented?(field)
89+
config[index].gsub!(patterns[:commented], patterns[:uncommented])
90+
echo("## \"#{config[index].split('=').last.lstrip}\" is current user ##") if field == :name
91+
replaced!(field)
92+
when config[index].include?(patterns[:uncommented]) && initialized?(field)
93+
config[index].gsub!(patterns[:uncommented], patterns[:commented])
94+
commented!(field)
95+
end
96+
end
97+
98+
def patterns(field)
99+
{
100+
commented: "\t# #{field}",
101+
uncommented: "\t#{field}"
102+
}
103+
end
104+
105+
def echo(text)
106+
puts(text) unless silent
107+
end
108+
end
109+
110+
ChangeGitUser.()

script/guser.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
ruby guser.rb

services/change/file_service.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def prepare!
3232
end
3333

3434
def read!
35-
puts File.read(file_path)
35+
File.read(file_path)
3636
end
3737

3838
def write!
@@ -51,4 +51,3 @@ def file_name
5151
end
5252
end
5353
end
54-

0 commit comments

Comments
 (0)