#! /usr/bin/ruby1.8 # TITLE # # Manifest Command # # SUMMARY: # # Commandline tool for generating and comparing package manifest. # # AUTHOR: # # - Thomas Sawyer require 'facets/command' require 'facets/module/alias' require 'ratch/manifest' module Ratch # def optparse # opts = GetoptLong.new( # [ '--file' , '-f', GetoptLong::REQUIRED_ARGUMENT ], # [ '--digest' , '-g', GetoptLong::REQUIRED_ARGUMENT ], # [ '--exclude', '-x', GetoptLong::REQUIRED_ARGUMENT ], # [ '--all' , '-a', GetoptLong::NO_ARGUMENT ], # [ '--update' , '-u', GetoptLong::NO_ARGUMENT ], # [ '--list' , '-l', GetoptLong::NO_ARGUMENT ], # [ '--diff' , '-d', GetoptLong::NO_ARGUMENT ], # [ '--new' , '-n', GetoptLong::NO_ARGUMENT ], # [ '--old' , '-o', GetoptLong::NO_ARGUMENT ], # [ '--clean' , GetoptLong::NO_ARGUMENT ], # [ '--help' , '-h', GetoptLong::NO_ARGUMENT ] # ) # unless args.empty? # if File.file?(args[0]) # opts[:file] = args[0] # opts[:directory] = args[1] if args[1] # else # opts[:directory] = args[0] # opts[:file] = args[1] if args[1] # end # end # # @quiet = opts.delete(:quiet) # @options = opts # @command = cmd # end # Manifest Console Command class ManifestCommand < Console::MasterCommand include UniversalOptions option_arity( 'x' => 1, 'exclude' => 1, 'f' => 1, 'file' => 1, 'g' => 1, 'digest' => 1 ) attr_accessor :quiet attr_accessor :file attr_accessor :digest attr_accessor :exclude attr_accessor :all # shorcuts alias_accessor :f, :file alias_accessor :x, :exclude alias_accessor :g, :digest alias_accessor :a, :all # Default command -- output manifest. def generate if file update else manifest = Manifest.new(manifest_options) manifest.generate end end alias_method :default, :generate # Update a MANIFEST file for this package. def update begin file = manifest.update rescue NoManifestError => e puts e.message exit -1 end report_updated(file) end alias_method :up, :update # List files in manifest file. def list puts manifest.filelist end # Show diff comparison between listed and actual. def diff #begin result = manifest.diff report_difference(result) #rescue NoManifestError # report_manifest_missing #end end # Files listed in manifest, but not found. def old #begin list = manifest.whatsold unless list.empty? report_whatsold(list) end #rescue NoManifestError # report_manifest_missing # exit 0 #end end # Files found, but not listed in manifest. def new #begin list = manifest.whatsnew unless list.empty? report_whatsnew(list) end #rescue NoManifestError # report_manifest_missing # exit! #end end # Clean (or clobber if you prefer) non-manifest files. def clean ansr = confirm_clean(manifest.clean_files) case ansr.downcase when 'y', 'yes' manifest.clean else report_cancelled('Clean') exit! end end # Display command help information. def help report_help end private # Load manifest. #-- # TODO Manifest lookup needs to go in Manifest class? #++ def manifest @manifest ||= ( begin manifest = Manifest.open(file) manifest.change_options(manifest_options) manifest rescue LoadError report_manifest_missing exit 0 end ) end def manifest_options { :file=>file, :digest=>digest, :exclude=>exclude, :all=>all } end # Quiet opertation? def quiet?; @quiet; end # Get confirmation for clean. def confirm_clean(list) puts list.join("\n") ask("The above files will be removed. Continue?", "yN") end # Get confirmation for clobber. def confirm_clobber(list) puts list.join("\n") ask("The above files will be removed. Continue?", "yN") end # Report manifest created. def report_created(file) file = File.basename(file) puts "#{file} created." unless quiet? end # Report manifest updated. def report_updated(file) if file file = File.basename(file) puts "#{file} updated." unless quiet? else puts "Manifest file doesn't exit." end end # Display diff between file and actual. #-- # TODO What about checkmode? #++ def report_difference(result) output = nil if pass = result.empty? if @checkmode output = justified('Manifest', '[PASS]') + "\n" else #"Manifest is current." end else output = result end puts output if output end # Report missing manifest file. def report_whatsnew(list) puts list.join("\n") end # Report missing manifest file. def report_whatsold(list) puts list.join("\n") end # Show help. def report_help puts DATA.read % [ File.mtime(__FILE__).strftime("%Y-%m-%d") ] end # Report missing manifest file. def report_manifest_missing puts "No manifest file." end # Report action cancelled. def report_cancelled(action) puts "#{action} cancelled" end # Report manifest overwrite. def report_overwrite(manifest) puts "#{manifest.filename} already exists." end # Warn that a manifest already exist higher in this hierarchy. def report_warn_shadowing(manifest) puts "Shadowing #{manifest.file}" end end end Ratch::ManifestCommand.start =begin scrap # # Lookup manifest. # # def manifest(create_missing=false) # @manifest ||= ( # file = @options[:file] # #manifest = file ? Manifest.open(file) : Manifest.lookup # manifest = nil # # if file # manifest = Manifest.open(file, @options) # elsif create_missing # manifest = Manifest.new(@options) # else # manifest = nil # end # # if manifest # #manifest.send(:set, @options) # else # report_manifest_missing # exit 0 # end # manifest # ) # end # @manifest ||= ( # file = @options[:file] # #manifest = file ? Manifest.open(file) : Manifest.lookup # manifest = nil # # if file # manifest = Manifest.open(file) # elsif create_missing # manifest = Manifest.new # else # manifest = nil # end # # if manifest # manifest.change_options(@options) # else # report_manifest_missing # exit 0 # end # manifest # ) # end # # Generate manifest. By default it is a very simple filename # # list. The digest can be supplied and a checksum will # # be given before each filename. # # def create # manifest = Manifest.new #lookup # # return report_overwrite(manifest) if ( # manifest and manifest.location == Dir.pwd # ) # # report_warn_shadowing(manifest) if manifest # # manifest = Manifest.new(options) # file = manifest.create # report_created(file) # end # # Clobber non-manifest files. # #-- # # TODO Should clobber work off the manifest file itself # #++ # # def clobber # ansr = confirm_clobber(manifest.toss) # case ansr.downcase # when 'y', 'yes' # manifest.clobber # else # report_cancelled('Clobber') # exit! # end # end =end __END__ manifest (%s) The manifest listing tool is used to list or create and update a manifest file for a package (eg. a directory), or compare a manifest to actual contents. lmf is part of the ProUtils set of tools. USAGE: lmf [command] [options...] [file] [dir] EXAMPLES: manifest manifest update -f READEME.manifest COMMANDS: When no command is given, a manifest is generated to standard out. If --file is specified, it will generate to that file instead. generate Create a manifest and send it to stdout. This is the default action when no command is given. update up Update an existing manifest/digest file using any previous parameters set for that file. list Show all files listed in the manifest file. diff Diff manifest file against actual. new List existant files not given in the manifest. old Show files listed in manifest but are not in the the package. clean Remove non-manifest files. (Will ask for confirmation first.) help Display this help message. OPTIONS: -a --all Include all files. This deactivates deafult exclusions so it is possible to make complete list of a contents. -f --file [name] Path to manifest file. By defualt this is the 'manifest' with optional '.txt' or '.list' extension. it is case-insensitive and it can also be in a meta/ subdirectory. If the path of the file is anything else then --file option must be specified. -g --digest [type] Include crytogrpahic signiture. Type can be either md5, sha1, sha128, sha256, or sha512. The default if the type is not given id sha1. -x --exclude [path] Exclude a file or dir from the manifest. You can use --exclude repeatedly. -q --quiet Suppress extraneous output.