lib/teamster-cli.rb in teamster-0.6.1 vs lib/teamster-cli.rb in teamster-0.7.0

- old
+ new

@@ -8,16 +8,13 @@ def quit(msg, code = 0) warn msg exit code end - def create_config(team_name) - if team_name - @config[:title] = team_name - else - ask_user_for :title, "What is your team name" - end + def create_config + @config['title'] = ask_user "What is your team name" + @config['adapters'] = [] File.open(CONFIG_FILE, 'w') {|fh| fh.write @config.to_yaml} end def create_user puts "Creating default user.." @@ -30,33 +27,91 @@ def b64_enc(obj) Base64.strict_encode64(obj) end - def ask_user_for(opt, question) - unless @config[opt] - @config[opt] = ask_user question - end - end - def ask_user(question) print "#{question}: " STDIN.gets.strip end + def update_adapter(name) + config = YAML.load_file(CONFIG_FILE) + adapter = config.fetch('adapters').find {|e| e.fetch("name") == name} + quit "No local adapter found with name: #{name}" unless adapter + list_from_fs = Dir.glob("lib/teamster-adapters/#{name.gsub(' ', '_')}/**/*.*") + list_from_conf = adapter.fetch('files') + list_from_conf.concat(list_from_fs).uniq! + File.open(CONFIG_FILE, 'w') {|fh| fh.write config.to_yaml} + end + + def update_new_adapters + config = YAML.load_file(CONFIG_FILE) + adapters = config.fetch('adapters') + current_adapters = Dir.glob("lib/teamster-adapters/*.rb").map do |f| + f.split('/').last.gsub('.rb', '').gsub('_', ' ') + end + current_adapters.each do |name| + next if adapters.find {|e| e.fetch("name") == name} + adapters << {}.tap do |hsh| + hsh["name"] = name + file_list = Dir.glob("lib/teamster-adapters/#{name.gsub(' ', '_')}/**/*.*") + file_list << "lib/teamster-adapters/#{name.gsub(' ', '_')}.rb" + hsh["files"] = file_list + end + end + File.open(CONFIG_FILE, 'w') {|fh| fh.write config.to_yaml} + end + + def update_existing_adapters + config = YAML.load_file(CONFIG_FILE) + adapters = config.fetch('adapters') + current_adapters = Dir.glob("lib/teamster-adapters/*.rb").map do |f| + f.split('/').last.gsub('.rb', '').gsub('_', ' ') + end + current_adapters.each do |name| + adapter = adapters.find {|e| e.fetch("name") == name} + list_from_fs = Dir.glob("lib/teamster-adapters/#{name.gsub(' ', '_')}/**/*.*") + list_from_conf = adapter.fetch('files') + list_from_conf.concat(list_from_fs).uniq! + end + File.open(CONFIG_FILE, 'w') {|fh| fh.write config.to_yaml} + end + + def add_adapter_to_config(name, filename) + @config = YAML.load_file CONFIG_FILE + adapter = { + 'name' => name, + 'files' => [ + "lib/teamster-adapters/#{filename}.rb", + "lib/teamster-adapters/#{filename}/#{filename}_helper.rb", + "lib/teamster-adapters/#{filename}/views/#{filename}.erb", + "lib/teamster-adapters/#{filename}/views/#{filename}_summary.erb" + ] + } + @config.tap do |hsh| + adapters = hsh.fetch('adapters') + adapters << adapter + end + File.open(CONFIG_FILE, 'w') {|fh| fh.write @config.to_yaml} + end + def create_adapter_for(name) puts "Creating placeholders for adapter #{name}...\n" - FileUtils.mkdir_p "lib/teamster-adapters/#{name}/views" - create_file "lib/teamster-adapters/#{name}.rb", "adapter_placeholder_for", name - create_file "lib/teamster-adapters/#{name}/#{name}_helper.rb", "adapter_helper_placeholder_for", name - create_file "lib/teamster-adapters/#{name}/views/#{name}.erb", "view_placeholder_for", name - create_file "lib/teamster-adapters/#{name}/views/#{name}_summary.erb", "view_summary_placeholder_for", name + filename = name.split(' ').map{|a| a.downcase}.join('_') + class_name = name.split(' ').map{|a| a.capitalize}.join('') + FileUtils.mkdir_p "lib/teamster-adapters/#{filename}/views" + create_file "lib/teamster-adapters/#{filename}.rb", "adapter_placeholder_for", filename, class_name + create_file "lib/teamster-adapters/#{filename}/#{filename}_helper.rb", "adapter_helper_placeholder_for", filename, class_name + create_file "lib/teamster-adapters/#{filename}/views/#{filename}.erb", "view_placeholder_for", filename, class_name + create_file "lib/teamster-adapters/#{filename}/views/#{filename}_summary.erb", "view_summary_placeholder_for", filename, class_name puts "\nBasic adapter creation done!" - puts "Controller : \"lib/teamster-adapters/#{name}.rb\"" - puts "Helper : \"lib/teamster-adapters/#{name}/#{name}_helper.rb\"" - puts "View : \"lib/teamster-adapters/#{name}/views/#{name}.erb\"" - puts "Summary View : \"lib/teamster-adapters/#{name}/views/#{name}_summary.erb\"" + puts "Controller : \"lib/teamster-adapters/#{filename}.rb\"" + puts "Helper : \"lib/teamster-adapters/#{filename}/#{filename}_helper.rb\"" + puts "View : \"lib/teamster-adapters/#{filename}/views/#{filename}.erb\"" + puts "Summary View : \"lib/teamster-adapters/#{filename}/views/#{filename}_summary.erb\"" + add_adapter_to_config name, filename end def import_adapter_for(name) puts "Importing adapter: #{name}" zip_file = "#{name}.zip" @@ -70,26 +125,27 @@ else puts "Unable to find file: #{zip_file}" end end - def export_adapter_for(name) - puts "Exporting adapter: #{name}" - zip_file = "#{name}.zip" - puts "The following files will be zipped:" - puts "- lib/teamster-adapters/#{name}.rb" - puts '- Everything in folder lib/teamster-adapters/#{name}/' + def export_adapter(name, files) + zip_file = "#{name.gsub(' ', '_')}.zip" + puts "\nExporting adapter #{name} to zip: #{zip_file}\n\n" + puts "The following files will be exported into a zip file:" + files.each {|f| puts "- #{f}"} + puts if `which zip`.length != 0 - `zip -r #{zip_file} lib/teamster-adapters/#{name}.rb lib/teamster-adapters/#{name}/` - puts "\nExported to #{zip_file}!" - else - puts "\nUnable to export adapter. Export depends on cli tool \"zip\"." + if system "zip -r #{zip_file} #{files.join(' ')}" + quit "\nExport successful!", 0 + else + quit "\nError occurred when zipping!", 1 + end end end def create_file(filename, method, *args) - case [File.exists?(filename), !!@config[:overwrite]] + case [File.exists?(filename), !!@opts[:overwrite]] when [true, false] puts "File \"#{filename}\" exists. Run with --overwrite to overwrite file." else puts "Creating file #{filename}..." File.open(filename, "w") {|fh| fh.write(send(method.to_sym, *args))} @@ -103,16 +159,16 @@ def usage <<-HELP Initialize application: teamster init +Create an adapter: + teamster create my amazing adapter + Run web application: teamster start -Run web application in production (uses unix socket & state file): - teamster start --prod [--socket-file FILE] [--state-file FILE] - Verify by opening browser and navigating to "http://localhost:9292". For more detailed help, please run "teamster --help". HELP end @@ -125,36 +181,81 @@ Usage: teamster [COMMAND] [OPTIONS] Commands: - init, start, stop, restart + init, list, create, delete, export, import, update, start, stop, restart Options (standalone): --help Display this detailed help. --version Version of the teamster used. - --create-adapter NAME Creates a stub of a adapter - --import-adapter FILE << PENDING IMPLEMENTATION >> - --export-adapter FILE << PENDING IMPLEMENTATION >> -Options used with \"start\": +Command \"init\" : Initializes the web app. Creates required files for web app. +Options: + --overwrite If app is already initialized, --overwrite will + recreate all the base files. + + +Command \"list\" Lists all teamster adapters. + + +Command \"create\" NAME Creates a skeleton of a teamster adapter. Creates a + new entry in the config file. + + +Command \"update\" NAME Updates the files for a teamster adapter in the + config file. NAME is optional. If NAME is not given, + all new and existing adapters are updated. + + +Command \"delete\" NAME Deletes all the files of the adapter based on the + config file. +Option: + --no-update Does not update new and existing adapters in the + config files before deletion. + + +Command \"remove\" NAME Same as DELETE above. + + +Command \"export\" NAME Zips all the files listed in the config file for + the specified adapter. Take care to scrub all + information in config files, etc. +Option: + --no-update Does not update new and existing adapters in the + config files before deletion. + + +Command \"import\" NAME Import is not yet implemented. + + +Command \"start\" : Used to run the teamster web app. +Options: --prod Binds a unix socket to be used by a web server (eg. Nginx) and creates a state file that is used by the Puma app server. - --socket-file FILE Relative/absolute path to the UNIX socket file. - --state-file FILE Relative/absolute path to the Puma state file. + --socket-file FILE Required with --prod. Relative/absolute path + to the UNIX socket file. + --state-file FILE Required with --prod. Relative/absolute path + to the Puma state file. -Options used with \"stop\": - --socket-file FILE Relative/absolute path to the UNIX socket file. - --state-file FILE Relative/absolute path to the Puma state file. +Command \"stop\" : Used to stop the teamster web app in production mode. +Options: + --socket-file FILE Required. Relative/absolute path to the UNIX + socket file. + --state-file FILE Required. Relative/absolute path to the Puma + state file. -Options used with \"restart\": - --socket-file FILE Relative/absolute path to the UNIX socket file. - --state-file FILE Relative/absolute path to the Puma state file. +Command \"restart\" : Used to restart the teamster web app in production mode. +Options: + --socket-file FILE Required. Relative/absolute path to the UNIX + socket file. + --state-file FILE Required. Relative/absolute path to the Puma + state file. DETAIL end def config_ru <<-CODE @@ -178,70 +279,74 @@ require mdl end CODE end - def adapter_placeholder_for(name) + def adapter_placeholder_for(filename, class_name) <<-CODE -require_relative \"#{name}/#{name}_helper\" +require_relative \"#{filename}/#{filename}_helper\" -\# NOTE: If the namespace is changed, please take care of the -\# namespace of the sub-class and helper adapters. - module Teamster module Adapters - class #{name.capitalize} < Sinatra::Base + class #{class_name} < Sinatra::Base \# Class methods that contain Teamster-Adapter specific helpers. include BaseAdapter - \# Stuff that needs to be done before registration with core. - has_helpers #{name.capitalize}Helper \# Add adapters here (comma separated) if there are helper adapters. - views_at \"\#\{File.dirname(__FILE__)\}/#{name}/views\" + \# --{ Stuff that needs to be done before registration with core. }-- + + \# Add adapters here (comma separated) if there are helper adapters. + has_helpers #{class_name}Helper + + \# Location of the views folder + views_at \"\#\{File.dirname(__FILE__)\}/#{filename}/views\" + under_development \# Remove this line when development is finished. + + \# ------------------------------------------------------------------ \# Register this class so it can be used. - register self + register self, "#{filename}" configure do enable :logging \# To log, use \"logger.info <MSG>\". Log messages are captured \# in the file specified in config.ru. end - get '/#{name}/?' do - erb :#{name} + get '/#{filename.gsub('_', '-')}/?' do + erb :#{filename} end end end end CODE end - def adapter_helper_placeholder_for(name) + def adapter_helper_placeholder_for(filename, class_name) <<-CODE module Teamster module Adapters - module #{name.capitalize}Helper - def #{name}_summary? + module #{class_name}Helper + def #{filename}_summary? true end - def #{name}_summary - erb :#{name}_summary + def #{filename}_summary + erb :#{filename}_summary end end end end CODE end - def view_placeholder_for(name) + def view_placeholder_for(filename, class_name) <<-CODE -<h1 style='text-align: center'>PLACEHOLDER FOR #{name.upcase}</h1> +<h1 style='text-align: center'>PLACEHOLDER FOR #{filename.split('_').map{|a| a.upcase}.join(' ')}</h1> <p style='text-align: center'>Page under construction. Please check back later!</p> CODE end - def view_summary_placeholder_for(name) + def view_summary_placeholder_for(filename, class_name) <<-CODE <p>Under development right now..</p> CODE end end