Skip to content

set文羅列とdelete文羅列を入力すると、deleteを適用したset文羅列にできる差分 #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions exe/junoser-apply
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby

require 'optparse'
require 'pathname'

$: << File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
require 'junoser'


command = :apply
opts = OptionParser.new do |opts|
opts.banner = 'junoser-apply: apply commands to config. (delete)'
opts.define_head 'Usage: junoser-apply [path]'

opts.on_tail '-h', '--help', 'Show this message' do
puts opts
exit
end
end
opts.parse!
case command
when :apply
puts Junoser::Cli.apply($<)
else
puts opts
abort
end
27 changes: 27 additions & 0 deletions exe/junoser-compare
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby

require 'optparse'
require 'pathname'

$: << File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
require 'junoser'


command = :compare
opts = OptionParser.new do |opts|
opts.banner = 'junoser-compare: output difference between two configs'
opts.define_head 'Usage: junoser-compare [path] [path]'

opts.on_tail '-h', '--help', 'Show this message' do
puts opts
exit
end
end
opts.parse!
case command
when :compare
puts Junoser::Cli.compare($<)
else
puts opts
abort
end
7 changes: 7 additions & 0 deletions lib/junoser/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ def struct(io_or_string)
Junoser::Display::Structure.new(io_or_string).transform
end

def apply(io_or_string)
Junoser::Display::Delete.new(io_or_string).apply
end

def compare(io_or_string)
Junoser::Display::Compare.new(io_or_string).diff
end

private

Expand Down
2 changes: 2 additions & 0 deletions lib/junoser/display.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'junoser/display/set'
require 'junoser/display/structure'
require 'junoser/display/delete'
require 'junoser/display/compare'

module Junoser
module Display
Expand Down
175 changes: 175 additions & 0 deletions lib/junoser/display/compare.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
require 'junoser/input'
require 'junoser/display/config_store'
require 'junoser/parser'
require 'junoser/transformer'

module Junoser
module Display
class Compare
def initialize(io_or_string)
@input = io_or_string
end
def diff
master,branch = Junoser::Input.new(@input).read2
master_struct = Junoser::Display::Structure.new(master).transform
branch_struct = Junoser::Display::Structure.new(branch).transform
generate_diff_set_and_delete(master_struct,branch_struct)
end

private

def generate_diff_set_and_delete(master,branch)
master_hash = struct_to_hash(master)
branch_hash = struct_to_hash(branch)
set_hash = hash_cmp(master_hash,branch_hash,"set")
delete_hash = hash_cmp(master_hash,branch_hash,"delete")
set_struct = hash_to_struct(set_hash)
delete_struct = hash_to_struct(delete_hash)
set_ = Junoser::Display::Set.new(set_struct).transform
delete_ = Junoser::Display::Set.new(delete_struct).transform
delete_.gsub!(/^set /, 'delete ')
delete_ << "\n" << set_
end


def hash_cmp(master,branch,delete_or_set,depth = 0)
if delete_or_set == "set" and depth == 0
tmp = master
master = branch
branch = tmp
end
answer = {}
master.each do |key,value|
if branch.key?(key)
if not including(value,branch[key])
answer.store(key,hash_cmp(value,branch[key],delete_or_set,depth + 1))
end
else
if delete_or_set == "delete"
answer.store(key,{})
elsif delete_or_set == "set"
answer.store(key,value)
end
end
end
answer
end

def including(hash,hash2)
# hash <= hash2
if hash.keys - hash2.keys == []
if hash == {}
return true
else
hash.each do |key,value|
if not including(value,hash2[key])
return false
end
end
end
else
return false
end
true
end

def struct_to_hash(struct)
struct.gsub!(/\n/, '')
hash = struct_to_first_hash(struct)
hash_value_to_hash(hash)
end

def hash_value_to_hash(hash)
hash.each do |key,value|
if value != {}
hash.store(key,struct_to_first_hash(value))
hash_value_to_hash(hash[key])
end
end
end

