class TaskJuggler::Tj3

Public Class Methods

new() click to toggle source
Calls superclass method TaskJuggler::Tj3AppBase.new
# File lib/taskjuggler/apps/Tj3.rb, line 23
def initialize
  super

  # tj3 just requires Ruby 1.8.7. All other apps need 1.9.2.
  @mininumRubyVersion = '1.8.7'
  # By default, we're only using 1 CPU core.
  @maxCpuCores = 1
  # Don't generate warnings for differences between time sheet data and
  # the plan.
  @warnTsDeltas = false
  # Don't stop after reading all files.
  @checkSyntax = false
  # Don't generate reports when previous errors have been found.
  @forceReports = false
  # List of requested report IDs.
  @reportIDs = []
  # List of requested report IDs (as regular expressions).
  @reportRegExpIDs = []
  # Don't generate trace reports by default
  @generateTraces = false
  # Should a booking file be generated?
  @freeze = false
  # The cut-off date for the freeze
  @freezeDate = TjTime.new.align(3600)
  # Should bookings be grouped by Task or by Resource (default).
  @freezeByTask = false
  # Generate a list of all defined reports if true.
  @listReports = false
  # Regular expression to select the report IDs to be listed.
  @listReportPattern = '*'
  # Don't generate any reports.
  @noReports = false
  # Treat warnings like errors or not.
  @abortOnWarning = false
  # The directory where generated reports should be put in.
  @outputDir = nil
  # The file names of the time sheet files to check.
  @timeSheets = []
  # The file names of the status sheet files to check.
  @statusSheets = []

  # Show some progress information by default
  TaskJuggler::Log.silent = false
end

Public Instance Methods

appMain(files) click to toggle source
# File lib/taskjuggler/apps/Tj3.rb, line 167
def appMain(files)
  if files.empty?
    error('tj3_tjp_file_missing',
          'You must provide at least one .tjp file')
  end
  if @outputDir && !File.directory?(@outputDir)
    error('tj3_outdir_missing',
          "Output directory '#{@outputDir}' does not exist or is not " +
          "a directory!")
  end

  tj = TaskJuggler.new
  tj.maxCpuCores = @maxCpuCores
  tj.warnTsDeltas = @warnTsDeltas
  tj.generateTraces = @generateTraces
  MessageHandlerInstance.instance.abortOnWarning = @abortOnWarning
  keepParser = !@timeSheets.empty? || !@statusSheets.empty?
  return 1 unless tj.parse(files, keepParser)

  return 0 if @checkSyntax

  if !tj.schedule
    return 1 unless @forceReports
  end

  # The checks of time and status sheets is probably only used for
  # debugging.  Normally, this function is provided by tj3client.
  @timeSheets.each do |ts|
    return 1 if !tj.checkTimeSheet(ts) || tj.errors > 0
  end
  @statusSheets.each do |ss|
    return 1 if !tj.checkStatusSheet(ss) || tj.errors > 0
  end

  # Check for freeze mode and generate the booking file if requested.
  if @freeze
    return 1 unless tj.freeze(@freezeDate, @freezeByTask) &&
                    tj.errors == 0
  end

  # List all the reports that match the requested expression.
  tj.listReports(@listReportPattern, true) if @listReports

  return 0 if @noReports

  if @reportIDs.empty? && @reportRegExpIDs.empty?
    return 1 if !tj.generateReports(@outputDir) || tj.errors > 0
  else
    @reportIDs.each do |id|
      return 1 if !tj.generateReport(id, false)
    end
    @reportRegExpIDs.each do |id|
      return 1 if !tj.generateReport(id, true)
    end
  end

  0
end
processArguments(argv) click to toggle source
# File lib/taskjuggler/apps/Tj3.rb, line 68
    def processArguments(argv)
      super do
        @opts.banner += <<'EOT'
This is the main application. It reads in your project files, schedules the
project and generates the reports.
EOT
        @opts.on('--debuglevel N', Integer,
                 format("Verbosity of debug output")) do |arg|
          TaskJuggler::Log.level = arg
        end
        @opts.on('--debugmodules x,y,z', Array,
                format('Restrict debug output to a list of modules')) do |arg|
          TaskJuggler::Log.segments = arg
        end
        @opts.on('--freeze',
                 format('Generate or update the booking file for ' +
                        'the project. The file will have the same ' +
                        'base name as the project file but has a ' +
                        '-bookings.tji extension.')) do
          @freeze = true
        end
        @opts.on('--freezedate <date>', String,
                 format('Use a different date than the current moment' +
                        'as cut-off date for the booking file')) do |arg|
          begin
            @freezeDate = TjTime.new(arg).align(3600)
          rescue TjException => msg
            error('tj3_ivld_freeze_date',
                  "Invalid freeze date: #{msg.message}")
          end
        end
        @opts.on('--freezebytask',
                 format('Group the bookings in the booking file generated ' +
                        'during a freeze by task instead of by resource.')) do
          @freezeByTask = true
        end
        @opts.on('--check-time-sheet <tji-file>', String,
                format("Check the given time sheet")) do |arg|
          @timeSheets << arg
        end
        @opts.on('--check-status-sheet <tji-file>', String,
                format("Check the given status sheet")) do |arg|
          @statusSheets << arg
        end
        @opts.on('--warn-ts-deltas',
                format('Turn on warnings for requested changes in time ' +
                       'sheets')) do
         @warnTsDeltas = true
        end
        @opts.on('--check-syntax',
                format('Only parse the input files and check the syntax.')) do
         @checkSyntax = true
        end
        @opts.on('--no-reports',
                format('Just schedule the project, but don\t generate any ' +
                       'reports.')) do
         @noReports = true
        end
        @opts.on('--list-reports <report ID regular expression>', String,
                 format('List id, formats and file name of all the defined ' +
                        'reports that have IDs that match the specified ' +
                        'regular expression.')) do |arg|
          @listReports = true
          @listReportPattern = arg
        end
        @opts.on('--report <report ID>', String,
                 format('Only generate the report with the specified ID. ' +
                        'This option can be used multiple times.')) do |arg|
          @reportIDs << arg
        end
        @opts.on('--reports <report ID regular expression>', String,
                 format('Only generate the reports that have IDs that match ' +
                        'the specified regular expression. This option can ' +
                        'be used multiple times.')) do |arg|
          @reportRegExpIDs << arg
        end
        @opts.on('-f', '--force-reports',
                format('Generate reports despite scheduling errors')) do
          @forceReports = true
        end
        @opts.on('--add-trace',
                 format('Append a current data set to all trace reports.')) do
          @generateTraces = true
        end
        @opts.on('--abort-on-warnings',
                 format('Abort program on warnings like we do on errors.')) do
          @abortOnWarning = true
        end
        @opts.on('-o', '--output-dir <directory>', String,
                format('Directory the reports should go into')) do |arg|
          @outputDir = arg + (arg[-1] == ?/ ? '' : '/')
        end
        @opts.on('-c N', Integer,
                 format('Maximum number of CPU cores to use')) do |arg|
          @maxCpuCores = arg
        end
      end
    end