201 lines
4.9 KiB
Ruby
201 lines
4.9 KiB
Ruby
module Kook
|
|
class App
|
|
CONFIG_DIR = File.join ENV['HOME'], '.config', 'kook'
|
|
CONFIG_FILE = File.join CONFIG_DIR, 'config.yml'
|
|
|
|
attr_accessor :verbose
|
|
|
|
class ExistingProject < RuntimeError ; end
|
|
class MissingProject < RuntimeError ; end
|
|
class MissingProjectFile < RuntimeError ; end
|
|
|
|
def initialize
|
|
super
|
|
@projects = {}
|
|
@config_file = CONFIG_FILE
|
|
@verbose = false
|
|
@current_project = nil
|
|
end
|
|
|
|
def list_projects
|
|
projects_exist = false
|
|
|
|
@projects.each do |project_name,project_data|
|
|
projects_exist = true
|
|
exist = File.exist? project_data.path
|
|
display_path = (
|
|
project_data.path.clone
|
|
.gsub!(/#{ENV['HOME']}/,'~')
|
|
.send(exist ? :green : :red)
|
|
)
|
|
puts "%- 24s %s" % [project_name, display_path]
|
|
end
|
|
STDERR.puts "No project found." if not projects_exist
|
|
end
|
|
|
|
def add_project project_name, project_path=nil
|
|
raise ExistingProject if @projects.has_key? project_name
|
|
|
|
project_data = Project.new project_name
|
|
project_data.path = project_path
|
|
@projects[project_name] = project_data
|
|
save
|
|
end
|
|
|
|
def edit_project project_name
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
|
|
project_config_path = File.join @projects[project_name].path, "Kookfile"
|
|
system "%s %s" % [ENV['EDITOR'], project_config_path]
|
|
end
|
|
|
|
def remove_project project_name
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
@projects.delete project_name
|
|
save
|
|
end
|
|
|
|
def fire_project project_name
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
|
|
project_path = @projects[project_name].path
|
|
@projects[project_name].fire
|
|
|
|
end
|
|
|
|
def add_view project_name, view_name, view_path=nil
|
|
View.validate_name view_name
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
|
|
project_path = @projects[project_name].path
|
|
|
|
# simplify if current dir is a subdir of project base
|
|
if view_path == project_path then
|
|
view_path = '.'
|
|
else
|
|
view_path = (view_path
|
|
.gsub(/^#{project_path}\//,'')
|
|
.gsub(/\/$/,'')
|
|
)
|
|
end
|
|
|
|
@projects[project_name].create_view view_name, view_path
|
|
save
|
|
end
|
|
|
|
def add_command project_name, view_name, command
|
|
View.validate_name view_name
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
|
|
@projects[project_name].add_command view_name, command
|
|
save
|
|
end
|
|
|
|
def remove_command project_name, view_name, command_idx
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
|
|
@projects[project_name].remove_command view_name, command_idx
|
|
save
|
|
end
|
|
|
|
def list_views project_name
|
|
raise MissingProject if not @projects.has_key? project_name
|
|
|
|
@projects[project_name].each_view do |view_name,view_data|
|
|
puts "%- 24s %s" % [view_name, view_data.path]
|
|
|
|
if view_data.commands.empty?
|
|
next
|
|
end
|
|
|
|
view_data.commands.each_index do |idx|
|
|
puts "* % 4d. %s" % [idx, view_data.commands[idx]]
|
|
end
|
|
end
|
|
end
|
|
|
|
def load config_file=nil
|
|
config_file ||= @config_file
|
|
@config_file = config_file
|
|
|
|
if not File.exist? config_file then
|
|
STDERR.puts "Missing config file #{config_file}" if @verbose
|
|
return false
|
|
end
|
|
|
|
|
|
STDERR.puts "Loading main configuration #{config_file}..." if @verbose
|
|
yaml = YAML::load_file config_file
|
|
|
|
yaml['projects'].each do |project_name,project_path|
|
|
# pp project_path
|
|
#project_path = @config['projects'][project]
|
|
project_file = File.join project_path, "Kookfile"
|
|
|
|
STDERR.puts "Loading sub configuration #{project_file}..." if @verbose
|
|
if File.exist? project_file then
|
|
subconfig = YAML::load_file project_file
|
|
next if not subconfig
|
|
|
|
@projects[project_name] = Project.from_hash subconfig, project_path
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
def save config_file=nil
|
|
config_file ||= @config_file
|
|
config_dir = File.dirname config_file
|
|
if not File.exist? config_dir then
|
|
FileUtils.mkdir_p config_dir
|
|
end
|
|
|
|
STDERR.puts "Saving to #{config_file}" if @verbose
|
|
|
|
@projects.each do |project_name,project_data|
|
|
# FIXME: test if project configuration is dirty
|
|
project_file = File.join project_data.path, "Kookfile"
|
|
|
|
File.open(project_file, "w") do |file|
|
|
file.puts "# This file was generated by Kook #{VERSION}"
|
|
file.puts "# You can get it at https://github.com/glenux/kook"
|
|
file.write project_data.to_hash.to_yaml
|
|
end
|
|
end
|
|
|
|
File.open(config_file, "w") do |file|
|
|
file.write to_yaml
|
|
end
|
|
self
|
|
end
|
|
|
|
def current_project= project_name
|
|
# FIXME: validate project name
|
|
@current_project = project_name
|
|
end
|
|
|
|
def current_project
|
|
return @current_project if not @current_project.nil?
|
|
|
|
current_dir = Dir.pwd
|
|
@projects.each do |project_name,project|
|
|
if current_dir =~ /^#{project.path}/ then
|
|
return project_name
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
private
|
|
|
|
def to_yaml
|
|
return {
|
|
'global' => {},
|
|
'projects' => Hash[@projects.map{ |p,v| [v.name, v.path] }]
|
|
}.to_yaml
|
|
end
|
|
|
|
end
|
|
end
|