def struct_to_first_hash(struct)
hash = {}
key,value = "",""
state = 0
struct.strip!
struct.chars.each do |c|
case state
when 0 then # initial state
case c
when "{" then
state += 1 # 1
when ";" then
hash.store(key.strip,value.strip)
key,value = "",""
else
key << c
end
when 1 then
case c
when "{" then
value << c
state += 1 # 2
when "}" then
hash.store(key.strip,value.strip)
key,value = "",""
state -= 1 # 0
else
value << c
end
else
case c
when "{" then
value << c
state += 1
when "}" then
value << c
state -= 1
else
value << c
end
end
end
hash
end

def apply_delete(set_hash,delete_line_hash)
key,hash = ret_first_key_and_value(delete_line_hash)
if hash == {}
set_hash.delete(key)
set_hash
else
apply_delete(set_hash[key],hash)
end
set_hash
end

def hash_to_struct(hash)
struct = ""
hash_to_struct_iter(hash){|str| struct << str}
struct
end

def hash_to_struct_iter(hash,&block)
hash.each_with_index do |(key,value),i|
yield key
if value != {}
yield "{\n"
hash_to_struct_iter(value,&block)
else
yield ";\n"
end
if i == hash.length - 1
yield "}\n"
end
end
end

def ret_first_key_and_value(hash)
hash.each do |key,hash|
return key,hash
end
end
end
end
end
133 changes: 133 additions & 0 deletions lib/junoser/display/delete.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
require 'junoser/input'
require 'junoser/display/config_store'
require 'junoser/parser'
require 'junoser/transformer'

module Junoser
module Display
class Delete
def initialize(io_or_string)
@input = io_or_string
end
def apply
sd = Junoser::Input.new(@input).read.split("\n")
d = sd.grep(/^delete /).map {|l| l.sub(/^delete /, 'set ')}
s = sd.grep(/^set /)
set_struct = Junoser::Display::Structure.new(s.join("\n")).transform
set_h = struct_to_hash(set_struct)
d.each do |delete_line|
begin
delete_line_struct = Junoser::Display::Structure.new(delete_line).transform
delete_line_hash = struct_to_hash(delete_line_struct)
set_h = apply_delete(set_h,delete_line_hash)
rescue
next
end
end

set_struct = hash_to_struct(set_h)
Junoser::Display::Set.new(set_struct).transform
end

private

def struct_to_hash(struct)
struct.gsub!(/\n/, '')
hash = struct_to_first_hash(struct)
hash_value_to_hash(hash)
end

def hash_value_to_hash(hash)
hash.each do |key,value|
if value != {}
hash.store(key,struct_to_first_hash(value))
hash_value_to_hash(hash[key])
end
end
end

def struct_to_first_hash(struct)
hash = {}
key,value = "",""
state = 0
struct.strip!
struct.chars.each do |c|
case state
when 0 then # initial state
case c
when "{" then
state += 1 # 1
when ";" then
hash.store(key.strip,value.strip)
key,value = "",""
else
key << c
end
when 1 then
case c
when "{" then
value << c
state += 1 # 2
when "}" then
hash.store(key.strip,value.strip)
key,value = "",""
state -= 1 # 0
else
value << c
end
else
case c
when "{" then
value << c
state += 1
when "}" then
value << c
state -= 1
else
value << c
end
end
end
hash
end

def apply_delete(set_hash,delete_line_hash)
key,hash = ret_first_key_and_value(delete_line_hash)
if hash == {}
set_hash.delete(key)
set_hash
else
apply_delete(set_hash[key],hash)
end
set_hash
end

def hash_to_struct(hash)
struct = ""
hash_to_struct_iter(hash){|str| struct << str}
struct
end

def hash_to_struct_iter(hash,&block)
hash.each_with_index do |(key,value),i|
yield key
if value != {}
yield "{\n"
hash_to_struct_iter(value,&block)
else
yield ";\n"
end
if i == hash.length - 1
yield "}\n"
end
end
end

def ret_first_key_and_value(hash)
hash.each do |key,hash|
return key,hash
end
end
end
end
end
Loading