schubert-minglr 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/Rakefile +2 -0
  2. data/VERSION.yml +2 -2
  3. data/bin/minglr +11 -11
  4. data/bin/mtx +1 -1
  5. data/lib/minglr.rb +18 -10
  6. data/lib/minglr/action.rb +75 -0
  7. data/lib/minglr/config_parser.rb +49 -0
  8. data/lib/minglr/extensions/array.rb +23 -0
  9. data/lib/minglr/input_cache.rb +3 -3
  10. data/lib/minglr/options_parser.rb +79 -0
  11. data/lib/minglr/resources/attachment.rb +46 -0
  12. data/lib/minglr/resources/base.rb +42 -0
  13. data/lib/minglr/resources/card.rb +107 -0
  14. data/lib/minglr/resources/project.rb +25 -0
  15. data/lib/minglr/resources/property_definition.rb +12 -0
  16. data/lib/minglr/resources/transition_execution.rb +6 -0
  17. data/lib/minglr/resources/user.rb +25 -0
  18. data/minglr.gemspec +30 -28
  19. data/minglrconfig.sample +19 -0
  20. data/test/extensions/array_test.rb +41 -0
  21. data/test/resources/attachment_test.rb +40 -0
  22. data/test/resources/base_test.rb +45 -0
  23. data/test/resources/card_test.rb +89 -0
  24. data/test/resources/project_test.rb +26 -0
  25. data/test/resources/property_definition_test.rb +25 -0
  26. data/test/resources/user_test.rb +39 -0
  27. data/test/test_helper.rb +15 -5
  28. metadata +27 -15
  29. data/lib/minglr/attachment.rb +0 -7
  30. data/lib/minglr/card.rb +0 -2
  31. data/lib/minglr/mingle_resource.rb +0 -5
  32. data/lib/minglr/minglr_action.rb +0 -200
  33. data/lib/minglr/minglr_config_parser.rb +0 -44
  34. data/lib/minglr/minglr_options_parser.rb +0 -70
  35. data/lib/minglr/property_definition.rb +0 -2
  36. data/lib/minglr/transition_execution.rb +0 -2
  37. data/lib/minglr/user.rb +0 -2
  38. data/test/attachment_test.rb +0 -24
  39. data/test/minglr_resource_test.rb +0 -24
data/Rakefile CHANGED
@@ -63,3 +63,5 @@ Rake::RDocTask.new do |rdoc|
63
63
  rdoc.rdoc_files.include('lib/**/*.rb')
64
64
  end
65
65
 
66
+
67
+ task "dev" => ["test", "gemspec", "build"]
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :major: 1
3
- :minor: 1
2
+ :minor: 2
4
3
  :patch: 0
4
+ :major: 1
data/bin/minglr CHANGED
@@ -1,14 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'minglr'))
4
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'minglr', "minglr_action"))
5
4
 
6
- rc_config = MinglrConfigParser.parse
5
+ rc_config = Minglr::ConfigParser.parse
7
6
  uri_options = rc_config[:global] || {}
8
7
  project = rc_config[:global][:default].to_sym if rc_config[:global][:default]
9
8
  original_arguments = ARGV
10
9
 
11
- if MinglrAction::ACTIONS.include?(ARGV[0])
10
+ if Minglr::Action.valid_action?(ARGV[0])
12
11
  action = ARGV[0]
13
12
  else
14
13
  if ARGV[0] && (ARGV[0] =~ /^--/).nil?
@@ -17,13 +16,14 @@ else
17
16
  end
18
17
  end
19
18
 
20
- if project
19
+ unless project.nil?
20
+ if action.nil?
21
+ puts "No action specified. Valid actions are: #{Minglr::Action.valid_actions.join(", ")}"
22
+ exit 1
23
+ end
21
24
  uri_options.merge! rc_config[project]
