lib/subtrac.rb in keithsalisbury-subtrac-0.1.7 vs lib/subtrac.rb in keithsalisbury-subtrac-0.1.9

- old
+ new

@@ -39,72 +39,137 @@ require 'erb' require 'fileutils' require 'subtrac/version' module Subtrac - SUBTRAC_ROOT = File.join(File.dirname(__FILE__), "subtrac") - DEV_ENV = 'development' # should be a system environment var - - attr_accessor :server_name, :server_hostname, :server_ip, :default_client, :default_project, :install_dir, :docs_dir, :conf_dir, :locations_dir, :svn_dir, :trac_dir, :temp_dir + SUBTRAC_ROOT = "#{File.dirname(__FILE__)}/" unless defined?(SUBTRAC_ROOT) + SUBTRAC_ENV = (ENV['SUBTRAC_ENV'] || 'development').dup unless defined?(SUBTRAC_ENV) + USER_CONFIG = 'config/user.yml' + + class << self + + # The Configuration instance used to configure the Subtrac environment + def configuration + @@configuration + end + + def configuration=(configuration) + @@configuration = configuration + end + + def initialized? + @initialized || false + end + + def initialized=(initialized) + @initialized ||= initialized + end + + def root + Pathname.new(SUBTRAC_ROOT) if defined?(SUBTRAC_ROOT) + end + + def public_path + @@public_path ||= self.root ? File.join(self.root, "public") : "public" + end + + def subtrac_path + @@subtrac_path ||= self.root ? File.join(self.root, "subtrac") : "subtrac" + end + + def public_path=(path) + @@public_path = path + end + + def docs_dir + @@docs_dir ||= File.join(@install_dir,@APP_CONFIG[:dirs][:docs]) + end + + def docs_dir=(dir) + @@docs_dir = dir + end + + def svn_dir + @@svn_dir ||= File.join(@install_dir,@APP_CONFIG[:dirs][:svn]) + end + + def svn_dir=(dir) + @@svn_dir = dir + end + + def trac_dir + @@trac_dir ||= File.join(@install_dir,@APP_CONFIG[:dirs][:trac]) + end + + def trac_dir=(dir) + @@trac_dir = dir + end + + def temp_dir + @@temp_dir ||= File.join(@install_dir,@APP_CONFIG[:dirs][:temp]) + end + + def temp_dir=(dir) + @@temp_dir = dir + end + + def log_dir + @@log_dir ||= File.join(@install_dir,@APP_CONFIG[:dirs][:log]) + end + + def log_dir=(dir) + @@log_dir = dir + end + + def locations_dir + @@locations_dir ||= File.join(@install_dir,@APP_CONFIG[:dirs][:locations]) + end + + def locations_dir=(dir) + @@locations_dir = dir + end + + end + module Commands class Install def initialize(args, options) Subtrac.load_config() Subtrac.install(args,options) end end class Create def initialize(args, options) - project = ask("What is the name of the project you would like to create? ") if !options.project - client = ask("Which client is this project for? ") if !options.client + options.project = ask("What is the name of the project you would like to create? ") if !options.project + options.client = ask("Which client is this project for? ") if !options.client + # this needs to load the updated configuration? Subtrac.load_config() Subtrac.create_project(options.project,options.client) end end end - - # Install - def self.install(args,options) - puts "\n==== Installing development server files ====" - # Ask if the user agrees (yes or no) - confirm_clean = agree("Are you sure you would like a clean install? [Y/n]") if options.clean - # clear previous data - clean() if confirm_clean - # right lets install - change_server_name = agree("The default server name is \"#{@server_name}\". Would you like to change this? [Y/n]") - @server_name = ask("What would you like to call your new development server? ") if change_server_name - - create_environment_directories() - install_common_files() - create_virtual_host() - confirm_default_client = agree("Do you want to create a default client project? [Y/n]") - # create default project and client - if confirm_default_client - change_client = agree("The default client name is \"#{@default_client}\". Would you like to change this? [Y/n]") - @default_client = ask("What client name would you like to use? ") if change_client - change_project = agree("The default project name is \"#{@default_project}\". Would you like to change this? [Y/n]") - @default_project = ask("What would you like to call your new project? ") if change_project - create_project(@default_project,@default_client) - end - end - + # Loads the configuration YML file def self.load_config + # TODO: We need to refactor this code so it will load the default configuration only if one has not been created puts "\n==== Loading configuration file ====" # load configuration file + file_path = File.join(subtrac_path, USER_CONFIG) + file_path = File.join(subtrac_path,"/config/config.yml") if not File.exists?(file_path) + puts "Attempting to read config file: #{file_path}" begin - raw_config = File.read(SUBTRAC_ROOT + "/config/config.yml") + raw_config = File.read(file_path) yamlFile = YAML.load(raw_config) rescue Exception => e raise StandardError, "Config #{file_path} could not be loaded." end if yamlFile - if yamlFile[DEV_ENV] - @APP_CONFIG = yamlFile[DEV_ENV] + if yamlFile[SUBTRAC_ENV] + @APP_CONFIG = yamlFile[SUBTRAC_ENV] else - raise StandardError, "config/config.yml exists, but doesn't have a configuration for DEV_ENV=#{DEV_ENV}." + raise StandardError, "config/config.yml exists, but doesn't have a configuration for #{SUBTRAC_ENV}." end else raise StandardError, "config/config.yml does not exist." end puts "\n==== Installation options ====" @@ -116,29 +181,73 @@ @default_client = @APP_CONFIG[:default_client] @default_project = @APP_CONFIG[:default_project] @install_dir = File.expand_path(@APP_CONFIG[:installation_dir]) - @docs_dir = File.join(@install_dir,@APP_CONFIG[:dirs][:docs]) @conf_dir = @APP_CONFIG[:apache2_conf] - @locations_dir = File.join(@install_dir,@APP_CONFIG[:dirs][:conf_locations]) - @svn_dir = File.join(@install_dir,@APP_CONFIG[:dirs][:svn]) - @trac_dir = File.join(@install_dir,@APP_CONFIG[:dirs][:trac]) - @temp_dir = File.join(@install_dir,@APP_CONFIG[:dirs][:temp]) - @log_dir = File.join(@install_dir,@APP_CONFIG[:dirs][:log]) @ldap_bind_dn = @APP_CONFIG[:ldap][:bind_dn] @ldap_bind_password = @APP_CONFIG[:ldap][:bind_password] @ldap_url = @APP_CONFIG[:ldap][:host] + + end + + + # Install + def self.install(args,options) + puts "\n==== Installing development server files ====" + # check where we are installing + change_install_dir = agree("The default installation directory is \"#{@install_dir}\". Would you like to change this? [Y/n]") + @install_dir = ask("Where would you like to install this server?") if change_install_dir + + unless !File.directory?(@install_dir) + # Ask if the user agrees (yes or no) + confirm_clean = agree("Err, that dirctory's got stuff init. You sure you want me to overwrite? [Y/n]") if options.clean + end + # right lets install + change_server_name = agree("The default server name is \"#{@server_name}\". Would you like to change this? [Y/n]") + @server_name = ask("What would you like to call your new development server? ") if change_server_name + + create_environment_directories(confirm_clean) + install_common_files() + # TODO: Need to check for default client/project before creating virtual host + # otherwise we need remove the rewrite rule + create_virtual_host() + confirm_default_client = agree("Do you want to create a default client project? [Y/n]") + # create default project and client + if confirm_default_client + change_client = agree("The default client name is \"#{@default_client}\". Would you like to change this? [Y/n]") + @default_client = ask("What client name would you like to use? ") if change_client + change_project = agree("The default project name is \"#{@default_project}\". Would you like to change this? [Y/n]") + @default_project = ask("What would you like to call your new project? ") if change_project + create_project(@default_project,@default_client) + end + save_config() end private - # Ask the user for configuration details - def self.get_config + # Write the changes configuration to disk + def self.save_config + # save the things that might have changed + @APP_CONFIG[:server_name] = @server_name + @APP_CONFIG[:server_hostname] = @server_hostname + @APP_CONFIG[:server_ip] = @server_ip + @APP_CONFIG[:default_client] = @default_client + @APP_CONFIG[:default_project] = @default_project + + @APP_CONFIG[:installation_dir] = @install_dir + @APP_CONFIG[:apache2_conf] = @conf_dir + + @APP_CONFIG[:ldap][:bind_dn] = @ldap_bind_dn + @APP_CONFIG[:ldap][:bind_password] = @ldap_bind_password + @APP_CONFIG[:ldap][:host] = @ldap_url + + file_path = File.join(subtrac_path, USER_CONFIG) + open(file_path, 'w') {|f| YAML.dump({SUBTRAC_ENV => @APP_CONFIG}, f)} end # creates a directory if it does not exist def self.create_if_missing *names names.each do |name| @@ -165,124 +274,132 @@ end # creates a new virtual host and reloads apache and enables the new virtual host def self.create_virtual_host puts "\n==== Creating new virtual host ====" - vhost_template = File.join(SUBTRAC_ROOT, @APP_CONFIG[:templates][:virtual_host]) + vhost_template = File.join(subtrac_path, @APP_CONFIG[:templates][:virtual_host]) + puts "group apache tempalte: #{vhost_template}" new_vhost = File.join(@conf_dir,@server_hostname) - parse_template(vhost_template,new_vhost,binding) + puts "group apache file: #{new_vhost}" + parse_template(vhost_template,new_vhost,binding) if SUBTRAC_ENV != 'test' # reload apache configuration - `/etc/init.d/apache2 force-reload` if DEV_ENV != 'test' - `a2ensite #{@server_hostname}` if DEV_ENV != 'test' + `/etc/init.d/apache2 force-reload` if SUBTRAC_ENV != 'test' + `a2ensite #{@server_hostname}` if SUBTRAC_ENV != 'test' end def self.install_common_files puts "\n==== Installing common files ====" # TODO: implement a mask for .svn folders # TODO: refactor /common to the app config - common_dir = File.join(SUBTRAC_ROOT, "common") - source = Dir.glob("#{common_dir}/.") - dest = @docs_dir - FileUtils.cp_r(source,dest) + FileUtils.cp_r(Dir.glob(File.join(subtrac_path, "common/.")),docs_dir) + FileUtils.cp_r(Dir.glob(File.join(subtrac_path, "shared/.")),File.join(trac_dir, ".shared")) end - def self.create_environment_directories + def self.create_environment_directories(overwrite=false) puts "\n==== Creating new environment directories ====" + FileUtils.rm_rf @install_dir if overwrite + create_if_missing @install_dir # create the environment directories @APP_CONFIG[:dirs].each do |key, value| - create_if_missing File.join(@install_dir,value) + dir = File.join(@install_dir,value) + create_if_missing dir end end - def self.clean - puts "\n==== Remove old data if exists ====" - @APP_CONFIG[:dirs].each do |key, value| - #TODO: Ask for confirmation - yes,no,All - puts "Deleting #{value}" - FileUtils.rm_rf value - end - end - def self.create_client(name) puts "\n==== Create a new client called #{name} ====" client_name = name.downcase # create apache configuration - location_template = File.join(SUBTRAC_ROOT, @APP_CONFIG[:templates][:location]) - location_conf = File.join(@locations_dir,"#{client_name}.conf") + puts "subtrac_path: #{subtrac_path}" + puts "templates_location: #{@APP_CONFIG[:templates][:location]}" + location_template = File.join(subtrac_path, @APP_CONFIG[:templates][:location]) + puts "location_template: #{location_template}" + location_conf = File.join(locations_dir,"#{client_name}.conf") + puts "location_conf: #{location_conf}" parse_template(location_template,location_conf,binding) - `/etc/init.d/apache2 force-reload` if DEV_ENV != 'test' + `/etc/init.d/apache2 force-reload` if SUBTRAC_ENV != 'test' # create svn+trac directory - create_if_missing File.join(@svn_dir,client_name) - create_if_missing File.join(@trac_dir,client_name) + create_if_missing File.join(svn_dir,client_name) + create_if_missing File.join(trac_dir,client_name) end def self.create_project(project, client) puts "\n==== Create a new project called #{project} for #{client} ====" client_name = client.downcase project_name = project.downcase # create client directory if needed - create_client(client_name) if (!File.directory? File.join(@svn_dir,client_name)) + create_client(client_name) if (!File.directory? File.join(svn_dir,client_name)) - svn_dir = File.join(@svn_dir,client_name,project_name) - trac_dir = File.join(@trac_dir,client_name,project_name) - if (File.directory? svn_dir) then + project_svn_dir = File.join(svn_dir,client_name,project_name) + project_trac_dir = File.join(trac_dir,client_name,project_name) + + # TODO: Need to change this to use a 'groups' yml file + if (File.directory? project_svn_dir) then raise StandardError, "A project called #{project} already exists in the #{client} repository. Would you like to replace it?" end # create new project directories - create_if_missing svn_dir - create_if_missing trac_dir + say("Create project directories...") + create_if_missing project_svn_dir + create_if_missing project_trac_dir - project_template = File.join(SUBTRAC_ROOT, @APP_CONFIG[:templates][:projects],@APP_CONFIG[:default_project_template]) + project_template = File.join(subtrac_path, @APP_CONFIG[:templates][:projects],@APP_CONFIG[:default_project_template]) # copy template svn project to a temp folder, then svn import it into the repo + say("Create temporary project directory and copy template files...") svn_template_dir = File.join(project_template,"svn") - temp_dir = File.join(@temp_dir,project_name) - FileUtils.cp_r(svn_template_dir,temp_dir) + project_temp_dir = File.join(temp_dir,project_name) + FileUtils.cp_r(svn_template_dir,project_temp_dir) # create a new subversion repository say("Creating a new subversion repository...") - `svnadmin create #{svn_dir}` if DEV_ENV != 'test' + `svnadmin create #{project_svn_dir}` if SUBTRAC_ENV != 'test' # import into svn - `svn import #{temp_dir} file:///#{svn_dir} --message "initial import"` if DEV_ENV != 'test' + say("Importing temporary project into the new subversion repository...") + `svn import #{project_temp_dir} file:///#{project_svn_dir} --message "initial import"` if SUBTRAC_ENV != 'test' # delete the temporary directory - FileUtils.rm_r(temp_dir, :force => true) + FileUtils.rm_r(project_temp_dir, :force => true) # create a new trac site say("Creating a new trac site...") - result = `trac-admin #{trac_dir} initenv #{project_name} sqlite:#{trac_dir}/db/trac.db svn #{svn_dir}` if DEV_ENV != 'test' - FileUtils.chown_R('www-data', 'www-data', trac_dir, :verbose => true) if DEV_ENV != 'test' - FileUtils.mkdir_p("#{trac_dir}/conf") if DEV_ENV == 'test' # fake the folder for tests + result = `trac-admin #{project_trac_dir} initenv #{project_name} sqlite:#{project_trac_dir}/db/trac.db svn #{project_svn_dir}` if SUBTRAC_ENV != 'test' + FileUtils.chown_R('www-data', 'www-data', project_trac_dir, :verbose => true) if SUBTRAC_ENV != 'test' + FileUtils.mkdir_p("#{project_trac_dir}/conf") if SUBTRAC_ENV == 'test' # fake the folder for tests + say("Installing trac configuration...") # install shared trac.ini - trac_ini_template = File.join(SUBTRAC_ROOT, @APP_CONFIG[:templates][:trac]) - parse_template(trac_ini_template,File.join(trac_dir,"/conf/trac.ini"),binding) + trac_ini_template = File.join(subtrac_path, @APP_CONFIG[:templates][:trac]) + parse_template(trac_ini_template,File.join(project_trac_dir,"/conf/trac.ini"),binding) # remove custom templates directory so trac uses the shared location (while we wait for trac patch) - FileUtils.rm_rf("#{trac_dir}/templates") + FileUtils.rm_rf("#{project_trac_dir}/templates") - say("Setting up default trac permission...") + say("Setting up default trac permissions...") # set up trac permissions @APP_CONFIG[:trac][:permissions].each do |key, value| - `trac-admin #{trac_dir} permission add #{key} #{value}` if DEV_ENV != 'test' + `trac-admin #{project_trac_dir} permission add #{key} #{value}` if SUBTRAC_ENV != 'test' end say("Adding default trac wiki pages...") # this needs to loop through the directory and import all pages Dir.foreach("#{project_template}/trac/wiki/.") do |file| # do something with the file here unless ['.', '..','.svn'].include? file - temp_file = File.join(@temp_dir,file) + temp_file = File.join(temp_dir,file) parse_template(File.join(project_template,"trac/wiki",file), temp_file, binding) - `trac-admin #{trac_dir} wiki import #{file} #{temp_file}` if DEV_ENV != 'test' + `trac-admin #{project_trac_dir} wiki import #{file} #{temp_file}` if SUBTRAC_ENV != 'test' FileUtils.rm(temp_file) end end - + + # run trac upgrade + say("Upgrading the trac installation...") + `trac-admin #{project_trac_dir} upgrade` if SUBTRAC_ENV != 'test' + end end