taskjuggler 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +35 -0
- data/data/tjp.vim +21 -7
- data/lib/taskjuggler/Allocation.rb +27 -3
- data/lib/taskjuggler/Attributes.rb +3 -2
- data/lib/taskjuggler/HTMLDocument.rb +3 -1
- data/lib/taskjuggler/KateSyntax.rb +213 -0
- data/lib/taskjuggler/Limits.rb +22 -0
- data/lib/taskjuggler/Log.rb +1 -1
- data/lib/taskjuggler/MessageHandler.rb +20 -10
- data/lib/taskjuggler/PTNProxy.rb +6 -1
- data/lib/taskjuggler/Project.rb +10 -4
- data/lib/taskjuggler/ProjectFileParser.rb +1 -2
- data/lib/taskjuggler/ProjectFileScanner.rb +41 -42
- data/lib/taskjuggler/ResourceScenario.rb +41 -1
- data/lib/taskjuggler/RichText/Element.rb +8 -0
- data/lib/taskjuggler/RichText/Parser.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +20 -10
- data/lib/taskjuggler/RichText/Scanner.rb +54 -38
- data/lib/taskjuggler/RichText/SyntaxRules.rb +12 -0
- data/lib/taskjuggler/SheetReceiver.rb +1 -1
- data/lib/taskjuggler/TableColumnDefinition.rb +5 -1
- data/lib/taskjuggler/TaskJuggler.rb +2 -2
- data/lib/taskjuggler/TaskScenario.rb +117 -33
- data/lib/taskjuggler/TextParser.rb +2 -4
- data/lib/taskjuggler/TextParser/MacroTable.rb +7 -0
- data/lib/taskjuggler/TextParser/Scanner.rb +10 -9
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjTime.rb +5 -28
- data/lib/taskjuggler/TjpSyntaxRules.rb +85 -13
- data/lib/taskjuggler/UTF8String.rb +5 -0
- data/lib/taskjuggler/XMLElement.rb +2 -1
- data/lib/taskjuggler/apps/Tj3.rb +29 -5
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +1 -1
- data/lib/taskjuggler/daemon/ProjectServer.rb +5 -2
- data/lib/taskjuggler/daemon/ReportServer.rb +7 -4
- data/lib/taskjuggler/reports/AccountListRE.rb +2 -0
- data/lib/taskjuggler/reports/CSVFile.rb +24 -2
- data/lib/taskjuggler/reports/GanttChart.rb +3 -2
- data/lib/taskjuggler/reports/GanttHeader.rb +18 -18
- data/lib/taskjuggler/reports/GanttLoadStack.rb +1 -1
- data/lib/taskjuggler/reports/MspXmlRE.rb +5 -1
- data/lib/taskjuggler/reports/Report.rb +29 -18
- data/lib/taskjuggler/reports/ReportTable.rb +5 -1
- data/lib/taskjuggler/reports/ReportTableCell.rb +16 -10
- data/lib/taskjuggler/reports/ResourceListRE.rb +2 -0
- data/lib/taskjuggler/reports/TableReport.rb +23 -16
- data/lib/taskjuggler/reports/TaskListRE.rb +2 -0
- data/lib/taskjuggler/reports/TraceReport.rb +1 -1
- data/manual/Installation +5 -1
- data/manual/Intro +1 -0
- data/manual/Rich_Text_Attributes +5 -0
- data/manual/TaskJuggler_Internals +82 -34
- data/manual/Tutorial +1 -1
- data/manual/html/Day_To_Day_Juggling.html +1 -1
- data/manual/html/Getting_Started.html +1 -1
- data/manual/html/How_To_Contribute.html +1 -1
- data/manual/html/Installation.html +3 -2
- data/manual/html/Intro.html +2 -1
- data/manual/html/Reporting_Bugs.html +1 -1
- data/manual/html/Rich_Text_Attributes.html +2 -1
- data/manual/html/Software.html +1 -1
- data/manual/html/TaskJuggler_2x_Migration.html +1 -1
- data/manual/html/TaskJuggler_Internals.html +15 -13
- data/manual/html/The_TaskJuggler_Syntax.html +1 -1
- data/manual/html/Tutorial.html +2 -2
- data/manual/html/account.html +1 -1
- data/manual/html/account.task.html +1 -1
- data/manual/html/accountprefix.html +1 -1
- data/manual/html/accountreport.html +14 -2
- data/manual/html/accountroot.html +1 -1
- data/manual/html/active.html +1 -1
- data/manual/html/adopt.task.html +1 -1
- data/manual/html/aggregate.html +1 -1
- data/manual/html/alert.html +1 -1
- data/manual/html/alertlevels.html +1 -1
- data/manual/html/allocate.html +1 -1
- data/manual/html/alphabet.html +1 -1
- data/manual/html/alternative.html +1 -1
- data/manual/html/author.html +3 -3
- data/manual/html/auxdir.html +69 -0
- data/manual/html/balance.html +3 -3
- data/manual/html/booking.resource.html +1 -1
- data/manual/html/booking.task.html +1 -1
- data/manual/html/caption.html +1 -1
- data/manual/html/cellcolor.column.html +1 -1
- data/manual/html/celltext.column.html +1 -1
- data/manual/html/center.html +1 -1
- data/manual/html/charge.html +1 -1
- data/manual/html/chargeset.html +1 -1
- data/manual/html/columnid.html +21 -9
- data/manual/html/columns.html +2 -2
- data/manual/html/complete.html +1 -1
- data/manual/html/copyright.html +1 -1
- data/manual/html/credits.html +1 -1
- data/manual/html/currency.html +1 -1
- data/manual/html/currencyformat.html +1 -1
- data/manual/html/dailymax.html +1 -1
- data/manual/html/dailymin.html +1 -1
- data/manual/html/dailyworkinghours.html +1 -1
- data/manual/html/date.extend.html +1 -1
- data/manual/html/date.html +1 -1
- data/manual/html/definitions.html +1 -1
- data/manual/html/depends.html +1 -1
- data/manual/html/details.html +1 -1
- data/manual/html/disabled.html +1 -1
- data/manual/html/duration.html +1 -1
- data/manual/html/efficiency.html +1 -1
- data/manual/html/effort.html +1 -1
- data/manual/html/email.html +1 -1
- data/manual/html/enabled.html +1 -1
- data/manual/html/end.column.html +1 -1
- data/manual/html/end.html +1 -1
- data/manual/html/end.limit.html +1 -1
- data/manual/html/end.report.html +1 -1
- data/manual/html/end.timesheet.html +1 -1
- data/manual/html/endcredit.html +1 -1
- data/manual/html/epilog.html +1 -1
- data/manual/html/export.html +1 -1
- data/manual/html/extend.html +1 -1
- data/manual/html/fail.html +1 -1
- data/manual/html/fdl.html +1 -1
- data/manual/html/flags.account.html +1 -1
- data/manual/html/flags.html +1 -1
- data/manual/html/flags.journalentry.html +1 -1
- data/manual/html/flags.report.html +1 -1
- data/manual/html/flags.resource.html +1 -1
- data/manual/html/flags.statussheet.html +1 -1
- data/manual/html/flags.task.html +1 -1
- data/manual/html/flags.timesheet.html +1 -1
- data/manual/html/fontcolor.column.html +1 -1
- data/manual/html/footer.html +1 -1
- data/manual/html/formats.export.html +1 -1
- data/manual/html/formats.html +1 -1
- data/manual/html/functions.html +1 -1
- data/manual/html/gapduration.html +1 -1
- data/manual/html/gaplength.html +1 -1
- data/manual/html/halign.center.html +1 -1
- data/manual/html/halign.column.html +1 -1
- data/manual/html/halign.left.html +1 -1
- data/manual/html/halign.right.html +1 -1
- data/manual/html/hasalert.html +1 -1
- data/manual/html/header.html +1 -1
- data/manual/html/headline.html +1 -1
- data/manual/html/height.html +1 -1
- data/manual/html/hideaccount.html +1 -1
- data/manual/html/hidejournalentry.html +1 -1
- data/manual/html/hidereport.html +1 -1
- data/manual/html/hideresource.html +1 -1
- data/manual/html/hidetask.html +1 -1
- data/manual/html/icalreport.html +1 -1
- data/manual/html/include.macro.html +1 -1
- data/manual/html/include.project.html +1 -1
- data/manual/html/include.properties.html +1 -1
- data/manual/html/index.html +1 -1
- data/manual/html/inherit.extend.html +1 -1
- data/manual/html/interval1.html +1 -1
- data/manual/html/interval2.html +1 -1
- data/manual/html/interval3.html +1 -1
- data/manual/html/interval4.html +1 -1
- data/manual/html/isactive.html +1 -1
- data/manual/html/ischildof.html +1 -1
- data/manual/html/isdependencyof.html +1 -1
- data/manual/html/isdutyof.html +1 -1
- data/manual/html/isfeatureof.html +1 -1
- data/manual/html/isleaf.html +1 -1
- data/manual/html/ismilestone.html +1 -1
- data/manual/html/isongoing.html +1 -1
- data/manual/html/isresource.html +1 -1
- data/manual/html/isresponsibilityof.html +1 -1
- data/manual/html/istask.html +1 -1
- data/manual/html/journalattributes.html +1 -1
- data/manual/html/journalentry.html +1 -1
- data/manual/html/journalmode.html +1 -1
- data/manual/html/leaveallowance.html +1 -1
- data/manual/html/leaves.html +1 -1
- data/manual/html/left.html +1 -1
- data/manual/html/length.html +1 -1
- data/manual/html/limits.allocate.html +1 -1
- data/manual/html/limits.html +1 -1
- data/manual/html/limits.resource.html +1 -1
- data/manual/html/limits.task.html +1 -1
- data/manual/html/listitem.column.html +1 -1
- data/manual/html/listtype.column.html +1 -1
- data/manual/html/loadunit.html +1 -1
- data/manual/html/logicalexpression.html +1 -1
- data/manual/html/logicalflagexpression.html +1 -1
- data/manual/html/macro.html +1 -1
- data/manual/html/managers.html +1 -1
- data/manual/html/mandatory.html +1 -1
- data/manual/html/maxend.html +1 -1
- data/manual/html/maximum.html +1 -1
- data/manual/html/maxstart.html +1 -1
- data/manual/html/milestone.html +1 -1
- data/manual/html/minend.html +1 -1
- data/manual/html/minimum.html +1 -1
- data/manual/html/minstart.html +1 -1
- data/manual/html/monthlymax.html +1 -1
- data/manual/html/monthlymin.html +1 -1
- data/manual/html/navbar.html +9 -1
- data/manual/html/navigator.html +1 -1
- data/manual/html/newtask.html +1 -1
- data/manual/html/nikureport.html +1 -1
- data/manual/html/note.task.html +1 -1
- data/manual/html/now.html +1 -1
- data/manual/html/numberformat.html +1 -1
- data/manual/html/onend.html +1 -1
- data/manual/html/onstart.html +1 -1
- data/manual/html/opennodes.html +1 -1
- data/manual/html/overtime.booking.html +1 -1
- data/manual/html/period.column.html +1 -1
- data/manual/html/period.limit.html +1 -1
- data/manual/html/period.report.html +1 -1
- data/manual/html/period.task.html +1 -1
- data/manual/html/persistent.html +1 -1
- data/manual/html/precedes.html +1 -1
- data/manual/html/priority.html +1 -1
- data/manual/html/priority.timesheet.html +1 -1
- data/manual/html/project.html +1 -1
- data/manual/html/projectid.html +1 -1
- data/manual/html/projectid.task.html +1 -1
- data/manual/html/projectids.html +1 -1
- data/manual/html/projection.html +1 -1
- data/manual/html/prolog.html +1 -1
- data/manual/html/properties.html +1 -1
- data/manual/html/purge.html +1 -1
- data/manual/html/rate.html +1 -1
- data/manual/html/rate.resource.html +3 -3
- data/manual/html/rawhtmlhead.html +68 -0
- data/manual/html/reference.extend.html +3 -3
- data/manual/html/remaining.html +1 -1
- data/manual/html/replace.html +1 -1
- data/manual/html/reportprefix.html +1 -1
- data/manual/html/resource.html +1 -1
- data/manual/html/resourceattributes.html +1 -1
- data/manual/html/resourceprefix.html +1 -1
- data/manual/html/resourcereport.html +14 -2
- data/manual/html/resourceroot.html +1 -1
- data/manual/html/resources.limit.html +1 -1
- data/manual/html/responsible.html +1 -1
- data/manual/html/richtext.extend.html +1 -1
- data/manual/html/right.html +1 -1
- data/manual/html/rollupaccount.html +1 -1
- data/manual/html/rollupresource.html +1 -1
- data/manual/html/rolluptask.html +1 -1
- data/manual/html/scale.column.html +1 -1
- data/manual/html/scenario.html +1 -1
- data/manual/html/scenario.ical.html +1 -1
- data/manual/html/scenarios.export.html +1 -1
- data/manual/html/scenarios.html +1 -1
- data/manual/html/scenariospecific.extend.html +1 -1
- data/manual/html/scheduled.html +1 -1
- data/manual/html/scheduling.html +2 -1
- data/manual/html/select.html +1 -1
- data/manual/html/selfcontained.html +1 -1
- data/manual/html/shift.allocate.html +1 -1
- data/manual/html/shift.html +1 -1
- data/manual/html/shift.resource.html +1 -1
- data/manual/html/shift.task.html +1 -1
- data/manual/html/shift.timesheet.html +1 -1
- data/manual/html/shifts.allocate.html +1 -1
- data/manual/html/shifts.resource.html +1 -1
- data/manual/html/shifts.task.html +1 -1
- data/manual/html/shorttimeformat.html +1 -1
- data/manual/html/sloppy.booking.html +1 -1
- data/manual/html/sloppy.projection.html +1 -1
- data/manual/html/sortaccounts.html +1 -1
- data/manual/html/sortjournalentries.html +1 -1
- data/manual/html/sortresources.html +1 -1
- data/manual/html/sorttasks.html +1 -1
- data/manual/html/start.column.html +1 -1
- data/manual/html/start.html +1 -1
- data/manual/html/start.limit.html +1 -1
- data/manual/html/start.report.html +1 -1
- data/manual/html/startcredit.html +1 -1
- data/manual/html/status.statussheet.html +1 -1
- data/manual/html/status.timesheet.html +1 -1
- data/manual/html/statussheet.html +1 -1
- data/manual/html/statussheetreport.html +1 -1
- data/manual/html/strict.projection.html +1 -1
- data/manual/html/summary.html +1 -1
- data/manual/html/supplement.html +1 -1
- data/manual/html/supplement.resource.html +1 -1
- data/manual/html/supplement.task.html +1 -1
- data/manual/html/tagfile.html +2 -2
- data/manual/html/task.html +1 -1
- data/manual/html/task.statussheet.html +1 -1
- data/manual/html/task.timesheet.html +1 -1
- data/manual/html/taskattributes.html +1 -1
- data/manual/html/taskprefix.html +1 -1
- data/manual/html/taskreport.html +14 -2
- data/manual/html/taskroot.export.html +1 -1
- data/manual/html/taskroot.html +1 -1
- data/manual/html/text.extend.html +1 -1
- data/manual/html/textreport.html +14 -2
- data/manual/html/timeformat.html +3 -3
- data/manual/html/timeformat1.html +67 -0
- data/manual/html/timeformat2.html +67 -0
- data/manual/html/timeoff.nikureport.html +3 -3
- data/manual/html/timesheet.html +1 -1
- data/manual/html/timesheetreport.html +1 -1
- data/manual/html/timezone.export.html +1 -1
- data/manual/html/timezone.html +1 -1
- data/manual/html/timezone.report.html +1 -1
- data/manual/html/timezone.shift.html +1 -1
- data/manual/html/timingresolution.html +1 -1
- data/manual/html/title.column.html +1 -1
- data/manual/html/title.html +1 -1
- data/manual/html/toc.html +270 -242
- data/manual/html/tooltip.column.html +1 -1
- data/manual/html/tracereport.html +14 -2
- data/manual/html/trackingscenario.html +1 -1
- data/manual/html/treelevel.html +1 -1
- data/manual/html/vacation.html +1 -1
- data/manual/html/vacation.resource.html +1 -1
- data/manual/html/vacation.shift.html +1 -1
- data/manual/html/warn.html +1 -1
- data/manual/html/weeklymax.html +1 -1
- data/manual/html/weeklymin.html +1 -1
- data/manual/html/weekstartsmonday.html +1 -1
- data/manual/html/weekstartssunday.html +1 -1
- data/manual/html/width.column.html +1 -1
- data/manual/html/width.html +1 -1
- data/manual/html/work.html +1 -1
- data/manual/html/workinghours.project.html +1 -1
- data/manual/html/workinghours.resource.html +1 -1
- data/manual/html/workinghours.shift.html +1 -1
- data/manual/html/yearlyworkingdays.html +1 -1
- data/tasks/kate.rake +8 -0
- data/test/TestSuite/HTML-Reports/Calendars.tjp +10 -0
- data/test/TestSuite/Scheduler/Correct/PersistentResources-2.tjp +33 -0
- data/test/TestSuite/Scheduler/Correct/PersistentResources.tjp +30 -0
- data/test/TestSuite/Scheduler/Correct/PriorityInversion.tjp +2 -0
- data/test/TestSuite/Syntax/Correct/Macro-4.tjp +4 -0
- data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
- data/test/test_BatchProcessor.rb +1 -1
- data/test/test_CSVFile.rb +10 -0
- data/test/test_RichText.rb +20 -0
- metadata +38 -9
|
@@ -341,8 +341,7 @@ class TaskJuggler
|
|
|
341
341
|
"Unexpected token '#{token[1]}' found. " +
|
|
342
342
|
"Expecting #{@stack.last.state.expectedTokens.length > 1 ?
|
|
343
343
|
'one of ' : ''}" +
|
|
344
|
-
"#{@stack.last.state.expectedTokens.join(', ')}",
|
|
345
|
-
@scanner.sourceFileInfo)
|
|
344
|
+
"#{@stack.last.state.expectedTokens.join(', ')}", token[2])
|
|
346
345
|
end
|
|
347
346
|
if finishPattern(token)
|
|
348
347
|
# Accept: We're done with parsing.
|
|
@@ -378,8 +377,7 @@ class TaskJuggler
|
|
|
378
377
|
# rules.
|
|
379
378
|
error('unexpctd_token', "Unexpected token '#{token[1]}' found. " +
|
|
380
379
|
"Expecting one of " +
|
|
381
|
-
"#{stackEntry.state.expectedTokens.join(', ')}",
|
|
382
|
-
@scanner.sourceFileInfo)
|
|
380
|
+
"#{stackEntry.state.expectedTokens.join(', ')}", token[2])
|
|
383
381
|
end
|
|
384
382
|
# Memorize if the rule for this pattern was repeatable. Then we will
|
|
385
383
|
# store the result of the pattern in an Array.
|
|
@@ -57,6 +57,13 @@ class TaskJuggler::TextParser
|
|
|
57
57
|
# unchanged. No error is generated.
|
|
58
58
|
def resolve(args, sourceFileInfo)
|
|
59
59
|
name = args[0]
|
|
60
|
+
# If the first character of the macro name is a '?', the macro may be
|
|
61
|
+
# undefined and is silently ignored.
|
|
62
|
+
if name[0] == ??
|
|
63
|
+
# Remove the '?' from the name.
|
|
64
|
+
name = name[1..-1]
|
|
65
|
+
return [ nil, '' ] unless @macros[name]
|
|
66
|
+
end
|
|
60
67
|
return nil unless @macros[name]
|
|
61
68
|
|
|
62
69
|
resolved = @macros[name].value.dup
|
|
@@ -174,7 +174,7 @@ class TaskJuggler::TextParser
|
|
|
174
174
|
begin
|
|
175
175
|
@stream = StringIO.new(data.forceUTF8Encoding)
|
|
176
176
|
rescue
|
|
177
|
-
error('fileEncoding',
|
|
177
|
+
error('fileEncoding', $!.message)
|
|
178
178
|
end
|
|
179
179
|
@log.msg { "Parsing file #{@fileName} ..." }
|
|
180
180
|
@log.startProgressMeter("Reading file #{fileName}")
|
|
@@ -195,7 +195,7 @@ class TaskJuggler::TextParser
|
|
|
195
195
|
begin
|
|
196
196
|
@stream = StringIO.new(buffer.forceUTF8Encoding)
|
|
197
197
|
rescue
|
|
198
|
-
error('bufferEncoding',
|
|
198
|
+
error('bufferEncoding', $!.message)
|
|
199
199
|
end
|
|
200
200
|
#@log.msg { "Parsing buffer #{buffer[0, 20]} ..." }
|
|
201
201
|
end
|
|
@@ -242,9 +242,9 @@ class TaskJuggler::TextParser
|
|
|
242
242
|
tokenPatterns.each do |pat|
|
|
243
243
|
type = pat[0]
|
|
244
244
|
regExp = pat[1]
|
|
245
|
-
mode = pat[
|
|
246
|
-
postProc = pat[
|
|
247
|
-
addPattern(type,
|
|
245
|
+
mode = pat[2] || :tjp
|
|
246
|
+
postProc = pat[3]
|
|
247
|
+
addPattern(type, regExp, mode, postProc)
|
|
248
248
|
end
|
|
249
249
|
self.mode = defaultMode
|
|
250
250
|
end
|
|
@@ -449,13 +449,14 @@ class TaskJuggler::TextParser
|
|
|
449
449
|
def expandMacro(prefix, args, callLength)
|
|
450
450
|
# Get the expanded macro from the @macroTable.
|
|
451
451
|
macro, text = @macroTable.resolve(args, sourceFileInfo)
|
|
452
|
-
unless macro && text
|
|
453
|
-
error('undefined_macro', "Undefined macro '#{args[0]}' called")
|
|
454
|
-
end
|
|
455
452
|
|
|
456
453
|
# If the expanded macro is empty, we can ignore it.
|
|
457
454
|
return if text == ''
|
|
458
455
|
|
|
456
|
+
unless macro && text
|
|
457
|
+
error('undefined_macro', "Undefined macro '#{args[0]}' called")
|
|
458
|
+
end
|
|
459
|
+
|
|
459
460
|
unless @cf.injectMacro(macro, args, prefix + text, callLength)
|
|
460
461
|
error('macro_stack_overflow', "Too many nested macro calls.")
|
|
461
462
|
end
|
|
@@ -526,7 +527,7 @@ class TaskJuggler::TextParser
|
|
|
526
527
|
rescue ArgumentError
|
|
527
528
|
# This is triggered by StringScanner.scan, but we don't want to put
|
|
528
529
|
# the block in the inner loops for performance reasons.
|
|
529
|
-
error('scan_encoding_error', $!.
|
|
530
|
+
error('scan_encoding_error', $!.message)
|
|
530
531
|
end
|
|
531
532
|
end
|
|
532
533
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
require 'taskjuggler/UTF8String'
|
|
15
15
|
require 'taskjuggler/AppConfig'
|
|
16
16
|
|
|
17
|
-
AppConfig.version = '3.
|
|
17
|
+
AppConfig.version = '3.4.0'
|
|
18
18
|
AppConfig.packageName = 'taskjuggler'
|
|
19
19
|
AppConfig.softwareName = 'TaskJuggler'
|
|
20
20
|
AppConfig.packageInfo = 'A Project Management Software'
|
data/lib/taskjuggler/TjTime.rb
CHANGED
|
@@ -370,10 +370,13 @@ class TaskJuggler
|
|
|
370
370
|
def to_s(format = nil)
|
|
371
371
|
return 'unknown' if @time.nil?
|
|
372
372
|
if format.nil?
|
|
373
|
-
|
|
373
|
+
fmt = '%Y-%m-%d-%H:%M' + (@time.sec == 0 ? '' : ':%S') + '-%z'
|
|
374
|
+
else
|
|
375
|
+
# Handle TJ specific extensions to the strftime format.
|
|
376
|
+
fmt = format.sub(/%Q/, "#{((localtime.mon - 1) / 3) + 1}")
|
|
374
377
|
end
|
|
375
378
|
# Always report values in local timezone
|
|
376
|
-
localtime.strftime(
|
|
379
|
+
localtime.strftime(fmt)
|
|
377
380
|
end
|
|
378
381
|
|
|
379
382
|
# Return the seconds since Epoch.
|
|
@@ -416,32 +419,6 @@ class TaskJuggler
|
|
|
416
419
|
localtime.year
|
|
417
420
|
end
|
|
418
421
|
|
|
419
|
-
# Return the abbreviated month name.
|
|
420
|
-
def shortMonthName
|
|
421
|
-
localtime.strftime('%b')
|
|
422
|
-
end
|
|
423
|
-
|
|
424
|
-
# Return the number of the quarter prefixed by a 'Q'.
|
|
425
|
-
def quarterName
|
|
426
|
-
"Q#{(localtime.mon / 3) + 1}"
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
# Return the week number. _weekStartsMonday_ specifies wheter the counting
|
|
430
|
-
# should be for weeks starting Mondays or Sundays.
|
|
431
|
-
def week(weekStartsMonday)
|
|
432
|
-
localtime.strftime(weekStartsMonday ? '%W' : '%U')
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
# Return the abbreviated month name and the full year. E. g. 'Feb 1972'.
|
|
436
|
-
def monthAndYear
|
|
437
|
-
localtime.strftime('%b %Y')
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
# Return the abbreviated weekday and the full date. E. g. 'Sat 2007-11-03'.
|
|
441
|
-
def weekdayAndDate
|
|
442
|
-
localtime.strftime('%A %Y-%m-%d')
|
|
443
|
-
end
|
|
444
|
-
|
|
445
422
|
private
|
|
446
423
|
|
|
447
424
|
def parse(t)
|
|
@@ -839,6 +839,26 @@ invariant values.
|
|
|
839
839
|
EOT
|
|
840
840
|
)
|
|
841
841
|
|
|
842
|
+
pattern(%w( _timeformat1 $STRING ), lambda {
|
|
843
|
+
@column.timeformat1 = @val[1]
|
|
844
|
+
})
|
|
845
|
+
doc('timeformat1', <<'EOT'
|
|
846
|
+
Specify an alternative format for the upper header line of calendar or Gantt
|
|
847
|
+
chart columns.
|
|
848
|
+
EOT
|
|
849
|
+
)
|
|
850
|
+
arg(1, 'format', 'See [[timeformat]] for details.')
|
|
851
|
+
|
|
852
|
+
pattern(%w( _timeformat2 $STRING ), lambda {
|
|
853
|
+
@column.timeformat2 = @val[1]
|
|
854
|
+
})
|
|
855
|
+
doc('timeformat2', <<'EOT'
|
|
856
|
+
Specify an alternative format for the lower header line of calendar or Gantt
|
|
857
|
+
chart columns.
|
|
858
|
+
EOT
|
|
859
|
+
)
|
|
860
|
+
arg(1, 'format', 'See [[timeformat]] for details.')
|
|
861
|
+
|
|
842
862
|
pattern(%w( _title $STRING ), lambda {
|
|
843
863
|
@column.title = @val[1]
|
|
844
864
|
})
|
|
@@ -3670,14 +3690,14 @@ EOT
|
|
|
3670
3690
|
singlePattern('_annualleave')
|
|
3671
3691
|
descr(<<'EOT'
|
|
3672
3692
|
The number of annual leave units within the reported time period. The unit
|
|
3673
|
-
can be adjusted with [[loadunit
|
|
3693
|
+
can be adjusted with [[loadunit]].
|
|
3674
3694
|
EOT
|
|
3675
3695
|
)
|
|
3676
3696
|
|
|
3677
3697
|
singlePattern('_annualleavebalance')
|
|
3678
3698
|
descr(<<'EOT'
|
|
3679
3699
|
The balance of the annual leave at the end of the reporting interval. The unit
|
|
3680
|
-
can be adjusted with [[loadunit
|
|
3700
|
+
can be adjusted with [[loadunit]].
|
|
3681
3701
|
EOT
|
|
3682
3702
|
)
|
|
3683
3703
|
|
|
@@ -3704,8 +3724,8 @@ EOT
|
|
|
3704
3724
|
singlePattern('_alerttrend')
|
|
3705
3725
|
descr(<<'EOT'
|
|
3706
3726
|
Shows how the alert level at the end of the report period compares to the
|
|
3707
|
-
alert level at the begining of the report period. Possible values are
|
|
3708
|
-
or
|
|
3727
|
+
alert level at the begining of the report period. Possible values are
|
|
3728
|
+
''''Up'''', ''''Down'''' or ''''Flat''''.
|
|
3709
3729
|
EOT
|
|
3710
3730
|
)
|
|
3711
3731
|
|
|
@@ -3730,6 +3750,19 @@ EOT
|
|
|
3730
3750
|
The number of sub-tasks (including the current task) that have been closed
|
|
3731
3751
|
during the reported time period. Closed means that they have and end date
|
|
3732
3752
|
before the current time or [[now]] date.
|
|
3753
|
+
EOT
|
|
3754
|
+
)
|
|
3755
|
+
|
|
3756
|
+
singlePattern('_competitorcount')
|
|
3757
|
+
descr(<<'EOT'
|
|
3758
|
+
The number of tasks that have successfully competed for the same resources and
|
|
3759
|
+
have potentially delayed the completion of this task.
|
|
3760
|
+
EOT
|
|
3761
|
+
)
|
|
3762
|
+
singlePattern('_competitors')
|
|
3763
|
+
descr(<<'EOT'
|
|
3764
|
+
A list of tasks that have successfully competed for the same resources and
|
|
3765
|
+
have potentially delayed the completion of this task.
|
|
3733
3766
|
EOT
|
|
3734
3767
|
)
|
|
3735
3768
|
|
|
@@ -4020,20 +4053,26 @@ EOT
|
|
|
4020
4053
|
singlePattern('_scenario')
|
|
4021
4054
|
descr('The name of the scenario')
|
|
4022
4055
|
|
|
4056
|
+
singlePattern('_scheduling')
|
|
4057
|
+
descr(<<'EOT'
|
|
4058
|
+
The scheduling mode of the leaf tasks. ASAP tasks are scheduled start to end while ALAP tasks are scheduled end to start.
|
|
4059
|
+
EOT
|
|
4060
|
+
)
|
|
4061
|
+
|
|
4023
4062
|
singlePattern('_seqno')
|
|
4024
4063
|
descr('The index of the item based on the declaration order')
|
|
4025
4064
|
|
|
4026
4065
|
singlePattern('_sickleave')
|
|
4027
4066
|
descr(<<'EOT'
|
|
4028
4067
|
The number of sick leave units within the reported time period. The unit can
|
|
4029
|
-
be adjusted with [[loadunit
|
|
4068
|
+
be adjusted with [[loadunit]].
|
|
4030
4069
|
EOT
|
|
4031
4070
|
)
|
|
4032
4071
|
|
|
4033
4072
|
singlePattern('_specialleave')
|
|
4034
4073
|
descr(<<'EOT'
|
|
4035
4074
|
The number of special leave units within the reported time period. The unit
|
|
4036
|
-
can be adjusted with [[loadunit
|
|
4075
|
+
can be adjusted with [[loadunit]].
|
|
4037
4076
|
EOT
|
|
4038
4077
|
)
|
|
4039
4078
|
|
|
@@ -4067,7 +4106,7 @@ EOT
|
|
|
4067
4106
|
singlePattern('_unpaidleave')
|
|
4068
4107
|
descr(<<'EOT'
|
|
4069
4108
|
The number of unpaid leave units within the reported time period. The unit
|
|
4070
|
-
can be adjusted with [[loadunit
|
|
4109
|
+
can be adjusted with [[loadunit]].
|
|
4071
4110
|
EOT
|
|
4072
4111
|
)
|
|
4073
4112
|
|
|
@@ -4100,6 +4139,22 @@ EOT
|
|
|
4100
4139
|
)
|
|
4101
4140
|
example('AccountReport')
|
|
4102
4141
|
|
|
4142
|
+
pattern(%w( _auxdir $STRING ), lambda {
|
|
4143
|
+
auxdir = @val[1]
|
|
4144
|
+
# Ensure that the directory always ends with a '/'.
|
|
4145
|
+
auxdir += '/' unless auxdir[-1] == ?/
|
|
4146
|
+
@property.set('auxdir', auxdir)
|
|
4147
|
+
})
|
|
4148
|
+
level(:beta)
|
|
4149
|
+
doc('auxdir', <<'EOT'
|
|
4150
|
+
Specifies an alternative directory for the auxiliary report files such as CSS,
|
|
4151
|
+
JavaScript and icon files. If this attribute is not set, the directoy will be
|
|
4152
|
+
generated automatically. If an alternative is provided, the user has to ensure
|
|
4153
|
+
that the directory exists and is filled with the proper data. The specified
|
|
4154
|
+
path and be absolute or relative to the generated report file.
|
|
4155
|
+
EOT
|
|
4156
|
+
)
|
|
4157
|
+
|
|
4103
4158
|
pattern(%w( !balance ), lambda {
|
|
4104
4159
|
@property.set('costaccount', @val[0][0])
|
|
4105
4160
|
@property.set('revenueaccount', @val[0][1])
|
|
@@ -4254,6 +4309,16 @@ EOT
|
|
|
4254
4309
|
also(%w( epilog footer header ))
|
|
4255
4310
|
|
|
4256
4311
|
pattern(%w( !purge ))
|
|
4312
|
+
|
|
4313
|
+
pattern(%w( _rawhtmlhead $STRING ), lambda {
|
|
4314
|
+
@property.set('rawHtmlHead', @val[1])
|
|
4315
|
+
})
|
|
4316
|
+
doc('rawhtmlhead', <<'EOT'
|
|
4317
|
+
Define a HTML fragment that will be inserted at the end of the HTML head
|
|
4318
|
+
section.
|
|
4319
|
+
EOT
|
|
4320
|
+
)
|
|
4321
|
+
|
|
4257
4322
|
pattern(%w( !reports ))
|
|
4258
4323
|
|
|
4259
4324
|
pattern(%w( _right $STRING ), lambda {
|
|
@@ -5315,8 +5380,9 @@ EOT
|
|
|
5315
5380
|
newReport(@val[1], @val[2], :statusSheet, @sourceFileInfo[0])
|
|
5316
5381
|
@property.set('formats', [ :tjp ])
|
|
5317
5382
|
|
|
5318
|
-
unless @project
|
|
5319
|
-
|
|
5383
|
+
unless (@project['trackingScenarioIdx'])
|
|
5384
|
+
error('ss_no_tracking_scenario',
|
|
5385
|
+
'You must have a tracking scenario defined to use status sheets.')
|
|
5320
5386
|
end
|
|
5321
5387
|
# Show all tasks, sorted by id-up.
|
|
5322
5388
|
@property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
|
|
@@ -5627,8 +5693,8 @@ EOT
|
|
|
5627
5693
|
@property.set('sortResources', [ [ 'seqno', true, -1 ] ])
|
|
5628
5694
|
})
|
|
5629
5695
|
arg(2, 'file name', <<'EOT'
|
|
5630
|
-
The name of the tagfile to generate.
|
|
5631
|
-
|
|
5696
|
+
The name of the tagfile to generate. Use ''''tags'''' if you want vim and
|
|
5697
|
+
other tools to find it automatically.
|
|
5632
5698
|
EOT
|
|
5633
5699
|
)
|
|
5634
5700
|
end
|
|
@@ -6437,6 +6503,10 @@ higher priority. This can result in situations where high priority tasks do
|
|
|
6437
6503
|
not get their resources even though the parallel competing tasks have a much
|
|
6438
6504
|
lower priority.
|
|
6439
6505
|
|
|
6506
|
+
ALAP tasks may not have [[booking.task|bookings]] since the first booked slot
|
|
6507
|
+
determines the start date of the task and prevents it from being scheduled
|
|
6508
|
+
from end to start.
|
|
6509
|
+
|
|
6440
6510
|
As a general rule, try to avoid ALAP tasks whenever possible. Have a close
|
|
6441
6511
|
eye on tasks that have been switched implicitly to ALAP mode because the
|
|
6442
6512
|
end attribute comes after the start attribute.
|
|
@@ -6971,9 +7041,11 @@ EOT
|
|
|
6971
7041
|
newReport(@val[1], @val[2], :timeSheet, @sourceFileInfo[0])
|
|
6972
7042
|
@property.set('formats', [ :tjp ])
|
|
6973
7043
|
|
|
6974
|
-
unless @project
|
|
6975
|
-
|
|
7044
|
+
unless (scenarioIdx = @project['trackingScenarioIdx'])
|
|
7045
|
+
error('ts_no_tracking_scenario',
|
|
7046
|
+
'You must have a tracking scenario defined to use time sheets.')
|
|
6976
7047
|
end
|
|
7048
|
+
@property.set('scenarios', [ scenarioIdx ])
|
|
6977
7049
|
# Show all tasks, sorted by seqno-up.
|
|
6978
7050
|
@property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
|
|
6979
7051
|
@property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
|
|
@@ -87,7 +87,7 @@ class TaskJuggler
|
|
|
87
87
|
end
|
|
88
88
|
@children += arg
|
|
89
89
|
elsif arg.nil?
|
|
90
|
-
#
|
|
90
|
+
# Do nothing. Insertions of nil are simply ignored.
|
|
91
91
|
else
|
|
92
92
|
raise "Elements must be of type XMLElement not #{arg.class}"
|
|
93
93
|
end
|
|
@@ -215,6 +215,7 @@ class TaskJuggler
|
|
|
215
215
|
|
|
216
216
|
def initialize(blob = '')
|
|
217
217
|
super(nil, {})
|
|
218
|
+
raise ArgumentError, "blob may not be nil" if blob.nil?
|
|
218
219
|
@blob = blob
|
|
219
220
|
end
|
|
220
221
|
|
data/lib/taskjuggler/apps/Tj3.rb
CHANGED
|
@@ -35,6 +35,10 @@ class TaskJuggler
|
|
|
35
35
|
@checkSyntax = false
|
|
36
36
|
# Don't generate reports when previous errors have been found.
|
|
37
37
|
@forceReports = false
|
|
38
|
+
# List of requested report IDs.
|
|
39
|
+
@reportIDs = []
|
|
40
|
+
# List of requested report IDs (as regular expressions).
|
|
41
|
+
@reportRegExpIDs = []
|
|
38
42
|
# Don't generate trace reports by default
|
|
39
43
|
@generateTraces = false
|
|
40
44
|
# Should a booking file be generated?
|
|
@@ -72,10 +76,6 @@ EOT
|
|
|
72
76
|
format('Restrict debug output to a list of modules')) do |arg|
|
|
73
77
|
TaskJuggler::Log.segments = arg
|
|
74
78
|
end
|
|
75
|
-
@opts.on('-f', '--force-reports',
|
|
76
|
-
format('Generate reports despite scheduling errors')) do
|
|
77
|
-
@forceReports = true
|
|
78
|
-
end
|
|
79
79
|
@opts.on('--freeze',
|
|
80
80
|
format('Generate or update the booking file for ' +
|
|
81
81
|
'the project. The file will have the same ' +
|
|
@@ -120,6 +120,21 @@ EOT
|
|
|
120
120
|
'reports.')) do
|
|
121
121
|
@noReports = true
|
|
122
122
|
end
|
|
123
|
+
@opts.on('--report <report ID>', String,
|
|
124
|
+
format('Only generate the report with the specified ID. ' +
|
|
125
|
+
'This option can be used multiple times.')) do |arg|
|
|
126
|
+
@reportIDs << arg
|
|
127
|
+
end
|
|
128
|
+
@opts.on('--reports <report ID RegExp>', String,
|
|
129
|
+
format('Only generate the reports that have IDs that match ' +
|
|
130
|
+
'the specified regular expression. This option can ' +
|
|
131
|
+
'be used multiple times.')) do |arg|
|
|
132
|
+
@reportRegExpIDs << arg
|
|
133
|
+
end
|
|
134
|
+
@opts.on('-f', '--force-reports',
|
|
135
|
+
format('Generate reports despite scheduling errors')) do
|
|
136
|
+
@forceReports = true
|
|
137
|
+
end
|
|
123
138
|
@opts.on('--add-trace',
|
|
124
139
|
format('Append a current data set to all trace reports.')) do
|
|
125
140
|
@generateTraces = true
|
|
@@ -181,7 +196,16 @@ EOT
|
|
|
181
196
|
|
|
182
197
|
return 0 if @noReports
|
|
183
198
|
|
|
184
|
-
|
|
199
|
+
if @reportIDs.empty? && @reportRegExpIDs.empty?
|
|
200
|
+
return 1 if !tj.generateReports(@outputDir) || tj.errors > 0
|
|
201
|
+
else
|
|
202
|
+
@reportIDs.each do |id|
|
|
203
|
+
return 1 if !tj.generateReport(id, false)
|
|
204
|
+
end
|
|
205
|
+
@reportRegExpIDs.each do |id|
|
|
206
|
+
return 1 if !tj.generateReport(id, true)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
185
209
|
|
|
186
210
|
0
|
|
187
211
|
end
|
|
@@ -29,7 +29,7 @@ class TaskJuggler
|
|
|
29
29
|
MessageHandlerInstance.instance.trapSetup = false
|
|
30
30
|
res
|
|
31
31
|
rescue => e
|
|
32
|
-
# Any exception here is a
|
|
32
|
+
# Any exception here is a fatal error. We try hard to terminate the DRb
|
|
33
33
|
# thread and then exit the program.
|
|
34
34
|
begin
|
|
35
35
|
fatal('pi_crash_trap', "#{e}\n#{e.backtrace.join("\n")}\n\n" +
|
|
@@ -340,8 +340,11 @@ class TaskJuggler
|
|
|
340
340
|
# If we have not received a ping from the ProjectBroker for 2
|
|
341
341
|
# minutes, we assume it has died and terminate as well.
|
|
342
342
|
if TjTime.new - @lastPing > 180
|
|
343
|
-
error(
|
|
344
|
-
|
|
343
|
+
# Since the abort via error() is not thread safe, we issue a
|
|
344
|
+
# warning and abort manually.
|
|
345
|
+
warning('daemon_heartbeat_lost',
|
|
346
|
+
'Heartbeat from daemon lost. Terminating.')
|
|
347
|
+
exit 1
|
|
345
348
|
end
|
|
346
349
|
sleep 1
|
|
347
350
|
end
|