Skip to content

Commit

Permalink
Search and compare tokens using hash lookups
Browse files Browse the repository at this point in the history
  • Loading branch information
aonemd committed Dec 3, 2016
1 parent e07c477 commit f9d308b
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 45 deletions.
5 changes: 3 additions & 2 deletions lib/changit.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
require 'changit/version'
require 'changit/git_dir_finder'
require 'changit/config_reader'
require 'changit/lexer/section_token'
require 'changit/lexer/key_value_token'
require 'changit/lexer'
require 'changit/git_dir_finder'
require 'changit/config_merger'
require 'changit/config_reader'
require 'changit/config_writer'

module Changit
Expand Down
32 changes: 32 additions & 0 deletions lib/changit/config_merger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Changit
class ConfigMerger
def initialize(src_config, target_config)
@src = src_config
@target = target_config
end

def merge
src_lexer = Lexer.new(@src)
src_token_hash = src_lexer.token_hash

target_lexer = Lexer.new(@target)
target_token_hash = target_lexer.token_hash

if target_token_hash.empty?
target_lexer = src_lexer
else
target_token_hash.each do |k, v|
if src_token_hash[k]
target_token_hash[k].merge!(src_token_hash[k])
end
end

config_difference = src_token_hash.dup.delete_if { |k, _| target_token_hash.key?(k) }
target_token_hash.merge!(config_difference)
target_lexer.reconstruct_tokens_from_hash!
end

target_lexer
end
end
end
30 changes: 3 additions & 27 deletions lib/changit/config_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,12 @@ def initialize(config, config_files)
@config = config
@config_files = config_files
end

def write
config_lexer = Lexer.new(@config)
config_token_hash = config_lexer.token_hash

def write
@config_files.each do |path|
file_lexer = Lexer.new(File.read(path))
file_token_hash = file_lexer.token_hash

unless file_token_hash.empty?
file_token_hash.each do |k, v|
if config_token_hash[k]
# calling `sort!` changes the order of the key_value pairs
config_token_hash[k].sort!
file_token_hash[k].sort!

config_token_hash[k].each_with_index do |e, i|
if v.include?(e)
# update it
file_token_hash[k][i].rhs = e.rhs
else
# push it
file_token_hash[k].push(e)
end
end
end
end
end
merged_config = ConfigMerger.new(@config, File.read(path)).merge

File.open(path, 'w') { |f| f.write(config_lexer.to_s); f.close }
File.open(path, 'w') { |f| f.write(merged_config.to_s); f.close }
end
end
end
Expand Down
14 changes: 12 additions & 2 deletions lib/changit/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ def to_s
@tokens.map(&:to_s).join
end

def reconstruct_tokens_from_hash!
tokens = []
@token_hash.each do |section, key_value|
tokens << SectionToken.new(section)
key_value.each { |lhs, rhs| tokens << KeyValueToken.new("#{lhs} = #{rhs}") }
end

@tokens = tokens
end

private

def tokenize
Expand All @@ -42,9 +52,9 @@ def to_hash

@tokens.map do |token|
if token.class == SectionToken
token_hash[token] = []
token_hash[token.section] = {}
else
token_hash[token_hash.to_a.last[0]].push(token)
token_hash[token_hash.to_a.last[0]][token.lhs] = token.rhs
end
end

Expand Down
6 changes: 0 additions & 6 deletions lib/changit/lexer/key_value_token.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
module Changit
class Lexer
class KeyValueToken
include Comparable

attr_reader :lhs # left-hand side
attr_accessor :rhs # right-hand side

Expand All @@ -13,10 +11,6 @@ def initialize(key_value)
def to_s
"\t#{@lhs} = #{@rhs}\n"
end

def <=>(another)
self.lhs <=> another.lhs
end
end
end
end
2 changes: 1 addition & 1 deletion lib/changit/lexer/section_token.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Changit
class Lexer
class SectionToken
attr_reader :section
attr_accessor :section

def initialize(section)
@section = section
Expand Down
2 changes: 1 addition & 1 deletion lib/changit/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Changit
VERSION='0.2.0'
VERSION='0.2.2'
end
7 changes: 5 additions & 2 deletions test/config_writer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
class ConfigWriterTest < Minitest::Test
def test_write_to_existing_file
writer = config_writer
expected = Changit::ConfigMerger.new(writer.config, File.read(writer.config_files.first)).merge.to_s

writer.write

assert writer.config == File.read(writer.config_files.first)
assert expected == File.read(writer.config_files.first)
end

def test_write_to_empty_file
Expand All @@ -21,8 +23,9 @@ def test_write_to_empty_file

def config_writer
config = "[user]\n\tname = testname\n\temail = [email protected]\n[core]\n\teditor = vim\n[color]\n\tui = true\n[rebase]\n\tautosquash = true\n".freeze

# this creates an actual file in /tmp you should remove it if you want to
config_files = [File.new("/tmp/config1237879867", 'w')]
config_files = [File.new("/tmp/config1237879867", 'a')]

Changit::ConfigWriter.new(config, config_files)
end
Expand Down
18 changes: 14 additions & 4 deletions test/lexer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,29 @@

class LexerTest < Minitest::Test
def test_tokenize
tokens = lexer.tokens
l = lexer
tokens = l.tokens

assert_kind_of Array, tokens
refute_empty tokens
assert_equal tokens.size, lexer.original_expression.each_line.count
assert_equal tokens.size, l.original_expression.each_line.count
end

def test_to_hash
token_hash = lexer.token_hash
l = lexer
token_hash = l.token_hash

assert_kind_of Hash, token_hash
refute_empty token_hash
assert_kind_of_array Changit::Lexer::SectionToken, token_hash.keys
end

def test_reconstruct_tokens_from_hash
l = lexer
old_tokens = l.tokens
l.token_hash["[user]"].merge!({ 'name' => 'newname' })
l.reconstruct_tokens_from_hash!

refute_equal lexer.tokens, old_tokens
end

private
Expand Down

0 comments on commit f9d308b

Please sign in to comment.