lib/bones/main.rb in bones-1.1.2 vs lib/bones/main.rb in bones-1.2.0
- old
+ new
@@ -1,6 +1,6 @@
-# $Id: main.rb 428 2007-12-31 17:55:51Z tim_pease $
+# $Id: main.rb 433 2008-01-01 04:32:48Z tim_pease $
require 'fileutils'
require 'optparse'
require 'erb'
@@ -23,11 +23,12 @@
# Parse the command line arguments and store the values for later use by
# the +create+ and +update+ methods.
#
def parse( args )
- self.data = File.join(::Bones::PATH, 'data')
+ self.data = File.join(mrbones_dir, 'data')
+ self.data = File.join(::Bones::PATH, 'data') unless test(?d, data)
self.update = false
self.verbose = false
opts = OptionParser.new
opts.banner << ' project_name'
@@ -37,21 +38,32 @@
'update the rake tasks for the project') {self.update = true}
opts.on('-v', '--verbose',
'enable verbose output') {self.verbose = true}
opts.separator ''
+ opts.on('--freeze', 'freeze the project skeleton') {freeze; exit}
+ opts.on('--unfreeze', 'use the standard project skeleton') {unfreeze; exit}
+ opts.on('-i', '--info',
+ 'report on the project skeleton being used') do
+ STDOUT.puts "the project skeleton will be copied from"
+ STDOUT.write " "
+ STDOUT.puts data
+ exit
+ end
+
+ opts.separator ''
opts.separator 'common options:'
opts.on_tail( '-h', '--help', 'show this message' ) {puts opts; exit}
opts.on_tail( '--version', 'show version' ) do
puts "Bones #{::Bones::VERSION}"
exit
end
# parse the command line arguments
opts.parse! args
- self.name = args.shift
+ self.name = args.join('_')
if name.nil?
puts opts
::Kernel.abort
end
@@ -63,47 +75,39 @@
#
def update?
@update
end
- # Returns the project name but converted to be useable as a Ruby class
+ # Returns the project name but converted to be usable as a Ruby class
# name.
#
def classname
name.split('_').map {|x| x.capitalize}.join
end
# Create a new project from the bones/data project template.
#
def create
- # * copy files from either
- # 1) the user's '.bones/data' directory or
- # 2) the Bones 'data' directory
- #
- # TODO - figure out if this really is the best way of doing this
- # should I just use either the .bones data or the gem data, not
- # both
-
# see if the directory already exists
abort "'#{name}' already exists" if test ?e, name
begin
files_to_copy.each {|fn| cp fn}
pwd = File.expand_path(FileUtils.pwd)
begin
FileUtils.cd name
system "rake manifest:create 2>&1 > #{::Bones::DEV_NULL}"
+ STDOUT.puts "created '#{name}'\nnow you need to fix these files"
+ system "rake notes"
ensure
FileUtils.cd pwd
end
rescue Exception => err
FileUtils.rm_rf name
abort "could not create '#{name}'"
end
-
- STDOUT.puts "created '#{name}'"
end
# Archive any existing tasks in the project's tasks folder, and then
# copy in new tasks from the bones/data directory.
#
@@ -121,23 +125,91 @@
next if fn == archive_dir
FileUtils.cp fn, archive_dir
end
files_to_copy.each do |fn|
- next unless 'tasks' == File.basename(File.dirname(fn))
+ next unless %r/^tasks\// =~ fn
cp fn
end
STDOUT.puts "updated tasks for '#{name}'"
end
+ # Freeze the project skeleton to the current Mr Bones gem. If the project
+ # skeleton has already been frozen, then it will be archived before being
+ # overwritten by the current Mr Bones skeleton.
+ #
+ # If the project skeleton is already frozen, only the tasks from the Mr
+ # Bones skeleton will be copied to the user's data directory.
+ #
+ def freeze
+ bones_data_dir = File.join(::Bones::PATH, 'data')
+ data_dir = File.join(mrbones_dir, 'data')
+ archive_dir = File.join(mrbones_dir, 'archive')
+ tasks_only = false
+ if test(?d, data_dir)
+ STDOUT.puts "archiving #{data_dir}" if verbose
+ FileUtils.rm_rf(archive_dir)
+ FileUtils.mkdir(archive_dir)
+ FileUtils.cp_r(File.join(data_dir, '.'), archive_dir)
+ tasks_only = true
+ else
+ FileUtils.mkdir_p(data_dir)
+ end
+
+ files_to_copy.each do |file|
+ next if tasks_only && !(%r/^tasks\// =~ file)
+
+ src = File.join(bones_data_dir, file)
+ dst = File.join(data_dir, file)
+
+ STDOUT.puts "freezing #{dst}" if verbose
+ FileUtils.mkdir_p(File.dirname(dst))
+ FileUtils.cp(src, dst)
+ end
+
+ File.open(frozen_version_file, 'w') {|fd| fd.puts ::Bones::VERSION}
+
+ if tasks_only
+ STDOUT.puts "project skeleton tasks have been updated " <<
+ "from Mr Bones #{::Bones::VERSION}"
+ else
+ STDOUT.puts "project skeleton has been frozen " <<
+ "to Mr Bones #{::Bones::VERSION}"
+ end
+ end
+
+ # Unfreeze the project skeleton. The default Mr Bones skeleton will be
+ # used insetad. This method will archive the current frozen skeleton if
+ # one exists.
+ #
+ def unfreeze
+ data_dir = File.join(mrbones_dir, 'data')
+ archive_dir = File.join(mrbones_dir, 'archive')
+
+ if test(?d, data_dir)
+ STDOUT.puts "archiving #{data_dir}" if verbose
+ FileUtils.rm_rf(archive_dir)
+ FileUtils.mkdir(archive_dir)
+ FileUtils.cp_r(File.join(data_dir, '.'), archive_dir)
+ FileUtils.rm_rf(data_dir)
+
+ STDOUT.puts "project skeleton has been unfrozen"
+ STDOUT.puts "(default Mr Bones #{::Bones::VERSION} sekeleton will be used)"
+ else
+ STDOUT.puts "project skeleton is not frozen (no action taken)"
+ end
+ FileUtils.rm_f frozen_version_file
+ end
+
+
private
# Copy a file from the Bones prototype project location to the user
# specified project location. A message will be displayed to the screen
- # indicating tha the file is being created.
+ # indicating that the file is being created.
#
def cp( file )
dir = File.dirname(file)
dir = (dir == '.' ? name : File.join(name, dir))
dst = File.join(dir, File.basename(file, '.erb').sub('NAME', name))
@@ -177,9 +249,25 @@
end
ary.compact!
ary.sort!
ary
+ end
+
+ # Returns the .bones resource directory in the user's home directory.
+ #
+ def mrbones_dir
+ return @mrbones_dir if defined? @mrbones_dir
+
+ path = (::Bones::WIN32 ? ENV['HOMEPATH'].tr("\\", "/") : ENV['HOME'])
+ path = File.join(path, '.mrbones')
+ @mrbones_dir = File.expand_path(path)
+ end
+
+ # File containing the Mr Bones version from which the skeleton was frozen.
+ #
+ def frozen_version_file
+ File.join(mrbones_dir, 'version.txt')
end
end # class Main
end # module Bones