taskjuggler 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|