Class: MppReader::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/mpp_reader/cli.rb

Class Method Summary collapse

Class Method Details

.duration(d) ⇒ Object



108
# File 'lib/mpp_reader/cli.rb', line 108

def self.duration(d) = d && { value: d.value, units: d.units }

.iso(time) ⇒ Object



106
# File 'lib/mpp_reader/cli.rb', line 106

def self.iso(time) = time&.strftime("%Y-%m-%dT%H:%M:%S")

.json_for(project, file) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/mpp_reader/cli.rb', line 65

def self.json_for(project, file)
  {
    file: file,
    format: project.file_format,
    application: project.application_name,
    tasks: project.tasks.map do |t|
      {
        unique_id: t.unique_id, id: t.id, name: t.name,
        outline_level: t.outline_level,
        start: iso(t.start), finish: iso(t.finish),
        duration: duration(t.duration),
        percent_complete: t.percent_complete,
        milestone: t.milestone?, summary: t.summary?,
        active: t.active, manually_scheduled: t.manual,
        parent_unique_id: t.parent&.unique_id,
        predecessors: t.predecessors.map do |r|
          { predecessor_task_unique_id: r.predecessor_task_unique_id,
            type: r.type, lag: duration(r.lag) }
        end,
        notes: t.notes
      }.compact
    end,
    resources: project.resources.map do |r|
      { unique_id: r.unique_id, id: r.id, name: r.name,
        calendar_unique_id: r.calendar_unique_id, notes: r.notes }.compact
    end,
    assignments: project.assignments.map do |a|
      { unique_id: a.unique_id, task_unique_id: a.task_unique_id,
        resource_unique_id: a.resource_unique_id,
        start: iso(a.start), finish: iso(a.finish),
        units: a.units, work: duration(a.work), notes: a.notes }.compact
    end,
    calendars: project.calendars.map do |c|
      { unique_id: c.unique_id, name: c.name,
        base_calendar_unique_id: c.base_calendar_unique_id,
        resource_unique_id: c.resource_unique_id,
        days: c.days, exceptions: c.exceptions }.compact
    end
  }
end


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/mpp_reader/cli.rb', line 46

def self.print_tree(project, file, stdout)
  stdout.puts "#{file} (#{project.file_format}, #{project.application_name})"
  stdout.puts "\nTasks (#{project.tasks.size}):"
  project.tasks.each do |t|
    indent = "  " * (t.outline_level || 0)
    dates = [t.start&.strftime("%Y-%m-%d"), t.finish&.strftime("%Y-%m-%d")].compact.join(" .. ")
    extras = []
    extras << "#{t.duration.value.round(2)} #{t.duration.units}" if t.duration
    extras << "#{t.percent_complete}%" if t.percent_complete&.positive?
    extras << "milestone" if t.milestone?
    extras << "inactive" unless t.active
    line = "#{indent}[#{t.unique_id}] #{t.name} #{dates} #{extras.join(', ')}".rstrip
    stdout.puts line
    stdout.puts "#{indent}    > #{t.notes.gsub("\n", "\n#{indent}    > ")}" if t.notes
  end
  stdout.puts "\nResources (#{project.resources.size}):"
  project.resources.each { |r| stdout.puts "  [#{r.unique_id}] #{r.name}" }
end

.run(argv, stdout: $stdout, stderr: $stderr) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
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
# File 'lib/mpp_reader/cli.rb', line 6

def self.run(argv, stdout: $stdout, stderr: $stderr)
  options = { json: false }
  parser = OptionParser.new do |opts|
    opts.banner = "Usage: mpp_reader FILE... [options]"
    opts.on("--json", "Print one JSON object per file to stdout instead of a task tree") do
      options[:json] = true
    end
    opts.on("--version", "Print version") do
      stdout.puts MppReader::VERSION
      return 0
    end
  end

  begin
    files = parser.parse(argv)
  rescue OptionParser::ParseError => e
    stderr.puts e.message
    stderr.puts parser.banner
    return 2
  end
  if files.empty?
    stderr.puts parser.banner
    return 2
  end

  status = 0
  files.each do |file|
    project = MppReader.open(file)
    if options[:json]
      stdout.puts JSON.generate(json_for(project, file))
    else
      print_tree(project, file, stdout)
    end
  rescue MppReader::Error, SystemCallError => e
    stderr.puts "#{file}: #{e.message}"
    status = 1
  end
  status
end