Class: GHI::Commands::Milestone

Inherits:
Command
  • Object
show all
Defined in:
lib/ghi/commands/milestone.rb

Constant Summary

Constants included from Formatting

Formatting::CURSOR, Formatting::THROBBERS

Constants included from Formatting::Colors

Formatting::Colors::ANSI, Formatting::Colors::WEB

Instance Attribute Summary collapse

Attributes inherited from Command

#action, #args, #verbose

Attributes included from Formatting

#paging

Instance Method Summary collapse

Methods inherited from Command

#api, #assigns, execute, #initialize, #repo, #repo=

Methods included from Formatting

#columns, #dimensions, #format_comment, #format_comment_editor, #format_comments_and_events, #format_date, #format_editor, #format_event, #format_event_type, #format_issue, #format_issues, #format_issues_header, #format_labels, #format_markdown, #format_milestone, #format_milestone_editor, #format_milestones, #format_number, #format_state, #format_tag, #format_username, #indent, #page, #paginate?, #paging?, #past_due?, #percent, #puts, #throb, #truncate

Methods included from Formatting::Colors

#bg, #blink, #bright, #colorize?, colorize?, #fg, #highlight, #inverse, #no_color, #to_hex, #underline

Constructor Details

This class inherits a constructor from GHI::Commands::Command

Instance Attribute Details

#editObject

Returns the value of attribute edit.



6
7
8
# File 'lib/ghi/commands/milestone.rb', line 6

def edit
  @edit
end

#reverseObject

Returns the value of attribute reverse.



7
8
9
# File 'lib/ghi/commands/milestone.rb', line 7

def reverse
  @reverse
end

#webObject

Returns the value of attribute web.



8
9
10
# File 'lib/ghi/commands/milestone.rb', line 8

def web
  @web
end

Instance Method Details

#executeObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/ghi/commands/milestone.rb', line 82

def execute
  self.action = 'index'
  require_repo
  extract_milestone

  begin
    options.parse! args
  rescue OptionParser::AmbiguousOption => e
    fallback.parse! e.args
  end

  milestone and case action
    when 'create' then self.action = 'update'
    when 'index'  then self.action = 'show'
  end

  if reverse
    assigns[:sort] ||= 'created'
    assigns[:direction] = 'asc'
  end

  case action
  when 'index'
    if web
      Web.new(repo).open 'milestones', assigns
    else
      assigns[:per_page] = 100
      state = assigns[:state] || 'open'
      print format_state state, "# #{repo} #{state} milestones"
      print "\n" unless paginate?
      res = throb(0, format_state(state, '#')) { api.get uri, assigns }
      page do
        milestones = res.body
        if verbose
          puts milestones.map { |m| format_milestone m }
        else
          puts format_milestones(milestones)
        end
        break unless res.next_page
        res = throb { api.get res.next_page }
      end
    end
  when 'show'
    if web
      List.execute %W(-w -M #{milestone} -- #{repo})
    else
      m = throb { api.get uri }.body
      page do
        puts format_milestone(m)
        puts 'Issues:'
        args.unshift(*%W(-q -M #{milestone} -- #{repo}))
        args.unshift '-v' if verbose
        List.execute args
        break
      end
    end
  when 'create'
    if web
      Web.new(repo).open 'issues/milestones/new'
    else
      if assigns[:title].nil?
        e = Editor.new 'GHI_MILESTONE'
        message = e.gets format_milestone_editor
        e.unlink 'Empty milestone.' if message.nil? || message.empty?
        assigns[:title], assigns[:description] = message.split(/\n+/, 2)
      end
      m = throb { api.post uri, assigns }.body
      puts 'Milestone #%d created.' % m['number']
      e.unlink if e
    end
  when 'update'
    if web
      Web.new(repo).open "issues/milestones/#{milestone}/edit"
    else
      if edit || assigns.empty?
        m = throb { api.get "/repos/#{repo}/milestones/#{milestone}" }.body
        e = Editor.new "GHI_MILESTONE_#{milestone}"
        message = e.gets format_milestone_editor(m)
        e.unlink 'Empty milestone.' if message.nil? || message.empty?
        assigns[:title], assigns[:description] = message.split(/\n+/, 2)
      end
      if assigns[:title] && m
        t_match = assigns[:title].strip == m['title'].strip
        if assigns[:description]
          b_match = assigns[:description].strip == m['description'].strip
        end
        if t_match && b_match
          e.unlink if e
          abort 'No change.' if assigns.dup.delete_if { |k, v|
            [:title, :description].include? k
          }
        end
      end
      m = throb { api.patch uri, assigns }.body
      puts format_milestone(m)
      puts 'Updated.'
      e.unlink if e
    end
  when 'destroy'
    require_milestone
    throb { api.delete uri }
    puts 'Milestone deleted.'
  end
end

#optionsObject

– FIXME: Opt for better interface, e.g.,

ghi milestone [-v | --verbose] [--[no-]closed]
ghi milestone add <name> <description>
ghi milestone rm <milestoneno>

++



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ghi/commands/milestone.rb', line 17

def options
  OptionParser.new do |opts|
    opts.banner = <<EOF
usage: ghi milestone [<modification options>] [<milestoneno>]
   or: ghi milestone -D <milestoneno>
   or: ghi milestone -l [-c] [-v]
EOF
    opts.separator ''
    opts.on '-l', '--list', 'list milestones' do
      self.action = 'index'
    end
    opts.on '-c', '--[no-]closed', 'show closed milestones' do |closed|
      assigns[:state] = closed ? 'closed' : 'open'
    end
    opts.on(
      '-S', '--sort <on>', %w(due_date completeness),
      {'d'=>'due_date', 'due'=>'due_date', 'c'=>'completeness'},
      "'due_date' or 'completeness'"
    ) do |sort|
      assigns[:sort] = sort
    end
    opts.on '--reverse', 'reverse (ascending) sort order' do
      self.reverse = !reverse
    end
    opts.on '-v', '--verbose', 'list milestones verbosely' do
      self.verbose = true
    end
    opts.on('-w', '--web') { self.web = true }
    opts.separator ''
    opts.separator 'Milestone modification options'
    opts.on(
      '-m', '--message [<text>]', 'change milestone description'
    ) do |text|
      self.action = 'create'
      self.edit = true
      next unless text
      assigns[:title], assigns[:description] = text.split(/\n+/, 2)
    end
    # FIXME: We already describe --[no-]closed; describe this, too?
    opts.on(
      '-s', '--state <in>', %w(open closed),
      {'o'=>'open', 'c'=>'closed'}, "'open' or 'closed'"
    ) do |state|
      self.action = 'create'
      assigns[:state] = state
    end
    opts.on(
      '--due <on>', 'when milestone should be complete',
      "e.g., '2012-04-30'"
    ) do |date|
      self.action = 'create'
      begin
        # TODO: Better parsing.
        assigns[:due_on] = DateTime.parse(date).strftime
      rescue ArgumentError => e
        raise OptionParser::InvalidArgument, e.message
      end
    end
    opts.on '-D', '--delete', 'delete milestone' do
      self.action = 'destroy'
    end
    opts.separator ''
  end
end