22
- uri_options[:protocol] = uri_options[:url].slice(/^.*\:/).chop
23
- uri_options[:url].gsub!(/^(http|https)\:\/\//, "")
24
- uri_options[:host_and_port], uri_options[:project] = uri_options[:url].split("/projects/")
25
- MingleResource.configure uri_options
26
- Attachment.configure
27
- extra_options = MinglrOptionsParser.parse(original_arguments)
28
- MinglrAction.execute(action, ARGV, extra_options, rc_config[project])
25
+ Resources::Base.configure uri_options
26
+ Resources::Attachment.configure
27
+ extra_options = Minglr::OptionsParser.parse(original_arguments)
28
+ Minglr::Action.execute(action, ARGV, extra_options, rc_config[project])
29
29
  end
data/bin/mtx CHANGED
@@ -4,7 +4,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'minglr'
4
4
 
5
5
  uri_options, execution_options = MtxOptionsParser.parse(ARGV, :card, :transition)
6
6
 
7
- MingleResource.configure uri_options
7
+ Resources::Base.configure uri_options
8
8
 
9
9
  if card = Card.find(execution_options[:card])
10
10
  execution = TransitionExecution.create(execution_options)
data/lib/minglr.rb CHANGED
@@ -3,16 +3,24 @@ require 'activesupport'
3
3
  require 'activeresource'
4
4
  require 'optparse'
5
5
 
6
- require File.dirname(__FILE__) + '/minglr/mingle_resource'
7
- require File.dirname(__FILE__) + '/minglr/mtx_options_parser'
8
- require File.dirname(__FILE__) + '/minglr/minglr_options_parser'
9
- require File.dirname(__FILE__) + '/minglr/minglr_config_parser'
10
- require File.dirname(__FILE__) + '/minglr/card'
11
- require File.dirname(__FILE__) + '/minglr/user'
12
- require File.dirname(__FILE__) + '/minglr/property_definition'
13
- require File.dirname(__FILE__) + '/minglr/attachment'
14
- require File.dirname(__FILE__) + '/minglr/transition_execution'
15
- require File.dirname(__FILE__) + '/minglr/input_cache'
6
+ prefix = File.join(File.dirname(__FILE__), "minglr")
7
+ require File.join(prefix, "action")
8
+ require File.join(prefix, "options_parser")
9
+ require File.join(prefix, "config_parser")
10
+
11
+ require File.join(prefix, "mtx_options_parser")
12
+ require File.join(prefix, "input_cache")
13
+
14
+ require File.join(prefix, "resources", "base")
15
+ resources = File.join(prefix, "resources", "*")
16
+ Dir[resources].each do |file_name|
17
+ load file_name
18
+ end
19
+
20
+ extensions = File.join(prefix, "extensions", "*")
21
+ Dir[extensions].each do |file_name|
22
+ load file_name
23
+ end
16
24
 
17
25
  $:.unshift(File.dirname(__FILE__)) unless
18
26
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
@@ -0,0 +1,75 @@
1
+ module Minglr
2
+
3
+ class Action
4
+
5
+ def self.execute(action, options = [], flag_options = {}, config = {})
6
+ if action == options[0].to_sym
7
+ options.shift
8
+ else
9
+ options.shift
10
+ options.shift
11
+ end
12
+ begin
13
+ Commands.send(action, options, flag_options, config)
14
+ rescue ActiveResource::ResourceNotFound => error
15
+ puts error.message + " for URL #{Resources::Base.site}..."
16
+ end
17
+ end
18
+
19
+ def self.valid_actions
20
+ Commands.methods(false)
21
+ end
22
+
23
+ def self.valid_action?(action)
24
+ valid_actions.include? action
25
+ end
26
+
27
+ class Commands
28
+
29
+ def self.attach(options, flag_options, config)
30
+ card_number = options.first
31
+ file_name = flag_options[:file_attachment]
32
+ Resources::Attachment.attach(card_number, file_name, config[:username], config[:password])
33
+ end
34
+
35
+ def self.card(options, flag_options, config)
36
+ card_number = options.first
37
+ Resources::Card.print_card(options.first, config[:status_property])
38
+ end
39
+
40
+ def self.cards(options, flag_options, config)
41
+ Resources::Card.print_all(options, config[:status_property])
42
+ end
43
+
44
+ def self.create(options, flag_options, config)
45
+ Resources::Card.create(flag_options, config[:status_property])
46
+ end
47
+
48
+ def self.fetch(options, flag_options, config)
49
+ card_number = options.first
50
+ Resources::Attachment.fetch(card_number, config[:username], config[:password])
51
+ end
52
+
53
+ def self.move(options, flag_options, config)
54
+ card_number = options.first
55
+ Resources::Card.move(card_number, flag_options, config)
56
+ end
57
+
58
+ def self.projects(options, flag_options, config)
59
+ Resources::Project.print_all(options, config[:status_property])
60
+ end
61
+
62
+ def self.update(options, flag_options, config)
63
+ card_number = options.first
64
+ Resources::Card.update(card_number, flag_options)
65
+ end
66
+
67
+ def self.users(options, flag_options, config)
68
+ Resources::User.print_all(options)
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,49 @@
1
+ module Minglr
2
+
3
+ class ConfigParser
4
+
5
+ CONFIG_FILE = ".minglrconfig"
6
+ attr_reader :config
7
+
8
+ def self.parse
9
+ config_files = [File.join(ENV["HOME"], CONFIG_FILE), File.join(ENV["PWD"], CONFIG_FILE)]
10
+ config_files.each do |config_file_name|
11
+ if File.exist?(config_file_name)
12
+ return self.new(File.read(config_file_name)).config
13
+ end
14
+ end
15
+ puts "Unable to find #{CONFIG_FILE} in #{config_files.join(", ")}"
16
+ end
17
+
18
+ def initialize(config_contents)
19
+ @config = {}
20
+ @current_section = nil
21
+ config_contents.each_line do |line|
22
+ line = line.strip!
23
+ case line
24
+ when "", /^#.*$/
25
+ next
26
+ when /\[(.*)\]/
27
+ define_section($1.to_s)
28
+ else
29
+ define_var(line)
30
+ end
31
+ end
32
+ @config
33
+ end
34
+
35
+ def define_section(section_name)
36
+ @config[section_name.to_sym] = {} unless @config.has_key?(section_name.to_sym)
37
+ @current_section = section_name.to_sym
38
+ end
39
+
40
+ def define_var(line)
41
+ key, value = line.split("=")
42
+ key.strip!
43
+ value.strip!
44
+ @config[@current_section][key.to_sym] = value
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,23 @@
1
+ module Minglr
2
+
3
+ module Extensions
4
+
5
+ module Array
6
+
7
+ def filter(attributes, words)
8
+ collection = self
9
+ words.each do |word|
10
+ collection = self.select do |element|
11
+ output = ""
12
+ attributes.each { |attribute| output << element.send(attribute).to_s + " " }
13
+ output =~ /#{word}/i
14
+ end
15
+ end
16
+ collection
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -3,7 +3,7 @@ class InputCache
3
3
  def put(key, content)
4
4
  File.open(file_pathname(key), File::CREAT | File::WRONLY | File::TRUNC) { |file| file.write content }
5
5
  end
6
-
6
+
7
7
  def get(key)
8
8
  if content = File.read(file_pathname(key))
9
9
  return nil if content.blank?
@@ -12,9 +12,9 @@ class InputCache
12
12
  rescue
13
13
  nil
14
14
  end
15
-
15
+
16
16
  protected
17
-
17
+
18
18
  def file_pathname(key)
19
19
  File.join(Dir::tmpdir, "#{key.to_s.gsub(/[^\w]/, '')}.entry")
20
20
  end
@@ -0,0 +1,79 @@
1
+ module Minglr
2
+ class OptionsParser
3
+ def self.parse(args, *required_by_command)
4
+ project_options = []
5
+
6
+ if Resources::Base.site
7
+ begin
8
+ project_options = Resources::PropertyDefinition.project_options
9
+ rescue ActiveResource::UnauthorizedAccess => exception
10
+ puts "Connection #{exception.message} to #{Resources::Base.site.to_s}"
11
+ puts "Did you set 'basic_authentication_enabled: true' in your auth_config.yml file?"
12
+ exit 1
13
+ end
14
+ end
15
+
16
+ command_options = {}
17
+
18
+ parser = OptionParser.new do |opts|
19
+ opts.banner = "Usage: minglr [action] [options]"
20
+ opts.separator ""
21
+ opts.separator "Valid Commands Are: #{Minglr::Action.valid_actions.join(", ")}"
22
+
23
+ opts.on("-n NAME", String, "Short name of card") do |card_name|
24
+ command_options[:name] = card_name
25
+ end
26
+
27
+ opts.on("-d DESCRIPTION", String, "Description of card") do |card_description|
28
+ command_options[:description] = card_description
29
+ end
30
+
31
+ opts.on("-t TYPE", String, "Type of card") do |card_type|
32
+ command_options[:card_type_name] = card_type
33
+ end
34
+
35
+ opts.on("-c COMMENT", String, "Comment") do |comment|
36
+ command_options[:comment] = comment
37
+ end
38
+
39
+ opts.on("-f FILE", String, "File to attach") do |file|
40
+ command_options[:file_attachment] = file
41
+ end
42
+
43
+ unless project_options.empty?
44
+ opts.separator ""
45
+ opts.separator "Project Specific Options"
46
+
47
+ project_options.each do |option_pair|
48
+ option_switch = option_pair[1].downcase.gsub(/\s|_/, "-").gsub(/--|---/, '-').gsub(/--/, '-')
49
+ opts.on("--#{option_switch}", String, "Set the #{option_pair[1]} for a card") do |option|
50
+ command_options[option_pair[0]] = option
51
+ end
52
+ end
53
+
54
+ opts.separator ""
55
+ end
56
+
57
+ opts.on_tail("-h", "--help", "Show this help message.") do |help|
58
+ puts opts
59
+ exit
60
+ end
61
+
62
+ opts.on_tail("--version", "Show version") do
63
+ puts Minglr::VERSION
64
+ exit
65
+ end
66
+
67
+ if args.empty?
68
+ puts opts
69
+ exit
70
+ end
71
+ end
72
+
73
+ parser.parse! args
74
+ command_options
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,46 @@
1
+ require 'httpclient'
2
+
3
+ module Resources
4
+
5
+ class Attachment < Base
6
+
7
+ def self.configure
8
+ self.prefix += "cards/:card_number/"
9
+ end
10
+
11
+ def self.fetch(card_number, username, password)
12
+ if card_to_update = Card.find(card_number)
13
+ attachments = find(:all, :params => { :card_number => card_number })
14
+ attachments.each do |attachment|
15
+ url = self.site + attachment.url
16
+ url.userinfo = nil, nil
17
+ puts "Downloading #{url.to_s}:"
18
+ `curl --insecure --progress-bar --output #{attachment.file_name} --user #{username}:#{password} #{url}`
19
+ end
20
+ end
21
+ end
22
+
23
+ def self.attach(card_number, file_name, username, password)
24
+ if card_to_update = Card.find(card_number)
25
+ url = (site.to_s.gsub(/#{site.path}$/, '')) + collection_path(:card_number => card_number)
26
+ if File.exist?(file_name)
27
+ File.open(file_name) do |file|
28
+ body = { 'file' => file, "filename" => file_name }
29
+ client = HTTPClient.new
30
+ client.set_auth(nil, username, password)
31
+ response = client.post(url, body)
32
+ if response.status_code == 201
33
+ puts "File '#{file_name}' attached to card #{card_number}"
34
+ else
35
+ puts "Error attaching file '#{file_name}' to card #{card_number} (Got back HTTP code #{response.status_code})"
36
+ end
37
+ end
38
+ else
39
+ warn "Unable to open file '#{file_name}'"
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,42 @@
1
+ require "uri"
2
+
3
+ module Resources
4
+
5
+ class Base < ActiveResource::Base
6
+
7
+ def self.configure(uri_options)
8
+ uri = URI.parse(uri_options[:url])
9
+ uri.user = uri_options[:username]
10
+ uri.password = uri_options[:password]
11
+ self.site = uri
12
+ end
13
+
14
+ def self.print_collection(collection, attributes, align = :left)
15
+ output = []
16
+ longest_attributes = Array.new(attributes.length, 0)
17
+ alignment = (align == :left ? :ljust : :rjust)
18
+ collection.each do |element|
19
+ entry = []
20
+ attributes.each_with_index do |attribute, index|
21
+ attribute_value = element.send(attribute).to_s
22
+ longest_attributes[index] = attribute_value.length if attribute_value.length > longest_attributes[index]
23
+ entry << attribute_value
24
+ end
25
+ output << entry
26
+ end
27
+ output.each do |entry|
28
+ row = []
29
+ entry.each_with_index do |part, index|
30
+ row << [part.send(alignment, longest_attributes[index])]
31
+ end
32
+ puts row.join(" - ")
33
+ end
34
+ end
35
+
36
+ def self.warn(message)
37
+ puts "Warning: #{message}"
38
+ end
39
+
40
+ end
41
+
42
+ end