diff --git a/bin/kook.rb b/bin/kook.rb new file mode 100755 index 0000000..5c5df4b --- /dev/null +++ b/bin/kook.rb @@ -0,0 +1,164 @@ +#!/usr/bin/env ruby + +require 'singleton' +require 'yaml' +require 'pp' + +module Kook + class Project + attr_reader :name, :path + attr_accessor :description + PROJECT_NAME_MIN_SIZE = 4 + PROJECT_NAME_MAX_SIZE = 12 + + def initialize project_name + self.class.validate_name project_name + @name = project_name + @description = nil + @path = nil + @views = {} + end + + def path= path + # FIXME: validate current path exists + # + if not (File.exist? path and File.directory? path) then + raise "PathDoesNotExist #{path}" + end + @path = path + end + + def add_view view + raise "ExistingView #{view.name}" if @views.has_key? view.name + @views[view.name] = view + end + + def remove_view view_name + View.validate_name view_name + return @view.delete(view_name) + end + + def to_hash + return { + project: @name, + description: @description, + path: @path, + views: @views.values.map{ |v| v.to_hash } + } + end + + def from_hash project_hash + @name = project_hash[:project] + @description = project_hash[:description] + @path = project_hash[:path] + project_hash[:views].each do |hash_view| + view = View.new do |v| + v.from_hash hash_view + end + add_view view + end + end + + def self.validate_name name + raise "TooShortProjectIdentifier" if name.size < Project::PROJECT_NAME_MIN_SIZE + raise "TooLongProjectIdentifier" if name.size > Project::PROJECT_NAME_MAX_SIZE + if not name =~ /^\w+$/ then + raise "BadProjectIdentifier #{name}" + end + return true + end + end + + class View + attr_reader :name, :path + attr_accessor :description + VIEW_NAME_MIN_SIZE = 4 + VIEW_NAME_MAX_SIZE = 12 + + def initialize name + self.class.validate_name name + @name = name + @path = nil + @commands = {} + end + + def self.validate_name name + raise "TooShortViewIdentifier" if name.size < View::VIEW_NAME_MIN_SIZE + raise "TooLongViewIdentifier" if name.size > View::VIEW_NAME_MAX_SIZE + if not name =~ /^[\w-]+$/ then + raise "BadViewIdentifier #{name}" + end + return true + end + + def to_hash + return { + view: @name, + path: @path, + commands: @commands.values + } + end + + def from_hash view_hash + @name = view_hash[:view] + @path = view_hash[:path] + @commands = view_hash[:commands] + end + end + + class Command + end + + class Config + include Singleton + + def create_project project_name + raise "ExistingProject" if @projects.has_key? project_name + + @projects[project_name] = Project.new project_name + end + + def create_view project_name, view_name + Project.validate_name project_name + View.validate_name view_name + raise "MissingProject" if not @projects.has_key? project_name + + view = View.new view_name + @projects[project_name].add_view view + end + + def to_yaml + return { + global: {}, + projects: @projects.values.map{ |p| p.to_hash } + }.to_yaml + end + + private + + def initialize + @projects = {} + super + end + end + +end + +class Test + def self.test_project_create + config = Kook::Config.instance + config.create_project 'proj' + end + + def self.test_view_create + config = Kook::Config.instance + config.create_view 'proj', 'proj-root' + config.create_view 'proj', 'proj-base' + config.create_view 'proj', 'proj-3' + + puts config.to_yaml + end +end + +Test.test_project_create +Test.test_view_create