lib/subtrac.rb in keithsalisbury-subtrac-0.1.15 vs lib/subtrac.rb in keithsalisbury-subtrac-1.0.0
- old
+ new
@@ -37,387 +37,192 @@
require 'yaml'
require 'erb'
require 'fileutils'
require 'subtrac/version'
-require 'subtrac/commands'
-
module Subtrac
-
- 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
+ DEV_ENV = 'test' # should be a system environment var
+ DEV_ROOT = Dir.getwd
+ module Commands
+ class Install
+ def initialize(args, options)
+ Devserver.load_config()
+ Devserver.install(args,options)
+ end
end
-
- def configuration=(configuration)
- @@configuration = configuration
+ 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
+ Devserver.load_config()
+ Devserver.create_project(options.project,options.client)
+ end
end
+ end
- def initialized?
- @initialized || false
+ # Install
+ def self.install(args,options)
+ # Ask if the user agrees (yes or no)
+ confirm = agree("Are you sure?") if options.clean
+ if confirm
+ # clear previous data
+ clean()
+ create_environment_directories()
+ else
+ puts "\nAttempt install without overwrites"
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
-
+ install_common_files()
+ create_virtual_host()
+ # create default project and client
+ #create_client(@APP_CONFIG[:default_client])
+ create_project(@APP_CONFIG[:default_project],@APP_CONFIG[:default_client])
end
+
+ private
# 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(file_path)
- yamlFile = YAML.load(raw_config)
+ yamlFile = YAML.load_file("#{DEV_ROOT}/config/config.yml")
rescue Exception => e
- raise StandardError, "Config #{file_path} could not be loaded."
+ raise StandardError, "config/config.yml could not be loaded."
end
if yamlFile
- if yamlFile[SUBTRAC_ENV]
- @APP_CONFIG = yamlFile[SUBTRAC_ENV]
+ if yamlFile[DEV_ENV]
+ @APP_CONFIG = yamlFile[DEV_ENV]
else
- raise StandardError, "config/config.yml exists, but doesn't have a configuration for #{SUBTRAC_ENV}."
+ raise StandardError, "config/config.yml exists, but doesn't have a configuration for DEV_ENV=#{DEV_ENV}."
end
else
raise StandardError, "config/config.yml does not exist."
end
- puts "\n==== Installation options ===="
-
- say("Setting up default configuration...")
- @server_name = @APP_CONFIG[:server_name]
- @server_hostname = @APP_CONFIG[:server_hostname]
- @server_ip = @APP_CONFIG[:server_ip]
-
- @default_client = @APP_CONFIG[:default_client]
- @default_project = @APP_CONFIG[:default_project]
-
- @install_dir = File.expand_path(@APP_CONFIG[:installation_dir])
- @conf_dir = @APP_CONFIG[:apache2_conf]
-
- @ldap_enable = @APP_CONFIG[:ldap][:enable]
- if (@ldap_enable) then
- @ldap_bind_dn = @APP_CONFIG[:ldap][:bind_dn]
- @ldap_bind_password = @APP_CONFIG[:ldap][:bind_password]
- @ldap_url = @APP_CONFIG[:ldap][:host]
- end
-
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, it seems there's some stuff in there. You sure you want me to overwrite? [Y/n]") if options.clean
- confirm_clean = agree("Doubly sure? I can't undo this....[Y/n]") if confirm_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()
- configure_admin_user()
- # 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
-
- # 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|
- unless File.directory?(name)
- puts "Creating directory called #{names}..."
- FileUtils.mkdir_p(name)
- end
- end
+ def self.create_if_missing *names
+ puts "\n==== Creating directory #{names} ===="
+ names.each do |name| FileUtils.mkdir_p(name) unless File.directory?(name) end
end
# publishes an erb template
def self.parse_template(infile,outfile,binding)
- file = File.open(outfile, 'w+')
+ file = File.new(outfile, "w")
if file
- template = ERB.new(IO.read(infile))
- if template
- file.syswrite(template.result(binding))
- else
- raise "Could not read template. file #{infile}"
- end
+ file.syswrite(ERB.new(IO.read(infile)).result(binding))
else
- raise "Unable to open file for writing. file #{outfile}"
+ puts "Unable to write to file #{outfile}!"
end
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_path, @APP_CONFIG[:templates][:virtual_host])
- puts "group apache tempalte: #{vhost_template}"
- new_vhost = File.join(@conf_dir,@server_hostname)
- puts "group apache file: #{new_vhost}"
- parse_template(vhost_template,new_vhost,binding) if SUBTRAC_ENV != 'test'
+ parse_template(@APP_CONFIG[:templates][:virtual_host],"#{@APP_CONFIG[:dirs][:apache2_conf]}/#{@APP_CONFIG[:server][:hostname]}",binding)
# reload apache configuration
- `/etc/init.d/apache2 force-reload` if SUBTRAC_ENV != 'test'
- `a2ensite #{@server_hostname}` if SUBTRAC_ENV != 'test'
+ `/etc/init.d/apache2 force-reload` if DEV_ENV != 'test'
+ `a2ensite #{@APP_CONFIG[:server][:hostname]}` if DEV_ENV != 'test'
end
def self.install_common_files
puts "\n==== Installing common files ===="
- # TODO: implement a mask for .svn folders
+ # TODO: implement a mash for .svn folders
# TODO: refactor /common to the app config
- FileUtils.cp_r(Dir.glob(File.join(subtrac_path, "common/.")),docs_dir)
- FileUtils.cp_r(Dir.glob(File.join(subtrac_path, "shared/.")),create_if_missing(File.join(trac_dir, ".shared")))
- # this need to be replaced with a question/answer session
- #FileUtils.cp(,@install_dir)
+ source = Dir.glob("#{DEV_ROOT}/common/.")
+ dest = @APP_CONFIG[:dirs][:document]
+ FileUtils.cp_r(source,dest)
end
-
- def self.configure_admin_user
- puts "\n==== Configure admin user ===="
- # create admin user
- passwd_file = File.join(@install_dir, ".passwd")
- admin_user = ask("Pick an admin username: ") { |q| q.echo = true }
- `htpasswd -c #{passwd_file} #{admin_user}`
- @APP_CONFIG[:admin_user] = admin_user
- # ensure this guy is added to trac admin group
- @APP_CONFIG[:trac][:permissions][admin_user] = "admins"
- #FileUtils.chown_R('www-data', 'www-data', passwd_file, :verbose => true) if SUBTRAC_ENV != 'test'
- end
- def self.create_environment_directories(overwrite=false)
+ def self.create_environment_directories
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|
- dir = File.join(@install_dir,value)
- create_if_missing dir
+ create_if_missing value
end
end
+ def self.clean
+ puts "\n==== Remove old data if exists ===="
+ @APP_CONFIG[:dirs].each do |key, value|
+ unless [@APP_CONFIG[:dirs][:install]].include? value
+ #TODO: Ask for confirmation - yes,no,All
+ puts "Deleting #{value}"
+ FileUtils.rm_rf value
+ end
+ end
+ end
+
def self.create_client(name)
- puts "\n==== Create a new client called #{name} ===="
+ puts "\n==== Create a new client #{name} ===="
client_name = name.downcase
# create apache configuration
- 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 SUBTRAC_ENV != 'test'
+ # create apache template
+ parse_template(@APP_CONFIG[:templates][:location],"#{@APP_CONFIG[:dirs][:conf_locations]}/#{client_name}.conf",binding)
+ `/etc/init.d/apache2 force-reload` if DEV_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 a project for this clients trac theme
- create_project("trac_theme", client_name,@APP_CONFIG[:default_theme_template])
-
- # check the theme project out
- client_theme_dir = File.join(trac_dir,client_name,".theme")
- create_if_missing(client_theme_dir)
- FileUtils.chown_R('www-data', 'www-data', client_theme_dir, :verbose => true) if SUBTRAC_ENV != 'test'
- puts "Attempting checkout of theme project..."
-
- `sudo svn co --username #{@APP_CONFIG[:admin][:username]} --password #{@APP_CONFIG[:admin][:password]} \
- file://#{svn_dir}/#{client_name}/trac_theme/trunk #{client_theme_dir}` if SUBTRAC_ENV != 'test'
-
+ create_if_missing "#{@APP_CONFIG[:dirs][:svn]}/#{client_name}"
+ create_if_missing "#{@APP_CONFIG[:dirs][:trac]}/#{client_name}"
end
- def self.create_project(project, client, project_type=@APP_CONFIG[:default_project_template])
- puts "\n==== Create a new project called #{project} for #{client} ===="
+ def self.create_project(project, client)
+ puts "\n==== Create a new project #{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? "#{@APP_CONFIG[:dirs][:svn]}/#{client_name}")
- 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
+ svn_dir = "#{@APP_CONFIG[:dirs][:svn]}/#{client_name}/#{project_name}"
+ trac_dir = "#{@APP_CONFIG[:dirs][:trac]}/#{client_name}/#{project_name}"
+ if (File.directory? 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
- say("Create project directories...")
- create_if_missing project_svn_dir
- create_if_missing project_trac_dir
-
- project_template = File.join(subtrac_path, @APP_CONFIG[:templates][:projects],project_type)
-
# 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")
- project_temp_dir = File.join(temp_dir,project_name)
- FileUtils.cp_r(svn_template_dir,project_temp_dir)
+ svn_template_dir = "#{@APP_CONFIG[:templates][:blank]}/svn/."
+ temp_dir = "#{@APP_CONFIG[:dirs][:temp]}/#{project_name}"
+ FileUtils.cp_r(svn_template_dir,temp_dir)
# create a new subversion repository
- say("Creating a new subversion repository...")
- `svnadmin create #{project_svn_dir}` if SUBTRAC_ENV != 'test'
+ `svnadmin create #{svn_dir}` if DEV_ENV != 'test'
- # import into svn
- 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(project_temp_dir, :force => true)
+ # import into svn and delete the temporary directory
+ `svn import #{temp_dir} file:///#{svn_dir} --message "initial import"` if DEV_ENV != 'test'
+ FileUtils.rm_r(temp_dir, :force => true)
# create a new trac site
- say("Creating a new trac site...")
- 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
+ `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
- say("Installing trac configuration...")
# install shared trac.ini
- 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)
+ parse_template(@APP_CONFIG[:templates][:trac],"#{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("#{project_trac_dir}/templates")
+ FileUtils.rm_rf("#{trac_dir}/templates")
- say("Setting up default trac permissions...")
+ puts "Setting up default trac permission..."
# set up trac permissions
@APP_CONFIG[:trac][:permissions].each do |key, value|
- `sudo trac-admin #{project_trac_dir} permission add #{key} #{value}` if SUBTRAC_ENV != 'test'
+ `trac-admin #{trac_dir} permission add #{key} #{value}` if DEV_ENV != 'test'
end
- say("Adding default trac wiki pages...")
- # loop through the directory and import all pages
- Dir.foreach("#{project_template}/trac/wiki/.") do |file|
+ puts "Adding default trac wiki pages..."
+ # this needs to loop through the directory and import all pages
+ Dir.foreach("#{DEV_ROOT}/#{@APP_CONFIG[:default_project_template]}/trac/wiki/.") do |file|
# do something with the file here
unless ['.', '..','.svn'].include? file
- temp_file = File.join(temp_dir,file)
- puts = binding
- parse_template(File.join(project_template,"trac/wiki",file), temp_file, binding)
- `trac-admin #{project_trac_dir} wiki import #{file} #{temp_file}` if SUBTRAC_ENV != 'test'
- FileUtils.rm(temp_file)
+ parse_template("#{DEV_ROOT}/#{@APP_CONFIG[:default_project_template]}/trac/wiki/#{file}","#{@APP_CONFIG[:dirs][:temp]}/#{file}", binding)
+ `trac-admin #{trac_dir} wiki import #{file} #{@APP_CONFIG[:dirs][:temp]}/#{file}` if DEV_ENV != 'test'
+ FileUtils.rm("#{@APP_CONFIG[:dirs][:temp]}/#{file}")
end
end
-
- # run trac upgrade
- say("Upgrading the trac installation...")
- `trac-admin #{project_trac_dir} upgrade` if SUBTRAC_ENV != 'test'
-
end
+
end