diff -Nru tj3-3.6.0/data/css/tjreport.css tj3-3.7.1/data/css/tjreport.css --- tj3-3.6.0/data/css/tjreport.css 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/data/css/tjreport.css 2020-03-14 16:26:45.000000000 +0000 @@ -433,6 +433,10 @@ background-color:#EE0000; position:absolute; } +.markdateline { + background-color:#000000; + position:absolute; +} .white { background-color:#FFFFFF; position:absolute; diff -Nru tj3-3.6.0/debian/changelog tj3-3.7.1/debian/changelog --- tj3-3.6.0/debian/changelog 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/changelog 2020-06-20 11:43:41.000000000 +0000 @@ -1,3 +1,17 @@ +tj3 (3.7.1-1) unstable; urgency=medium + + [ Vincent Bernat ] + * New upstream release. + + [ Alexandre Rossi ] + * drop patches included upstream, unfuzz patches + * raise dh-compat to 13 + * raise standards version compliance to 4.5.0 and add Rules-Requires-Root + * add basic autopkgtest + * do no distribute dev scripts in binary package + + -- Vincent Bernat Sat, 20 Jun 2020 13:43:41 +0200 + tj3 (3.6.0-6) unstable; urgency=medium * d/control: update Vcs-* fields. diff -Nru tj3-3.6.0/debian/compat tj3-3.7.1/debian/compat --- tj3-3.6.0/debian/compat 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -9 diff -Nru tj3-3.6.0/debian/control tj3-3.7.1/debian/control --- tj3-3.6.0/debian/control 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/control 2020-06-20 11:43:41.000000000 +0000 @@ -2,7 +2,7 @@ Section: utils Priority: optional Maintainer: Vincent Bernat -Build-Depends: debhelper (>= 9~), +Build-Depends: debhelper-compat (=13), gem2deb, rake, ruby-mail (>= 2.4.3), @@ -10,7 +10,8 @@ ruby-term-ansicolor (>= 1.0.7), localehelper, help2man -Standards-Version: 3.9.8 +Standards-Version: 4.5.0 +Rules-Requires-Root: no Vcs-Browser: https://salsa.debian.org/debian/tj3 Vcs-Git: https://salsa.debian.org/debian/tj3.git Homepage: http://www.taskjuggler.org diff -Nru tj3-3.6.0/debian/patches/0010-tests-normalize-CRLF-when-checking-MIME-attachments.patch tj3-3.7.1/debian/patches/0010-tests-normalize-CRLF-when-checking-MIME-attachments.patch --- tj3-3.6.0/debian/patches/0010-tests-normalize-CRLF-when-checking-MIME-attachments.patch 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/0010-tests-normalize-CRLF-when-checking-MIME-attachments.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -From: Vincent Bernat -Date: Sun, 27 Jan 2019 16:33:08 +0100 -Subject: tests: normalize CRLF when checking MIME attachments - ---- - spec/StatusSheets_spec.rb | 4 ++-- - spec/TimeSheets_spec.rb | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/spec/StatusSheets_spec.rb b/spec/StatusSheets_spec.rb -index 1da147e..9d7be05 100644 ---- a/spec/StatusSheets_spec.rb -+++ b/spec/StatusSheets_spec.rb -@@ -229,8 +229,8 @@ EOT - - it 'should have matching status sheets in body and attachment' do - @sss_mails.each do |mail| -- bodySheet = extractStatusSheet(mail.parts[0].decoded) -- attachedSheet = extractStatusSheet(mail.part[1].decoded) -+ bodySheet = extractStatusSheet(mail.parts[0].decoded).gsub /\r\n/, "\n" -+ attachedSheet = extractStatusSheet(mail.part[1].decoded).gsub /\r\n/, "\n" - bodySheet.should == attachedSheet - end - end -diff --git a/spec/TimeSheets_spec.rb b/spec/TimeSheets_spec.rb -index 9360130..f649ae0 100644 ---- a/spec/TimeSheets_spec.rb -+++ b/spec/TimeSheets_spec.rb -@@ -215,8 +215,8 @@ EOT - - it 'should have matching timesheets in body and attachment' do - @tss_mails.each do |mail| -- bodySheet = extractTimeSheet(mail.parts[0].decoded) -- attachedSheet = extractTimeSheet(mail.part[1].decoded) -+ bodySheet = extractTimeSheet(mail.parts[0].decoded).gsub /\r\n/, "\n" -+ attachedSheet = extractTimeSheet(mail.part[1].decoded).gsub /\r\n/, "\n" - bodySheet.should == attachedSheet - end - end diff -Nru tj3-3.6.0/debian/patches/224.patch tj3-3.7.1/debian/patches/224.patch --- tj3-3.6.0/debian/patches/224.patch 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/224.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,701 +0,0 @@ -From 431d4957126fdbaefb85e50164398dff79e2b57a Mon Sep 17 00:00:00 2001 -From: Anders Blomdell -Date: Mon, 26 Feb 2018 18:59:37 +0100 -Subject: [PATCH] Coerce Fixnum/Bignum to Integer - ---- - lib/taskjuggler/Allocation.rb | 2 +- - lib/taskjuggler/AttributeBase.rb | 4 +-- - lib/taskjuggler/Attributes.rb | 4 +-- - lib/taskjuggler/Interval.rb | 22 ++++++++-------- - lib/taskjuggler/LogicalFunction.rb | 2 +- - lib/taskjuggler/LogicalOperation.rb | 6 ++--- - lib/taskjuggler/MessageHandler.rb | 2 +- - lib/taskjuggler/PTNProxy.rb | 2 +- - lib/taskjuggler/Project.rb | 40 +++++++++++++++--------------- - lib/taskjuggler/PropertySet.rb | 2 +- - lib/taskjuggler/PropertyTreeNode.rb | 2 +- - lib/taskjuggler/Query.rb | 6 ++--- - lib/taskjuggler/RealFormat.rb | 2 +- - lib/taskjuggler/ResourceScenario.rb | 12 ++++----- - lib/taskjuggler/RichText/Snip.rb | 2 +- - lib/taskjuggler/ShiftAssignments.rb | 2 +- - lib/taskjuggler/TimeSheets.rb | 4 +-- - lib/taskjuggler/UTF8String.rb | 4 +-- - lib/taskjuggler/WorkingHours.rb | 6 ++--- - lib/taskjuggler/deep_copy.rb | 2 +- - lib/taskjuggler/reports/CSVFile.rb | 6 ++--- - lib/taskjuggler/reports/ChartPlotter.rb | 2 +- - lib/taskjuggler/reports/ReportTableCell.rb | 2 +- - lib/taskjuggler/reports/TableReport.rb | 2 +- - 24 files changed, 69 insertions(+), 71 deletions(-) - -Index: tj3/lib/taskjuggler/Allocation.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/Allocation.rb -+++ tj3/lib/taskjuggler/Allocation.rb -@@ -50,7 +50,7 @@ class TaskJuggler - end - - # Set the selection mode identified by name specified in _str_. For -- # efficiency reasons, we turn the name into a Fixnum value. -+ # efficiency reasons, we turn the name into an Integer value. - def setSelectionMode(str) - modes = %w( order minallocated minloaded maxloaded random ) - @selectionMode = modes.index(str) -Index: tj3/lib/taskjuggler/AttributeBase.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/AttributeBase.rb -+++ tj3/lib/taskjuggler/AttributeBase.rb -@@ -136,7 +136,7 @@ class TaskJuggler - - def to_num - v = get -- if v.is_a?(Fixnum) || v.is_a?(Bignum) || v.is_a?(Float) -+ if v.is_a?(Integer) || v.is_a?(Float) - v - else - nil -@@ -145,7 +145,7 @@ class TaskJuggler - - def to_sort - v = get -- if v.is_a?(Fixnum) || v.is_a?(Bignum) || v.is_a?(Float) -+ if v.is_a?(Integer) || v.is_a?(Float) - v - elsif v.respond_to?('to_s') - v.to_s -Index: tj3/lib/taskjuggler/Attributes.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/Attributes.rb -+++ tj3/lib/taskjuggler/Attributes.rb -@@ -264,12 +264,12 @@ class TaskJuggler - - end - -- class FixnumAttribute < AttributeBase -+ class IntegerAttribute < AttributeBase - def initialize(property, type, container) - super - end - -- def FixnumAttribute::tjpId -+ def IntegerAttribute::tjpId - 'integer' - end - end -Index: tj3/lib/taskjuggler/Interval.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/Interval.rb -+++ tj3/lib/taskjuggler/Interval.rb -@@ -166,7 +166,7 @@ class TaskJuggler - # - # sbStart must be a TjTime of the scoreboard start - # slotDuration must be the duration of the scoreboard slots in seconds -- # a and b should be TjTime or Fixnum objects that describe the start and -+ # a and b should be TjTime or Integer objects that describe the start and - # end time or index of the interval. - # - # TimeInterval.new(iv) -@@ -191,7 +191,7 @@ class TaskJuggler - # If the third argument is a date we convert it to a scoreboard index. - args[2] = dateToIndex(args[2]) if args[2].is_a?(TjTime) - -- if args[2].is_a?(Fixnum) || args[2].is_a?(Bignum) -+ if args[2].is_a?(Integer) - super(args[2], args[2]) - else - raise ArgumentError, "Illegal argument 3: #{args[0].class}" -@@ -204,11 +204,11 @@ class TaskJuggler - args[2] = dateToIndex(args[2]) if args[2].is_a?(TjTime) - args[3] = dateToIndex(args[3]) if args[3].is_a?(TjTime) - -- if !(args[2].is_a?(Fixnum) || args[2].is_a?(Bignum)) -+ if !(args[2].is_a?(Integer)) - raise ArgumentError, "Interval start must be an index or TjTime, " + - "not a #{args[2].class}" - end -- if !(args[3].is_a?(Fixnum) || args[3].is_a?(Bignum)) -+ if !(args[3].is_a?(Integer)) - raise ArgumentError, "Interval end must be an index or TjTime, " + - "not a #{args[3].class}" - end -@@ -221,19 +221,18 @@ class TaskJuggler - raise ArgumentError, "sbStart must be a TjTime object, not a" + - "#{@sbStart.class}" - end -- unless @slotDuration.is_a?(Fixnum) -- raise ArgumentError, "slotDuration must be a Fixnum, not a " + -+ unless @slotDuration.is_a?(Integer) -+ raise ArgumentError, "slotDuration must be an Integer, not a " + - "#{@slotDuration.class}" - end - - end - -- # Assign the start of the interval. +arg+ can be a Fixnum, Bignum or -+ # Assign the start of the interval. +arg+ can be an Integer or - # TjTime object. - def start=(arg) - case arg -- when Fixnum -- when Bignum -+ when Integer - @start = arg - when TjTime - @start = dateToIndex(arg) -@@ -242,12 +241,11 @@ class TaskJuggler - end - end - -- # Assign the start of the interval. +arg+ can be a Fixnum, Bignum or -+ # Assign the start of the interval. +arg+ can be an Integer or - # TjTime object. - def end=(arg) - case arg -- when Fixnum -- when Bignum -+ when Integer - @end = arg - when TjTime - @end = dateToIndex(arg) -Index: tj3/lib/taskjuggler/LogicalFunction.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/LogicalFunction.rb -+++ tj3/lib/taskjuggler/LogicalFunction.rb -@@ -139,7 +139,7 @@ class TaskJuggler - # 2nd arg must be a scenario index. - return false if (scenarioIdx = project.scenarioIdx(args[1])).nil? - # 3rd arg must be an integer number. -- return false unless args[2].is_a?(Fixnum) -+ return false unless args[2].is_a?(Integer) - - property.isDependencyOf(scenarioIdx, task, args[2]) - end -Index: tj3/lib/taskjuggler/LogicalOperation.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/LogicalOperation.rb -+++ tj3/lib/taskjuggler/LogicalOperation.rb -@@ -64,7 +64,7 @@ class TaskJuggler - coerceTime(o, expr) - end - return res -- elsif opnd1.is_a?(Fixnum) || opnd1.is_a?(Float) || opnd1.is_a?(Bignum) -+ elsif opnd1.is_a?(Integer) || opnd1.is_a?(Float) - return evalBinaryOperation(opnd1, operator, opnd2) do |o| - coerceNumber(o, expr) - end -@@ -145,14 +145,14 @@ class TaskJuggler - # An empty String means false, else true. - return !val.empty? if val.is_a?(String) - # In TJP logic 'non 0' means false. -- return val != 0 if val.is_a?(Fixnum) || val.is_a?(Bignum) -+ return val != 0 if val.is_a?(Integer) - - expr.error("Operand #{val} can't be evaluated to true or false.") - end - - # Force the _val_ into a number. In case this fails, an exception is raised. - def coerceNumber(val, expr) -- unless val.is_a?(Fixnum) || val.is_a?(Float) || val.is_a?(Bignum) -+ unless val.is_a?(Integer) || val.is_a?(Float) - expr.error("Operand #{val} of type #{val.class} must be a number.") - end - val -Index: tj3/lib/taskjuggler/MessageHandler.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/MessageHandler.rb -+++ tj3/lib/taskjuggler/MessageHandler.rb -@@ -230,7 +230,7 @@ class TaskJuggler - private - - def checkLevel(level) -- if level.is_a?(Fixnum) -+ if level.is_a?(Integer) - if level < 0 || level > 5 - raise ArgumentError, "Unsupported level #{level}" - end -Index: tj3/lib/taskjuggler/PTNProxy.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/PTNProxy.rb -+++ tj3/lib/taskjuggler/PTNProxy.rb -@@ -104,7 +104,7 @@ class TaskJuggler - end - - # Return the 'index' attributes of this property, prefixed by the 'index' -- # attributes of all its parents. The result is an Array of Fixnums. -+ # attributes of all its parents. The result is an Array of Integers. - def getIndicies - idcs = [] - p = self -Index: tj3/lib/taskjuggler/Project.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/Project.rb -+++ tj3/lib/taskjuggler/Project.rb -@@ -126,7 +126,7 @@ class TaskJuggler - false, false, false, true ], - [ 'projection', 'Projection Mode', BooleanAttribute, - true, false, false, false ], -- [ 'seqno', 'No', FixnumAttribute, -+ [ 'seqno', 'No', IntegerAttribute, - false, false, false, nil ], - ] - attrs.each { |a| @scenarios.addAttributeType(AttributeDefinition.new(*a)) } -@@ -139,7 +139,7 @@ class TaskJuggler - false, false, false, "" ], - [ 'id', 'ID', StringAttribute, - false, false, false, nil ], -- [ 'index', 'Index', FixnumAttribute, -+ [ 'index', 'Index', IntegerAttribute, - false, false, false, -1 ], - [ 'leaves', 'Leaves', LeaveListAttribute, - true, true, true, LeaveList.new ], -@@ -147,7 +147,7 @@ class TaskJuggler - false, false, false, nil ], - [ 'replace', 'Replace', BooleanAttribute, - true, false, true, false ], -- [ 'seqno', 'No', FixnumAttribute, -+ [ 'seqno', 'No', IntegerAttribute, - false, false, false, nil ], - [ 'timezone', 'Time Zone', StringAttribute, - true, true, true, TjTime.timeZone ], -@@ -170,13 +170,13 @@ class TaskJuggler - false, false, true, [] ], - [ 'id', 'ID', StringAttribute, - false, false, false, nil ], -- [ 'index', 'Index', FixnumAttribute, -+ [ 'index', 'Index', IntegerAttribute, - false, false, false, -1 ], - [ 'flags', 'Flags', FlagListAttribute, - true, false, true, [] ], - [ 'name', 'Name', StringAttribute, - false, false, false, nil ], -- [ 'seqno', 'No', FixnumAttribute, -+ [ 'seqno', 'No', IntegerAttribute, - false, false, false, nil ], - [ 'tree', 'Tree Index', StringAttribute, - false, false, false, "" ] -@@ -201,7 +201,7 @@ class TaskJuggler - false, false, true, [] ], - [ 'efficiency','Efficiency', FloatAttribute, - true, false, true, 1.0 ], -- [ 'effort', 'Total Effort', FixnumAttribute, -+ [ 'effort', 'Total Effort', IntegerAttribute, - false, false, true, 0 ], - [ 'email', 'Email', StringAttribute, - false, false, false, nil ], -@@ -209,7 +209,7 @@ class TaskJuggler - false, false, false, [] ], - [ 'flags', 'Flags', FlagListAttribute, - true, false, true, [] ], -- [ 'index', 'Index', FixnumAttribute, -+ [ 'index', 'Index', IntegerAttribute, - false, false, false, -1 ], - [ 'leaveallowances', 'Leave Allowances', LeaveAllowanceListAttribute, - true, false, true, LeaveAllowanceList.new ], -@@ -223,7 +223,7 @@ class TaskJuggler - true, true, true, 0.0 ], - [ 'reports', 'Reports', ResourceListAttribute, - false, false, true, [] ], -- [ 'seqno', 'No', FixnumAttribute, -+ [ 'seqno', 'No', IntegerAttribute, - false, false, false, nil ], - [ 'shifts', 'Shifts', ShiftAssignmentsAttribute, - true, false, true, nil ], -@@ -264,9 +264,9 @@ class TaskJuggler - false, false, true, 0 ], - [ 'effort', 'Effort', DurationAttribute, - false, false, true, 0 ], -- [ 'effortdone', 'Completed Effort', FixnumAttribute, -+ [ 'effortdone', 'Completed Effort', IntegerAttribute, - false, false, true, nil ], -- [ 'effortleft', 'Remaining Effort', FixnumAttribute, -+ [ 'effortleft', 'Remaining Effort', IntegerAttribute, - false, false, true, nil ], - [ 'end', 'End', DateAttribute, - false, false, true, nil ], -@@ -284,7 +284,7 @@ class TaskJuggler - false, false, true, nil ], - [ 'id', 'ID', StringAttribute, - false, false, false, nil ], -- [ 'index', 'Index', FixnumAttribute, -+ [ 'index', 'Index', IntegerAttribute, - false, false, false, -1 ], - [ 'length', 'Length', DurationAttribute, - false, false, true, 0 ], -@@ -308,7 +308,7 @@ class TaskJuggler - false, false, true, 0.0 ], - [ 'precedes', 'Following tasks', DependencyListAttribute, - true, false, true, [] ], -- [ 'priority', 'Priority', FixnumAttribute, -+ [ 'priority', 'Priority', IntegerAttribute, - true, true, true, 500 ], - [ 'projectid', 'Project ID', SymbolAttribute, - true, true, true, nil ], -@@ -318,7 +318,7 @@ class TaskJuggler - true, false, true, false ], - [ 'projectionmode', 'Projection Mode', BooleanAttribute, - true, false, true, false ], -- [ 'seqno', 'No', FixnumAttribute, -+ [ 'seqno', 'No', IntegerAttribute, - false, false, false, nil ], - [ 'shifts', 'Shifts', ShiftAssignmentsAttribute, - true, false, true, nil ], -@@ -383,11 +383,11 @@ class TaskJuggler - true, false, false, nil ], - [ 'hideTask', 'Hide Task', LogicalExpressionAttribute, - true, false, false, nil ], -- [ 'height', 'Height', FixnumAttribute, -+ [ 'height', 'Height', IntegerAttribute, - false, false, false, 480 ], - [ 'id', 'ID', StringAttribute, - false, false, false, nil ], -- [ 'index', 'Index', FixnumAttribute, -+ [ 'index', 'Index', IntegerAttribute, - false, false, false, -1 ], - [ 'interactive', 'Interactive', BooleanAttribute, - false, false, false, false ], -@@ -429,7 +429,7 @@ class TaskJuggler - true, false, false, [ 0 ] ], - [ 'selfcontained', 'Selfcontained', BooleanAttribute, - true, false, false, false ], -- [ 'seqno', 'No', FixnumAttribute, -+ [ 'seqno', 'No', IntegerAttribute, - false, false, false, nil ], - [ 'shortTimeFormat', 'Short Time Format', StringAttribute, - true, true, false, nil ], -@@ -461,7 +461,7 @@ class TaskJuggler - false, false, false, "" ], - [ 'weekStartsMonday', 'Week Starts Monday', BooleanAttribute, - true, true, false, false ], -- [ 'width', 'Width', FixnumAttribute, -+ [ 'width', 'Width', IntegerAttribute, - true, false, false, 640 ] - ] - attrs.each { |a| @reports.addAttributeType(AttributeDefinition.new(*a)) } -@@ -560,7 +560,7 @@ class TaskJuggler - # - # Return the Scenario with the given _id_ or _index_. - def scenario(arg) -- if arg.is_a?(Fixnum) -+ if arg.is_a?(Integer) - @scenarios.each do |sc| - return sc if sc.sequenceNo - 1 == arg - end -@@ -874,7 +874,7 @@ class TaskJuggler - def isWorkingTime(*args) - # Normalize argument(s) to TimeInterval - if args.length == 1 -- if args[0].is_a?(Fixnum) || args[0].is_a?(Bignum) -+ if args[0].is_a?(Integer) - return @scoreboard[args[0]].nil? - elsif args[0].is_a?(TjTime) - return @scoreboard[dateToIdx(args[0])].nil? -@@ -969,7 +969,7 @@ class TaskJuggler - - def collectTimeOffIntervals(iv, minDuration) - @scoreboard.collectIntervals(iv, minDuration) do |val| -- val.is_a?(Fixnum) && (val & 0x3E) != 0 -+ val.is_a?(Integer) && (val & 0x3E) != 0 - end - end - -Index: tj3/lib/taskjuggler/PropertySet.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/PropertySet.rb -+++ tj3/lib/taskjuggler/PropertySet.rb -@@ -51,7 +51,7 @@ class TaskJuggler - [ - [ 'id', 'ID', StringAttribute, false, false, false, '' ], - [ 'name', 'Name', StringAttribute, false, false, false, '' ], -- [ 'seqno', 'Seq. No', FixnumAttribute, false, false, false, 0 ] -+ [ 'seqno', 'Seq. No', IntegerAttribute, false, false, false, 0 ] - ].each { |a| addAttributeType(AttributeDefinition.new(*a)) } - end - -Index: tj3/lib/taskjuggler/PropertyTreeNode.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/PropertyTreeNode.rb -+++ tj3/lib/taskjuggler/PropertyTreeNode.rb -@@ -331,7 +331,7 @@ class TaskJuggler - end - - # Return the 'index' attributes of this property, prefixed by the 'index' -- # attributes of all its parents. The result is an Array of Fixnums. -+ # attributes of all its parents. The result is an Array of Integers. - def getIndicies - idcs = [] - p = self -Index: tj3/lib/taskjuggler/Query.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/Query.rb -+++ tj3/lib/taskjuggler/Query.rb -@@ -81,7 +81,7 @@ class TaskJuggler - end - - def startIdx=(idx) -- if idx.is_a?(Fixnum) -+ if idx.is_a?(Integer) - @startIdx = idx - @start = @project.idxToDate(idx) - else -@@ -99,7 +99,7 @@ class TaskJuggler - end - - def endIdx=(idx) -- if idx.is_a?(Fixnum) -+ if idx.is_a?(Integer) - @endIdx = idx - @end = @project.idxToDate(idx) - else -@@ -239,7 +239,7 @@ class TaskJuggler - @attr ? @attr.to_s(self) : (@rti ? @rti.to_s : (@string || '')) - end - -- # Return the result of the Query as Fixnum or Float. The result may be -+ # Return the result of the Query as Integer or Float. The result may be - # nil. - def to_num - @attr ? @attr.to_num : @numerical -Index: tj3/lib/taskjuggler/RealFormat.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/RealFormat.rb -+++ tj3/lib/taskjuggler/RealFormat.rb -@@ -24,7 +24,7 @@ class TaskJuggler - # thousandsSeparator: Separator used after 3 integer digits. (String) - # fractionSeparator: Separator used between the inter part and the - # fractional part. (String) -- # fractionDigits: Number of fractional digits to show. (Fixnum) -+ # fractionDigits: Number of fractional digits to show. (Integer) - class RealFormat - - attr_reader :signPrefix, :signSuffix, :thousandsSeparator, -Index: tj3/lib/taskjuggler/ResourceScenario.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/ResourceScenario.rb -+++ tj3/lib/taskjuggler/ResourceScenario.rb -@@ -20,7 +20,7 @@ class TaskJuggler - def initialize(resource, scenarioIdx, attributes) - super - -- # Scoreboard may be nil, a Task, or a bit vector encoded as a Fixnum -+ # Scoreboard may be nil, a Task, or a bit vector encoded as an Integer - # nil: Value has not been determined yet. - # Task: A reference to a Task object - # Bit 0: Reserved -@@ -685,7 +685,7 @@ class TaskJuggler - initScoreboard if @scoreboard.nil? - - @scoreboard.collectIntervals(iv, minDuration) do |val| -- val.is_a?(Fixnum) && (val & 0x3E) != 0 -+ val.is_a?(Integer) && (val & 0x3E) != 0 - end - end - -@@ -723,7 +723,7 @@ class TaskJuggler - # leave. - def getLeaveSlots(startIdx, endIdx, type) - countSlots(startIdx, endIdx) do |val| -- val.is_a?(Fixnum) && (val & 0x3E) == (Leave::Types[type] << 2) -+ val.is_a?(Integer) && (val & 0x3E) == (Leave::Types[type] << 2) - end - end - -@@ -739,7 +739,7 @@ class TaskJuggler - def getTimeOffSlots(startIdx, endIdx) - countSlots(startIdx, endIdx) do |val| - # Bit 1 needs to be unset and the leave bits must not be 0. -- val.is_a?(Fixnum) && (val & 0x2) == 0 && (val & 0x3C) != 0 -+ val.is_a?(Integer) && (val & 0x2) == 0 && (val & 0x3C) != 0 - end - end - -@@ -900,7 +900,7 @@ class TaskJuggler - initScoreboard unless @scoreboard - - val = @scoreboard[sbIdx] -- return true unless val.is_a?(Fixnum) -+ return true unless val.is_a?(Integer) - - leave_type = (val >> 2) & 0xF - leave_type < Leave::Types[:unemployed] -Index: tj3/lib/taskjuggler/RichText/Snip.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/RichText/Snip.rb -+++ tj3/lib/taskjuggler/RichText/Snip.rb -@@ -27,7 +27,7 @@ class TaskJuggler - - # Create a RichTextSnip object. _document_ is a reference to the - # RichTextDocument. _fileName_ is the name of the structured text file -- # using RichText syntax. _sectionCounter_ is an 3 item Fixnum Array. These -+ # using RichText syntax. _sectionCounter_ is an 3 item Integer Array. These - # 3 numbers are used to store the section counters over multiple - # RichTextSnip objects. - def initialize(document, fileName, sectionCounter) -Index: tj3/lib/taskjuggler/ShiftAssignments.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/ShiftAssignments.rb -+++ tj3/lib/taskjuggler/ShiftAssignments.rb -@@ -79,7 +79,7 @@ class TaskJuggler - # To optimize memory usage and computation time the Scoreboard objects for - # similar ShiftAssignments are shared. - # -- # Scoreboard may be nil or a bit vector encoded as a Fixnum -+ # Scoreboard may be nil or a bit vector encoded as an Integer - # nil: Value has not been determined yet. - # Bit 0: 0: No assignment - # 1: Has assignement -Index: tj3/lib/taskjuggler/TimeSheets.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/TimeSheets.rb -+++ tj3/lib/taskjuggler/TimeSheets.rb -@@ -46,11 +46,11 @@ class TaskJuggler - @sourceFileInfo = nil - end - -- # Store the number of worked time slots. If the value is a Fixnum, it can -+ # Store the number of worked time slots. If the value is an Integer, it can - # be directly assigned. A Float is interpreted as percentage and must be - # in the rage of 0.0 to 1.0. - def work=(value) -- if value.is_a?(Fixnum) -+ if value.is_a?(Integer) - @work = value - else - # Must be percent value -Index: tj3/lib/taskjuggler/UTF8String.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/UTF8String.rb -+++ tj3/lib/taskjuggler/UTF8String.rb -@@ -18,7 +18,7 @@ require 'base64' - # This is an extension and modification of the standard String class. We do a - # lot of UTF-8 character processing in the parser. Ruby 1.8 does not have good - # enough UTF-8 support and Ruby 1.9 only handles UTF-8 characters as Strings. --# This is very inefficient compared to representing them as Fixnum objects. -+# This is very inefficient compared to representing them as Integer objects. - # Some of these hacks can be removed once we have switched to 1.9 support - # only. - class String -@@ -58,7 +58,7 @@ class String - alias old_double_left_angle << - - # Replacement for the existing << operator that also works for characters -- # above Fixnum 255 (UTF-8 characters). -+ # above Integer 255 (UTF-8 characters). - def << (obj) - if obj.is_a?(String) || (obj < 256) - # In this case we can use the built-in concat. -Index: tj3/lib/taskjuggler/WorkingHours.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/WorkingHours.rb -+++ tj3/lib/taskjuggler/WorkingHours.rb -@@ -17,7 +17,7 @@ require 'taskjuggler/Scoreboard' - class TaskJuggler - - # Class to store the working hours for each day of the week. The working hours -- # are stored as Arrays of Fixnum intervals for each day of the week. A day off -+ # are stored as Arrays of Integer intervals for each day of the week. A day off - # is modelled as empty Array for that week day. The start end end times of - # each working period are stored as seconds after midnight. - class WorkingHours -@@ -100,7 +100,7 @@ class TaskJuggler - - # Set the working hours for a given week day. +dayOfWeek+ must be 0 for - # Sunday, 1 for Monday and so on. +intervals+ must be an Array that -- # contains an Array with 2 Fixnums for each working period. Each value -+ # contains an Array with 2 Integers for each working period. Each value - # specifies the time of day as minutes after midnight. The first value is - # the start time of the interval, the second the end time. - def setWorkingHours(dayOfWeek, intervals) -@@ -133,7 +133,7 @@ class TaskJuggler - - # Return the working hour intervals for a given day of the week. - # +dayOfWeek+ must 0 for Sunday, 1 for Monday and so on. The result is an -- # Array that contains Arrays of 2 Fixnums. -+ # Array that contains Arrays of 2 Integers. - def getWorkingHours(dayOfWeek) - @days[dayOfWeek] - end -Index: tj3/lib/taskjuggler/deep_copy.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/deep_copy.rb -+++ tj3/lib/taskjuggler/deep_copy.rb -@@ -37,7 +37,7 @@ class Object - # We can't clone frozen objects. So just return a reference to them. - # Built-in classed can't be cloned either. The check below is probably - # cheaper than the frequent (hiddent) exceptions from those objects. -- return self if frozen? || nil? || is_a?(Fixnum) || is_a?(Float) || -+ return self if frozen? || nil? || is_a?(Integer) || is_a?(Float) || - is_a?(TrueClass) || is_a?(FalseClass) || is_a?(Symbol) - - # In case we have loops in our graph, we return references, not -Index: tj3/lib/taskjuggler/reports/CSVFile.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/reports/CSVFile.rb -+++ tj3/lib/taskjuggler/reports/CSVFile.rb -@@ -157,7 +157,7 @@ class TaskJuggler - end - when :fieldEnd - # We've completed processing a field. Add the field to the list of -- # fields. Convert Fixnums and Floats in native types. -+ # fields. Convert Integers and Floats in native types. - fields << unMarshal(field, quoted) - - if c == "\n" -@@ -198,7 +198,7 @@ class TaskJuggler - if str.nil? - nil - elsif /^[-+]?\d+$/ =~ str -- # field is a Fixnum -+ # field is an Integer - str.to_i - elsif /^[-+]?\d*\.?\d+([eE][-+]?\d+)?$/ =~ str - # field is a Float -@@ -216,7 +216,7 @@ class TaskJuggler - def marshal(field) - if field.nil? - '' -- elsif field.is_a?(Fixnum) || field.is_a?(Float) || field.is_a?(Bignum) -+ elsif field.is_a?(Integer) || field.is_a?(Float) - # Numbers don't have to be quoted. - field.to_s - else -Index: tj3/lib/taskjuggler/reports/ChartPlotter.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/reports/ChartPlotter.rb -+++ tj3/lib/taskjuggler/reports/ChartPlotter.rb -@@ -163,7 +163,7 @@ class TaskJuggler - - @yMinDate = cell if @yMinDate.nil? || cell < @yMinDate - @yMaxDate = cell if @yMaxDate.nil? || cell > @yMaxDate -- elsif cell.is_a?(Fixnum) || cell.is_a?(Float) -+ elsif cell.is_a?(Integer) || cell.is_a?(Float) - if @dataType && @dataType != :number - error("Column #{colIdx} contains non-number (#{cell}). " + - "The columns will be ignored.") -Index: tj3/lib/taskjuggler/reports/ReportTableCell.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/reports/ReportTableCell.rb -+++ tj3/lib/taskjuggler/reports/ReportTableCell.rb -@@ -60,7 +60,7 @@ class TaskJuggler - @alignment = :center - # Horizontal padding between frame and cell content - @padding = 3 -- # Whether or not to indent the cell. If not nil, it is a Fixnum -+ # Whether or not to indent the cell. If not nil, it is an Integer - # indicating the indentation level. - @indent = nil - # The basename of the icon file -Index: tj3/lib/taskjuggler/reports/TableReport.rb -=================================================================== ---- tj3.orig/lib/taskjuggler/reports/TableReport.rb -+++ tj3/lib/taskjuggler/reports/TableReport.rb -@@ -79,7 +79,7 @@ class TaskJuggler - @@propertiesByType = { - # Type Indent Align - DateAttribute => [ false, :left ], -- FixnumAttribute => [ false, :right ], -+ IntegerAttribute => [ false, :right ], - FloatAttribute => [ false, :right ], - ResourceListAttribute => [ false, :left ], - RichTextAttribute => [ false, :left ], diff -Nru tj3-3.6.0/debian/patches/clobber-clean.patch tj3-3.7.1/debian/patches/clobber-clean.patch --- tj3-3.6.0/debian/patches/clobber-clean.patch 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/clobber-clean.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -Subject: Clean the source tree using rake - Modify several rake tasks so that running 'rake clean' will remove any - intermediate files and running 'rake clobber' will remove any final products. -Forwarded: https://github.com/taskjuggler/TaskJuggler/pull/195 -Author: Christopher Hoskin -Last-Update: 2016-09-06 - -diff --git a/tasks/changelog.rake b/tasks/changelog.rake -index ec9a99f..4eadb56 100644 ---- a/tasks/changelog.rake -+++ b/tasks/changelog.rake -@@ -1,5 +1,7 @@ - require 'time' - -+CLOBBER.include "CHANGELOG" -+ - desc 'Generate the CHANGELOG file' - task :changelog do - -diff --git a/tasks/gem.rake b/tasks/gem.rake -index 7f6f07c..df730d5 100644 ---- a/tasks/gem.rake -+++ b/tasks/gem.rake -@@ -3,6 +3,8 @@ require 'find' - require 'rubygems' - require 'rubygems/package' - -+CLOBBER.include "pkg/" -+ - # Unfortunately Rake::GemPackageTest cannot deal with files that are generated - # by Rake targets. So we have to write our own packaging task. - desc 'Build the gem package' -diff --git a/tasks/kate.rake b/tasks/kate.rake -index ca3a0ed..d142269 100644 ---- a/tasks/kate.rake -+++ b/tasks/kate.rake -@@ -2,6 +2,8 @@ - - require 'taskjuggler/KateSyntax' - -+CLOBBER.include "data/kate-tjp.xml" -+ - desc 'Generate kate-tjp.xml Kate syntax file' - task :kate do - TaskJuggler::KateSyntax.new.generate('data/kate-tjp.xml') -diff --git a/tasks/manual.rake b/tasks/manual.rake -index 7bec4cc..e2947da 100644 ---- a/tasks/manual.rake -+++ b/tasks/manual.rake -@@ -2,6 +2,8 @@ - - require 'taskjuggler/apps/Tj3Man' - -+CLOBBER.include "manual/html/" -+ - desc 'Generate User Manual' - task :manual do - htmldir = 'manual/html' -diff --git a/tasks/test.rake b/tasks/test.rake -index f15d7ae..f521c7a 100644 ---- a/tasks/test.rake -+++ b/tasks/test.rake -@@ -2,6 +2,11 @@ $:.unshift File.join(File.dirname(__FILE__), '..', 'test') - - require 'rake/testtask' - -+CLEAN.include "test/TestSuite/Export-Reports/refs/Leave.tjp" -+CLEAN.include "test/TestSuite/Export-Reports/refs/ListAttributes.tjp" -+CLEAN.include "test/TestSuite/Export-Reports/refs/Macro-4.tjp" -+CLEAN.include "test/TestSuite/Export-Reports/refs/TraceReport.tjp" -+ - # TEST TASK - desc 'Run all unit tests in the test directory' - Rake::TestTask.new(:unittest) do |t| -diff --git a/tasks/vim.rake b/tasks/vim.rake -index 73afa49..ede600e 100644 ---- a/tasks/vim.rake -+++ b/tasks/vim.rake -@@ -2,6 +2,8 @@ - - require 'taskjuggler/VimSyntax' - -+CLOBBER.include "data/tjp.vim" -+ - desc 'Generate vim.tjp Vim syntax file' - task :vim do - TaskJuggler::VimSyntax.new.generate('data/tjp.vim') diff -Nru tj3-3.6.0/debian/patches/dont-require-git.patch tj3-3.7.1/debian/patches/dont-require-git.patch --- tj3-3.6.0/debian/patches/dont-require-git.patch 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/dont-require-git.patch 2020-06-20 11:43:41.000000000 +0000 @@ -1,10 +1,8 @@ Description: do not require git to find files -diff --git a/tasks/rdoc.rake b/tasks/rdoc.rake -index df673ed9ae3d..a6efbde51c3a 100644 ---- a/tasks/rdoc.rake -+++ b/tasks/rdoc.rake -@@ -7,7 +7,7 @@ end +--- tj3.git.orig/tasks/rdoc.rake 2020-06-19 14:45:45.390630150 +0200 ++++ tj3.git/tasks/rdoc.rake 2020-06-19 14:45:45.390630150 +0200 +@@ -7,7 +7,7 @@ # RDOC TASK Rake::RDocTask.new(:rdoc) do |t| t.rdoc_files = %w( README.rdoc COPYING CHANGELOG ) + @@ -13,13 +11,11 @@ t.title = "TaskJuggler API documentation" t.main = 'README.rdoc' t.rdoc_dir = 'doc' -diff --git a/taskjuggler.gemspec b/taskjuggler.gemspec -index b410e188752f..4963049149bc 100644 ---- a/taskjuggler.gemspec -+++ b/taskjuggler.gemspec -@@ -46,19 +46,19 @@ management. +--- tj3.git.orig/taskjuggler.gemspec 2020-06-19 14:45:45.390630150 +0200 ++++ tj3.git/taskjuggler.gemspec 2020-06-19 14:45:45.390630150 +0200 +@@ -46,19 +46,19 @@ EOT - + s.license = 'GPL-2.0' s.require_path = 'lib' - s.files = (`git ls-files -- lib`).split("\n") + - (`git ls-files -- data`).split("\n") + @@ -33,7 +29,7 @@ + (`find tasks -type f`).split("\n") + %w( .gemtest taskjuggler.gemspec Rakefile ) + # Generated files, not contained in Git repository. - %w( data/tjp.vim ) + Dir.glob('manual/html/**/*') + %w( data/tjp.vim ) + Dir.glob('manual/html/**/*') + Dir.glob('man/*.1') s.bindir = 'bin' - s.executables = (`git ls-files -- bin`).split("\n"). + s.executables = (`find bin -type f`).split("\n"). diff -Nru tj3-3.6.0/debian/patches/man-code.patch tj3-3.7.1/debian/patches/man-code.patch --- tj3-3.6.0/debian/patches/man-code.patch 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/man-code.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,258 +0,0 @@ -Subject: man pages: Code modifications - Make minimal modifications to the Tj3 apps and Tj3AppBase in order that when - the commands are called with --help the output is in the format help2man - expects. -Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=836810 -Forwarded: https://github.com/taskjuggler/TaskJuggler/pull/196/commits/6edf55f7289de494204c5dae7e3b9b95ece78b28 -Author: Christopher Hoskin -Last-Update: 2016-09-06 - -diff --git a/lib/taskjuggler/Tj3AppBase.rb b/lib/taskjuggler/Tj3AppBase.rb -index df99d93..a9d570b 100644 ---- a/lib/taskjuggler/Tj3AppBase.rb -+++ b/lib/taskjuggler/Tj3AppBase.rb -@@ -51,16 +51,15 @@ class TaskJuggler - @opts.summary_width = @optsSummaryWidth - @opts.summary_indent = ' ' * @optsSummaryIndent - -- @opts.banner = "#{AppConfig.softwareName} v#{AppConfig.version} - " + -- "#{AppConfig.packageInfo}\n\n" + -- "Copyright (c) #{AppConfig.copyright.join(', ')}\n" + -+ @opts.banner = "Copyright (c) #{AppConfig.copyright.join(', ')}\n" + - " by #{AppConfig.authors.join(', ')}\n\n" + - "#{AppConfig.license}\n" + - "For more info about #{AppConfig.softwareName} see " + - "#{AppConfig.contact}\n\n" + - "Usage: #{AppConfig.appName} [options] " + - "#{@mandatoryArgs}\n\n" -- @opts.separator "" -+ -+ @opts.separator "\nOptions:" - @opts.on('-c', '--config ', String, - format('Use the specified YAML configuration file')) do |arg| - @configFile = arg -@@ -91,8 +90,23 @@ EOT - quit - end - @opts.on_tail('--version', format('Show version info')) do -- puts "#{AppConfig.softwareName} v#{AppConfig.version} - " + -- "#{AppConfig.packageInfo}" -+# Display the software name and version in GNU format -+# as expected by help2man -+# https://www.gnu.org/prep/standards/standards.html#g_t_002d_002dversion -+ puts "#{AppConfig.appName} (#{AppConfig.softwareName}) #{AppConfig.version}\n" -+# To also display the copyright and license statements in GNU format -+# uncomment the following and remove the equivalent statements from -+# --help -+# + -+#<<'EOT' -+#Copyright (C) 2016 Chris Schlaeger -+#License GPLv2: GNU GPL version 2 -+#This is free software; you can redistribute it and/or modify it under -+#the terms of version 2 of the GNU General Public License as published by the -+#Free Software Foundation. -+# -+#For more info about TaskJuggler see http://www.taskjuggler.org -+#EOT - quit - end - -diff --git a/lib/taskjuggler/apps/Tj3.rb b/lib/taskjuggler/apps/Tj3.rb -index 464f0d2..c855fd3 100644 ---- a/lib/taskjuggler/apps/Tj3.rb -+++ b/lib/taskjuggler/apps/Tj3.rb -@@ -68,10 +68,12 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'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 -diff --git a/lib/taskjuggler/apps/Tj3Client.rb b/lib/taskjuggler/apps/Tj3Client.rb -index 7e85a37..b75ae38 100644 ---- a/lib/taskjuggler/apps/Tj3Client.rb -+++ b/lib/taskjuggler/apps/Tj3Client.rb -@@ -100,7 +100,7 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ prebanner = <<'EOT' - The TaskJuggler client is used to send commands and data to the TaskJuggler - daemon. The communication is done via TCP/IP. - -@@ -125,9 +125,10 @@ EOT - end - end - args = args.join(' ') -- @opts.banner += " #{cmd[:label] + ' ' + args + tail}" + -+ prebanner += " #{cmd[:label] + ' ' + args + tail}" + - "\n\n#{' ' * 10 + format(cmd[:descr], 10)}\n" - end -+ @opts.banner.prepend(prebanner) - @opts.on('-p', '--port ', Integer, - format('Use the specified TCP/IP port')) do |arg| - @port = arg -diff --git a/lib/taskjuggler/apps/Tj3Daemon.rb b/lib/taskjuggler/apps/Tj3Daemon.rb -index 53e972f..fece5e4 100644 ---- a/lib/taskjuggler/apps/Tj3Daemon.rb -+++ b/lib/taskjuggler/apps/Tj3Daemon.rb -@@ -42,11 +42,13 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - The TaskJuggler daemon can be used to quickly generate reports for a number - of scheduled projects that are resident in memory. Once the daemon has been - started tj3client can be used to control it. -+ - EOT -+ ) - @opts.on('-d', '--dont-daemonize', - format("Don't put program into daemon mode. Keep it " + - 'connected to the terminal and show debug output.')) do -diff --git a/lib/taskjuggler/apps/Tj3Man.rb b/lib/taskjuggler/apps/Tj3Man.rb -index 5a1c4f0..a1d8d40 100644 ---- a/lib/taskjuggler/apps/Tj3Man.rb -+++ b/lib/taskjuggler/apps/Tj3Man.rb -@@ -36,10 +36,12 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - This program can be used to generate the user manual in HTML format or to get - a textual help for individual keywords. -+ - EOT -+ ) - @opts.on('-d', '--dir ', String, - format('directory to put the manual')) do |dir| - @directory = dir -diff --git a/lib/taskjuggler/apps/Tj3SsReceiver.rb b/lib/taskjuggler/apps/Tj3SsReceiver.rb -index d7c20d9..6b8650b 100644 ---- a/lib/taskjuggler/apps/Tj3SsReceiver.rb -+++ b/lib/taskjuggler/apps/Tj3SsReceiver.rb -@@ -27,13 +27,15 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - This program can be used to receive filled-out status sheets via email. - It reads the emails from STDIN and extracts the status sheet from the - attached files. The status sheet is checked for correctness. Good status - sheets are filed away. The sender be informed by email that the status - sheets was accepted or rejected. -+ - EOT -+ ) - end - end - -diff --git a/lib/taskjuggler/apps/Tj3SsSender.rb b/lib/taskjuggler/apps/Tj3SsSender.rb -index 5adee07..331f855 100644 ---- a/lib/taskjuggler/apps/Tj3SsSender.rb -+++ b/lib/taskjuggler/apps/Tj3SsSender.rb -@@ -38,11 +38,13 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - This program can be used to out status sheets templates via email. It will - generate status sheet templates for managers of the project. The project data - will be accesses via tj3client from a running TaskJuggler server process. -+ - EOT -+ ) - @opts.on('-r', '--resource ', String, - format('Only generate template for given resource')) do |arg| - @resourceList << arg -diff --git a/lib/taskjuggler/apps/Tj3TsReceiver.rb b/lib/taskjuggler/apps/Tj3TsReceiver.rb -index 15526c1..9f2a5aa 100644 ---- a/lib/taskjuggler/apps/Tj3TsReceiver.rb -+++ b/lib/taskjuggler/apps/Tj3TsReceiver.rb -@@ -30,13 +30,15 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - This program can be used to receive filled-out time sheets via email. It - reads the emails from STDIN and extracts the time sheet from the attached - files. The time sheet is checked for correctness. Good time sheets are filed - away. The sender will be informed by email that the time sheets was accepted - or rejected. -+ - EOT -+ ) - end - end - -diff --git a/lib/taskjuggler/apps/Tj3TsSender.rb b/lib/taskjuggler/apps/Tj3TsSender.rb -index 004569c..3134c98 100644 ---- a/lib/taskjuggler/apps/Tj3TsSender.rb -+++ b/lib/taskjuggler/apps/Tj3TsSender.rb -@@ -37,11 +37,13 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - This program can be used to send out time sheets templates via email. It will - generate time sheet templates for all resources of the project. The project - data will be accesses via tj3client from a running TaskJuggler server process. -+ - EOT -+ ) - @opts.on('-r', '--resource ', String, - format('Only generate template for given resource')) do |arg| - @resourceList << arg -diff --git a/lib/taskjuggler/apps/Tj3TsSummary.rb b/lib/taskjuggler/apps/Tj3TsSummary.rb -index 05c67e3..aec982d 100644 ---- a/lib/taskjuggler/apps/Tj3TsSummary.rb -+++ b/lib/taskjuggler/apps/Tj3TsSummary.rb -@@ -36,12 +36,14 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - This program can be used to send out individual copies and a summary of all - accepted time sheets a list of email addresses. The directory structures for - templates and submitted time sheets must be present. The project data will be - accesses via tj3client from a running TaskJuggler server process. -+ - EOT -+ ) - @opts.on('-r', '--resource ', String, - format('Only generate summary for given resource')) do |arg| - @resourceList << arg -diff --git a/lib/taskjuggler/apps/Tj3WebD.rb b/lib/taskjuggler/apps/Tj3WebD.rb -index 77f00a0..8582ce6 100644 ---- a/lib/taskjuggler/apps/Tj3WebD.rb -+++ b/lib/taskjuggler/apps/Tj3WebD.rb -@@ -40,11 +40,13 @@ class TaskJuggler - - def processArguments(argv) - super do -- @opts.banner += <<'EOT' -+ @opts.banner.prepend(<<'EOT' - The TaskJuggler web server can be used to serve the HTTP reports of - TaskJuggler projects to be viewed by any HTML5 compliant web browser. It uses - the TaskJuggler daemon (tj3d) for data hosting and report generation. -+ - EOT -+ ) - @opts.on('-d', '--dont-daemonize', - format("Don't put program into daemon mode. Keep it " + - 'connected to the terminal and show debug output.')) do diff -Nru tj3-3.6.0/debian/patches/man-spelling.patch tj3-3.7.1/debian/patches/man-spelling.patch --- tj3-3.6.0/debian/patches/man-spelling.patch 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/man-spelling.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Description: Correct spelling mistake in lib/taskjuggler/apps/Tj3Man.rb -Forwarded: https://github.com/taskjuggler/TaskJuggler/pull/196/commits/a3589f61fd820603c464745402629f9fc8c4e7e2 -Author: Christopher Hoskin -Last-Update: 2016-09-06 -diff --git a/lib/taskjuggler/apps/Tj3Man.rb b/lib/taskjuggler/apps/Tj3Man.rb -index a1d8d40..861c21c 100644 ---- a/lib/taskjuggler/apps/Tj3Man.rb -+++ b/lib/taskjuggler/apps/Tj3Man.rb -@@ -48,7 +48,7 @@ EOT - end - @opts.on('--html', - format('Show the user manual in your local web browser. ' + -- 'By default, Firefox is used or the brower specified ' + -+ 'By default, Firefox is used or the browser specified ' + - 'with the $BROWSER environment variable.')) do - @showHtml = true - end diff -Nru tj3-3.6.0/debian/patches/series tj3-3.7.1/debian/patches/series --- tj3-3.6.0/debian/patches/series 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/patches/series 2020-06-20 11:43:41.000000000 +0000 @@ -1,10 +1,5 @@ -clobber-clean.patch -man-spelling.patch -man-code.patch rakefile.patch dont-require-git.patch data-search-dirs-debian.patch reproducible-build.patch manual-path.patch -224.patch -0010-tests-normalize-CRLF-when-checking-MIME-attachments.patch diff -Nru tj3-3.6.0/debian/rules tj3-3.7.1/debian/rules --- tj3-3.6.0/debian/rules 2019-01-27 15:25:12.000000000 +0000 +++ tj3-3.7.1/debian/rules 2020-06-20 11:43:41.000000000 +0000 @@ -9,6 +9,12 @@ rake vim rake help2man +override_dh_install: + dh_install + # do not distribute dev files + rm debian/tj3/usr/lib/ruby/vendor_ruby/updateheader.sh + rm debian/tj3/usr/lib/ruby/vendor_ruby/header.tmpl + override_dh_clean: rm -rf manual/html rake clobber diff -Nru tj3-3.6.0/debian/tests/control tj3-3.7.1/debian/tests/control --- tj3-3.6.0/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/debian/tests/control 2020-06-20 11:43:41.000000000 +0000 @@ -0,0 +1 @@ +Tests: smoke diff -Nru tj3-3.6.0/debian/tests/smoke tj3-3.7.1/debian/tests/smoke --- tj3-3.6.0/debian/tests/smoke 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/debian/tests/smoke 2020-06-20 11:43:41.000000000 +0000 @@ -0,0 +1,6 @@ +#!/bin/sh + +set -eu + + +tj3 examples/Tutorial/tutorial.tjp diff -Nru tj3-3.6.0/examples/ProjectTemplate/template.tjp tj3-3.7.1/examples/ProjectTemplate/template.tjp --- tj3-3.6.0/examples/ProjectTemplate/template.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/examples/ProjectTemplate/template.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -1,7 +1,7 @@ /* * This file contains a project skeleton. It is part of the * TaskJuggler project management tool. You can use this as a basis to - * start you own project file. + * start your own project file. */ project your_project_id "Your Project Title" 2011-11-11-0:00--0500 +4m { # Set the default time zone for the project. If not specified, UTC @@ -28,7 +28,7 @@ # You can define your own attributes for tasks and resources. This # is handy to capture additional information about the project that - # is not directly impacting the project schedule but you like to + # is not directly impacting the project schedule, but which you like to # keep in one place. #extend task { # reference spec "Link to Wiki page" @@ -59,7 +59,7 @@ # used to filter out subsets of them during reporting. flags important, hidden -# If you want to do budget planning for you project, you need to +# If you want to do budget planning for your project, you need to # define some accounts. account cost "Project Cost" { account dev "Development" @@ -67,10 +67,10 @@ } account rev "Customer Payments" -# The Profit&Loss analysis should be rev - cost accounts. +# The Profit & Loss analysis should be rev - cost accounts. balance cost rev -# Define you public holidays here. +# Define your public holidays here. vacation "New Year's Day" 2012-01-02 vacation "Birthday of Martin Luther King, Jr." 2012-01-16 vacation "Washington's Birthday" 2012-02-20 @@ -83,7 +83,7 @@ vacation "Christmas Day" 2012-12-25 # The daily default rate of all resources. This can be overridden for each -# resource. We specify this, so that we can do a good calculation of +# resource. We specify this so we can do a good calculation of # the costs of the project. rate 400.0 @@ -123,7 +123,7 @@ # Now the project has been specified completely. Stopping here would # result in a valid TaskJuggler file that could be processed and -# scheduled. But no reports would be generated to visualize the +# scheduled. Here reports will be generated to visualize the # results. navigator navbar { diff -Nru tj3-3.6.0/examples/Tutorial/tutorial.tjp tj3-3.7.1/examples/Tutorial/tutorial.tjp --- tj3-3.6.0/examples/Tutorial/tutorial.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/examples/Tutorial/tutorial.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -20,7 +20,7 @@ # used, but this will likely be outside of the project range, so it # can't be seen in the reports. now 2002-03-05-13:00 - # The currency for all money values is the Euro. + # The currency for all money values is the US Dollar. currency "USD" # We want to compare the baseline scenario to one with a slightly diff -Nru tj3-3.6.0/h2m/tj3client.h2m tj3-3.7.1/h2m/tj3client.h2m --- tj3-3.6.0/h2m/tj3client.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3client.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,43 @@ +[NAME] +tj3client \- send commands and data to the TaskJuggler daemon + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + +[FILES] + +.TP +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must contain: + +_global: + authKey: ******** + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + +[EXAMPLES] +.TP +Load a project: +tj3client add yourproject.tjp +.PP +.TP +List available reports for a project: +tj3client list-reports +.PP +.TP +Generate a report: +tj3client report +.PP +.TP +Terminate a running instance of the server: +tj3client terminate + + + +[SEE ALSO] +tj3d(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3d.h2m tj3-3.7.1/h2m/tj3d.h2m --- tj3-3.6.0/h2m/tj3d.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3d.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,33 @@ +[NAME] +tjd3 \- the TaskJuggler daemon + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + +[FILES] + +.TP +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must contain: + +_global: + authKey: ******** + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + +.TP +\fBtj3d.log\fR + +The tj3d log file, created in the working directory. Location can be overridden using the --logfile FILE option. + +[SECURITY] +The author advises: "the daemon has not received any kind of security review ... only use the daemon in a trusted environment with only trusted users!" + + +[SEE ALSO] +tj3client(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3.h2m tj3-3.7.1/h2m/tj3.h2m --- tj3-3.6.0/h2m/tj3.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,25 @@ +[NAME] +tj3 \- schedules tj3 projects and generates reports + +[ENVIRONMENT] + +.TP +\fBTASKJUGGLER_DATA_PATH\fR +Override the path to the TaskJuggler data folder. +The data folder contains the css, icons and scripts +for TaskJuggler reports. + +.TP +\fBTZ\fR +The POSIX Time Zone environment variable. + +Any environment variable may be used in a TaskJuggler file using the expression $(VAR_NAME). + +[EXAMPLES] + +tj3 tutorial.tjp + +[SEE ALSO] +tj3client(1), tj3d(1), tj3man(1), tj3ss_receiver(1), tj3ss_sender(1), tj3ts_receiver(1), tj3ts_sender(1), tj3ts_summary(1), tj3webd(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3man.h2m tj3-3.7.1/h2m/tj3man.h2m --- tj3-3.6.0/h2m/tj3man.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3man.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,22 @@ +[NAME] +tj3man \- get documentation for TaskJuggler keywords or generate user manual + +[ENVIRONMENT] + +.TP +\fBBROWSER\fR +The web browser used to display the user manual as HTML. + +[EXAMPLES] + +tj3man shift +.br +tj3man --html shift.timesheet +.br +tj3man --html + +[SEE ALSO] + +tj3(1) + +The TaskJuggler manual is also available online at http://www.taskjuggler.org/tj3/manual/. diff -Nru tj3-3.6.0/h2m/tj3ss_receiver.h2m tj3-3.7.1/h2m/tj3ss_receiver.h2m --- tj3-3.6.0/h2m/tj3ss_receiver.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3ss_receiver.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,41 @@ +[NAME] +tj3ss_receiver \- receive filled-out status sheets via email + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + + +[FILES] +.TP +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must configure an e-mail delivery method and sender e-mail e.g.: + +_global: + emailDeliveryMethod: smtp + smtpServer: smtp.your_company.com +.br +_statussheets: + senderEmail: 'TaskJuggler ' + +An alternative config file location may be specified using the -c, --config FILE option. + +.TP +\fBstatussheets.log\fR +The statussheets log file, created in the working directory. + +.TP +\fBStatusSheets/FailedMails/\fR +Directory created in the working directory to store the failed emails. + +.TP +\fBStatusSheets/FailedSheets/\fR +Directory created in the working directory to store the failed status sheets. + + +[SEE ALSO] +tj3ss_sender(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3ss_sender.h2m tj3-3.7.1/h2m/tj3ss_sender.h2m --- tj3-3.6.0/h2m/tj3ss_sender.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3ss_sender.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,38 @@ +[NAME] +tj3ss_sender \- send out status sheets templates via email + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + + +[FILES] + +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must configure an authentication key, an e-mail delivery method and sender e-mail e.g.: + +_global: + authKey: ******** + smtpServer: smtp.your_company.com +.br +_statussheets: + senderEmail: 'TaskJuggler ' + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + +.TP +\fBstatussheets.log\fR +The statussheets log file, created in the working directory. + +.TP +\fBStatusSheetTemplates\fR +Base directory of the sheet templates, created in the working directory. + + +[SEE ALSO] + +tj3ss_receiver(1), tj3d(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3ts_receiver.h2m tj3-3.7.1/h2m/tj3ts_receiver.h2m --- tj3-3.6.0/h2m/tj3ts_receiver.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3ts_receiver.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,41 @@ +[NAME] +tj3ts_receiver \- receive filled-out time sheets via email + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + + +[FILES] +.TP +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must configure an authentication key, an e-mail delivery method and sender e-mail e.g.: + +_global: + authKey: ******** + smtpServer: smtp.your_company.com +_timesheets: + senderEmail: 'TaskJuggler ' + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + +.TP +\fBtimesheets.log\fR +The statussheets log file, created in the working directory. + +.TP +\fBTimeSheets/FailedMails/\fR +Directory created in the working directory to store the failed emails. + +.TP +\fBTimeSheets/FailedSheets/\fR +Directory created in the working directory to store the failed status sheets. + + +[SEE ALSO] + +tj3ts_sender(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3ts_sender.h2m tj3-3.7.1/h2m/tj3ts_sender.h2m --- tj3-3.6.0/h2m/tj3ts_sender.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3ts_sender.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,37 @@ +[NAME] +tj3ts_sender \- send out time sheets templates via email + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + +[FILES] + +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must configure an authentication key, an e-mail delivery method and sender e-mail e.g.: + +_global: + authKey: ******** + smtpServer: smtp.your_company.com + projectId: acso +.br +_timesheets: + senderEmail: 'TaskJuggler ' + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + +.TP +\fBtimesheets.log\fR +The timesheets log file, created in the working directory. + +.TP +\fBTimeSheetTemplates\fR +Base directory of the sheet templates, created in the working directory. + + +[SEE ALSO] +tj3ts_receiver(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3ts_summary.h2m tj3-3.7.1/h2m/tj3ts_summary.h2m --- tj3-3.6.0/h2m/tj3ts_summary.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3ts_summary.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,42 @@ +[NAME] +tj3ts_summary \- send out individual copies and a summary of accepted time sheets + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + + +[FILES] + +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must configure an authentication key, an e-mail delivery method, project id, sender e-mail and receipients e.g.: + +_global: + authKey: ******** + smtpServer: smtp.your_company.com + projectId: acso +.br +_timesheets: + senderEmail: 'TaskJuggler ' + _summary: + sheetRecipients: + - team@your_company.com + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + + +.TP +\fBtimesheets.log\fR +The timesheets log file, created in the working directory. + +.TP +\fBTimeSheetTemplates\fR +Base directory of the sheet templates, created in the working directory. + + +[SEE ALSO] +tj3ts_receiver(1) tj3ts_sender(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/h2m/tj3webd.h2m tj3-3.7.1/h2m/tj3webd.h2m --- tj3-3.6.0/h2m/tj3webd.h2m 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/h2m/tj3webd.h2m 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,24 @@ +[NAME] +tj3webd \- TaskJuggler reports web server + +[ENVIRONMENT] + +.TP +\fBHOME\fR +The user's home folder. Used to search for configuration file if not specified. + +[FILES] + +.TP +\fB.taskjugglerrc\fR or \fBtaskjuggler.rc\fR +tj3d searches for a config file named .taskjugglerrc or taskjuggler.rc in the current path, the user's home path as specified by the HOME environment variable or /etc/. At a minimum the file must contain: + +_global: + authKey: ******** + +(the user should specify their own auth key and set file permissions accordingly). An alternative config file location may be specified using the -c, --config FILE option. + +[SEE ALSO] +tj3d(1) + +The full TaskJuggler manual is available online at http://www.taskjuggler.org/tj3/manual/, or via the tj3man command. diff -Nru tj3-3.6.0/lib/taskjuggler/Allocation.rb tj3-3.7.1/lib/taskjuggler/Allocation.rb --- tj3-3.6.0/lib/taskjuggler/Allocation.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Allocation.rb 2020-03-14 16:26:45.000000000 +0000 @@ -50,7 +50,7 @@ end # Set the selection mode identified by name specified in _str_. For - # efficiency reasons, we turn the name into a Fixnum value. + # efficiency reasons, we turn the name into an Integer value. def setSelectionMode(str) modes = %w( order minallocated minloaded maxloaded random ) @selectionMode = modes.index(str) diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3Client.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3Client.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3Client.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3Client.rb 2020-03-14 16:26:45.000000000 +0000 @@ -100,7 +100,7 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + prebanner = <<'EOT' The TaskJuggler client is used to send commands and data to the TaskJuggler daemon. The communication is done via TCP/IP. @@ -125,9 +125,10 @@ end end args = args.join(' ') - @opts.banner += " #{cmd[:label] + ' ' + args + tail}" + + prebanner += " #{cmd[:label] + ' ' + args + tail}" + "\n\n#{' ' * 10 + format(cmd[:descr], 10)}\n" end + @opts.banner.prepend(prebanner) @opts.on('-p', '--port ', Integer, format('Use the specified TCP/IP port')) do |arg| @port = arg diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3Daemon.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3Daemon.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3Daemon.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3Daemon.rb 2020-03-14 16:26:45.000000000 +0000 @@ -42,11 +42,13 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' The TaskJuggler daemon can be used to quickly generate reports for a number of scheduled projects that are resident in memory. Once the daemon has been started tj3client can be used to control it. + EOT + ) @opts.on('-d', '--dont-daemonize', format("Don't put program into daemon mode. Keep it " + 'connected to the terminal and show debug output.')) do diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3Man.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3Man.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3Man.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3Man.rb 2020-03-14 16:26:45.000000000 +0000 @@ -36,17 +36,19 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' This program can be used to generate the user manual in HTML format or to get a textual help for individual keywords. + EOT + ) @opts.on('-d', '--dir ', String, format('directory to put the manual')) do |dir| @directory = dir end @opts.on('--html', format('Show the user manual in your local web browser. ' + - 'By default, Firefox is used or the brower specified ' + + 'By default, Firefox is used or the browser specified ' + 'with the $BROWSER environment variable.')) do @showHtml = true end diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3.rb 2020-03-14 16:26:45.000000000 +0000 @@ -68,10 +68,12 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'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 diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3SsReceiver.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3SsReceiver.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3SsReceiver.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3SsReceiver.rb 2020-03-14 16:26:45.000000000 +0000 @@ -27,13 +27,15 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' This program can be used to receive filled-out status sheets via email. It reads the emails from STDIN and extracts the status sheet from the attached files. The status sheet is checked for correctness. Good status sheets are filed away. The sender be informed by email that the status sheets was accepted or rejected. + EOT + ) end end diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3SsSender.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3SsSender.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3SsSender.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3SsSender.rb 2020-03-14 16:26:45.000000000 +0000 @@ -38,11 +38,13 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' This program can be used to out status sheets templates via email. It will generate status sheet templates for managers of the project. The project data will be accesses via tj3client from a running TaskJuggler server process. + EOT + ) @opts.on('-r', '--resource ', String, format('Only generate template for given resource')) do |arg| @resourceList << arg diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3TsReceiver.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3TsReceiver.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3TsReceiver.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3TsReceiver.rb 2020-03-14 16:26:45.000000000 +0000 @@ -30,13 +30,15 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' This program can be used to receive filled-out time sheets via email. It reads the emails from STDIN and extracts the time sheet from the attached files. The time sheet is checked for correctness. Good time sheets are filed away. The sender will be informed by email that the time sheets was accepted or rejected. + EOT + ) end end diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3TsSender.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3TsSender.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3TsSender.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3TsSender.rb 2020-03-14 16:26:45.000000000 +0000 @@ -37,11 +37,13 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' This program can be used to send out time sheets templates via email. It will generate time sheet templates for all resources of the project. The project data will be accesses via tj3client from a running TaskJuggler server process. + EOT + ) @opts.on('-r', '--resource ', String, format('Only generate template for given resource')) do |arg| @resourceList << arg diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3TsSummary.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3TsSummary.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3TsSummary.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3TsSummary.rb 2020-03-14 16:26:45.000000000 +0000 @@ -36,12 +36,14 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' This program can be used to send out individual copies and a summary of all accepted time sheets a list of email addresses. The directory structures for templates and submitted time sheets must be present. The project data will be accesses via tj3client from a running TaskJuggler server process. + EOT + ) @opts.on('-r', '--resource ', String, format('Only generate summary for given resource')) do |arg| @resourceList << arg diff -Nru tj3-3.6.0/lib/taskjuggler/apps/Tj3WebD.rb tj3-3.7.1/lib/taskjuggler/apps/Tj3WebD.rb --- tj3-3.6.0/lib/taskjuggler/apps/Tj3WebD.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/apps/Tj3WebD.rb 2020-03-14 16:26:45.000000000 +0000 @@ -40,11 +40,13 @@ def processArguments(argv) super do - @opts.banner += <<'EOT' + @opts.banner.prepend(<<'EOT' The TaskJuggler web server can be used to serve the HTTP reports of TaskJuggler projects to be viewed by any HTML5 compliant web browser. It uses the TaskJuggler daemon (tj3d) for data hosting and report generation. + EOT + ) @opts.on('-d', '--dont-daemonize', format("Don't put program into daemon mode. Keep it " + 'connected to the terminal and show debug output.')) do diff -Nru tj3-3.6.0/lib/taskjuggler/AttributeBase.rb tj3-3.7.1/lib/taskjuggler/AttributeBase.rb --- tj3-3.6.0/lib/taskjuggler/AttributeBase.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/AttributeBase.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = AttributeBase.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -136,7 +136,7 @@ def to_num v = get - if v.is_a?(Fixnum) || v.is_a?(Bignum) || v.is_a?(Float) + if v.is_a?(Integer) || v.is_a?(Float) v else nil @@ -145,10 +145,16 @@ def to_sort v = get - if v.is_a?(Fixnum) || v.is_a?(Bignum) || v.is_a?(Float) + if v.is_a?(Integer) || v.is_a?(Float) v elsif v.respond_to?('to_s') - v.to_s + if v.respond_to?('join') + # If the attribute is an Array we convert it to a comma separated + # list. + v.join(', ') + else + v.to_s + end else nil end diff -Nru tj3-3.6.0/lib/taskjuggler/Attributes.rb tj3-3.7.1/lib/taskjuggler/Attributes.rb --- tj3-3.6.0/lib/taskjuggler/Attributes.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Attributes.rb 2020-03-14 16:26:45.000000000 +0000 @@ -264,12 +264,12 @@ end - class FixnumAttribute < AttributeBase + class IntegerAttribute < AttributeBase def initialize(property, type, container) super end - def FixnumAttribute::tjpId + def IntegerAttribute::tjpId 'integer' end end diff -Nru tj3-3.6.0/lib/taskjuggler/BatchProcessor.rb tj3-3.7.1/lib/taskjuggler/BatchProcessor.rb --- tj3-3.6.0/lib/taskjuggler/BatchProcessor.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/BatchProcessor.rb 2020-03-14 16:26:45.000000000 +0000 @@ -16,7 +16,7 @@ class TaskJuggler - # The JobInfo class is just a storage container for some batch job realted + # The JobInfo class is just a storage container for some batch job related # pieces of information. It contains things like a job id, the process id, # the stdout data and the like. class JobInfo diff -Nru tj3-3.6.0/lib/taskjuggler/deep_copy.rb tj3-3.7.1/lib/taskjuggler/deep_copy.rb --- tj3-3.6.0/lib/taskjuggler/deep_copy.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/deep_copy.rb 2020-03-14 16:26:45.000000000 +0000 @@ -37,7 +37,7 @@ # We can't clone frozen objects. So just return a reference to them. # Built-in classed can't be cloned either. The check below is probably # cheaper than the frequent (hiddent) exceptions from those objects. - return self if frozen? || nil? || is_a?(Fixnum) || is_a?(Float) || + return self if frozen? || nil? || is_a?(Integer) || is_a?(Float) || is_a?(TrueClass) || is_a?(FalseClass) || is_a?(Symbol) # In case we have loops in our graph, we return references, not diff -Nru tj3-3.6.0/lib/taskjuggler/Interval.rb tj3-3.7.1/lib/taskjuggler/Interval.rb --- tj3-3.6.0/lib/taskjuggler/Interval.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Interval.rb 2020-03-14 16:26:45.000000000 +0000 @@ -166,7 +166,7 @@ # # sbStart must be a TjTime of the scoreboard start # slotDuration must be the duration of the scoreboard slots in seconds - # a and b should be TjTime or Fixnum objects that describe the start and + # a and b should be TjTime or Integer objects that describe the start and # end time or index of the interval. # # TimeInterval.new(iv) @@ -191,7 +191,7 @@ # If the third argument is a date we convert it to a scoreboard index. args[2] = dateToIndex(args[2]) if args[2].is_a?(TjTime) - if args[2].is_a?(Fixnum) || args[2].is_a?(Bignum) + if args[2].is_a?(Integer) super(args[2], args[2]) else raise ArgumentError, "Illegal argument 3: #{args[0].class}" @@ -204,11 +204,11 @@ args[2] = dateToIndex(args[2]) if args[2].is_a?(TjTime) args[3] = dateToIndex(args[3]) if args[3].is_a?(TjTime) - if !(args[2].is_a?(Fixnum) || args[2].is_a?(Bignum)) + if !(args[2].is_a?(Integer)) raise ArgumentError, "Interval start must be an index or TjTime, " + "not a #{args[2].class}" end - if !(args[3].is_a?(Fixnum) || args[3].is_a?(Bignum)) + if !(args[3].is_a?(Integer)) raise ArgumentError, "Interval end must be an index or TjTime, " + "not a #{args[3].class}" end @@ -221,19 +221,18 @@ raise ArgumentError, "sbStart must be a TjTime object, not a" + "#{@sbStart.class}" end - unless @slotDuration.is_a?(Fixnum) - raise ArgumentError, "slotDuration must be a Fixnum, not a " + + unless @slotDuration.is_a?(Integer) + raise ArgumentError, "slotDuration must be an Integer, not a " + "#{@slotDuration.class}" end end - # Assign the start of the interval. +arg+ can be a Fixnum, Bignum or + # Assign the start of the interval. +arg+ can be an Integer or # TjTime object. def start=(arg) case arg - when Fixnum - when Bignum + when Integer @start = arg when TjTime @start = dateToIndex(arg) @@ -242,12 +241,11 @@ end end - # Assign the start of the interval. +arg+ can be a Fixnum, Bignum or + # Assign the start of the interval. +arg+ can be an Integer or # TjTime object. def end=(arg) case arg - when Fixnum - when Bignum + when Integer @end = arg when TjTime @end = dateToIndex(arg) diff -Nru tj3-3.6.0/lib/taskjuggler/Journal.rb tj3-3.7.1/lib/taskjuggler/Journal.rb --- tj3-3.6.0/lib/taskjuggler/Journal.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Journal.rb 2020-03-14 16:26:45.000000000 +0000 @@ -613,7 +613,7 @@ # This function returns a list of entries that have all the exact same # date and are the last entries before the deadline _date_. Only messages # with at least the required alert level _minLevel_ are returned. Messages - # with alert level _minLevel_ must be newer than _minDate_. + # with alert level _minLevel_ or higher must be newer than _minDate_. def currentEntries(date, property, minLevel, minDate, logExp) pEntries = getEntries(property) ? getEntries(property).last(date) : JournalEntryList.new @@ -621,7 +621,7 @@ # date. pEntries.delete_if do |e| e.headline.empty? || e.alertLevel < minLevel || - (e.alertLevel == minLevel && minDate && e.date < minDate) + (e.alertLevel >= minLevel && minDate && e.date < minDate) end unless pEntries.empty? diff -Nru tj3-3.6.0/lib/taskjuggler/LogicalFunction.rb tj3-3.7.1/lib/taskjuggler/LogicalFunction.rb --- tj3-3.6.0/lib/taskjuggler/LogicalFunction.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/LogicalFunction.rb 2020-03-14 16:26:45.000000000 +0000 @@ -139,7 +139,7 @@ # 2nd arg must be a scenario index. return false if (scenarioIdx = project.scenarioIdx(args[1])).nil? # 3rd arg must be an integer number. - return false unless args[2].is_a?(Fixnum) + return false unless args[2].is_a?(Integer) property.isDependencyOf(scenarioIdx, task, args[2]) end diff -Nru tj3-3.6.0/lib/taskjuggler/LogicalOperation.rb tj3-3.7.1/lib/taskjuggler/LogicalOperation.rb --- tj3-3.6.0/lib/taskjuggler/LogicalOperation.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/LogicalOperation.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = LogicalOperation.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -64,7 +64,7 @@ coerceTime(o, expr) end return res - elsif opnd1.is_a?(Fixnum) || opnd1.is_a?(Float) || opnd1.is_a?(Bignum) + elsif opnd1.is_a?(Integer) || opnd1.is_a?(Float) return evalBinaryOperation(opnd1, operator, opnd2) do |o| coerceNumber(o, expr) end @@ -145,14 +145,14 @@ # An empty String means false, else true. return !val.empty? if val.is_a?(String) # In TJP logic 'non 0' means false. - return val != 0 if val.is_a?(Fixnum) || val.is_a?(Bignum) + return val != 0 if val.is_a?(Integer) expr.error("Operand #{val} can't be evaluated to true or false.") end # Force the _val_ into a number. In case this fails, an exception is raised. def coerceNumber(val, expr) - unless val.is_a?(Fixnum) || val.is_a?(Float) || val.is_a?(Bignum) + unless val.is_a?(Integer) || val.is_a?(Float) expr.error("Operand #{val} of type #{val.class} must be a number.") end val @@ -216,6 +216,9 @@ query.scenarioIdx = @scenario.sequenceNo - 1 query.attributeId = @operand1 query.process + unless query.ok + return "Error in conversion to String: #{query.errorMessage}" + end query.to_s else "#{@scenario.fullId}.#{@operand1}" diff -Nru tj3-3.6.0/lib/taskjuggler/MessageHandler.rb tj3-3.7.1/lib/taskjuggler/MessageHandler.rb --- tj3-3.6.0/lib/taskjuggler/MessageHandler.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/MessageHandler.rb 2020-03-14 16:26:45.000000000 +0000 @@ -230,7 +230,7 @@ private def checkLevel(level) - if level.is_a?(Fixnum) + if level.is_a?(Integer) if level < 0 || level > 5 raise ArgumentError, "Unsupported level #{level}" end diff -Nru tj3-3.6.0/lib/taskjuggler/Project.rb tj3-3.7.1/lib/taskjuggler/Project.rb --- tj3-3.6.0/lib/taskjuggler/Project.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Project.rb 2020-03-14 16:26:45.000000000 +0000 @@ -78,6 +78,7 @@ 'currencyFormat' => RealFormat.new([ '-', '', '', ',', 2 ]), 'dailyworkinghours' => 8.0, 'end' => nil, + 'markdate' => nil, 'flags' => [], 'journal' => Journal.new, 'limits' => nil, @@ -126,7 +127,7 @@ false, false, false, true ], [ 'projection', 'Projection Mode', BooleanAttribute, true, false, false, false ], - [ 'seqno', 'No', FixnumAttribute, + [ 'seqno', 'No', IntegerAttribute, false, false, false, nil ], ] attrs.each { |a| @scenarios.addAttributeType(AttributeDefinition.new(*a)) } @@ -139,7 +140,7 @@ false, false, false, "" ], [ 'id', 'ID', StringAttribute, false, false, false, nil ], - [ 'index', 'Index', FixnumAttribute, + [ 'index', 'Index', IntegerAttribute, false, false, false, -1 ], [ 'leaves', 'Leaves', LeaveListAttribute, true, true, true, LeaveList.new ], @@ -147,7 +148,7 @@ false, false, false, nil ], [ 'replace', 'Replace', BooleanAttribute, true, false, true, false ], - [ 'seqno', 'No', FixnumAttribute, + [ 'seqno', 'No', IntegerAttribute, false, false, false, nil ], [ 'timezone', 'Time Zone', StringAttribute, true, true, true, TjTime.timeZone ], @@ -170,13 +171,13 @@ false, false, true, [] ], [ 'id', 'ID', StringAttribute, false, false, false, nil ], - [ 'index', 'Index', FixnumAttribute, + [ 'index', 'Index', IntegerAttribute, false, false, false, -1 ], [ 'flags', 'Flags', FlagListAttribute, true, false, true, [] ], [ 'name', 'Name', StringAttribute, false, false, false, nil ], - [ 'seqno', 'No', FixnumAttribute, + [ 'seqno', 'No', IntegerAttribute, false, false, false, nil ], [ 'tree', 'Tree Index', StringAttribute, false, false, false, "" ] @@ -201,7 +202,7 @@ false, false, true, [] ], [ 'efficiency','Efficiency', FloatAttribute, true, false, true, 1.0 ], - [ 'effort', 'Total Effort', FixnumAttribute, + [ 'effort', 'Total Effort', IntegerAttribute, false, false, true, 0 ], [ 'email', 'Email', StringAttribute, false, false, false, nil ], @@ -209,7 +210,7 @@ false, false, false, [] ], [ 'flags', 'Flags', FlagListAttribute, true, false, true, [] ], - [ 'index', 'Index', FixnumAttribute, + [ 'index', 'Index', IntegerAttribute, false, false, false, -1 ], [ 'leaveallowances', 'Leave Allowances', LeaveAllowanceListAttribute, true, false, true, LeaveAllowanceList.new ], @@ -223,7 +224,7 @@ true, true, true, 0.0 ], [ 'reports', 'Reports', ResourceListAttribute, false, false, true, [] ], - [ 'seqno', 'No', FixnumAttribute, + [ 'seqno', 'No', IntegerAttribute, false, false, false, nil ], [ 'shifts', 'Shifts', ShiftAssignmentsAttribute, true, false, true, nil ], @@ -264,9 +265,9 @@ false, false, true, 0 ], [ 'effort', 'Effort', DurationAttribute, false, false, true, 0 ], - [ 'effortdone', 'Completed Effort', FixnumAttribute, + [ 'effortdone', 'Completed Effort', IntegerAttribute, false, false, true, nil ], - [ 'effortleft', 'Remaining Effort', FixnumAttribute, + [ 'effortleft', 'Remaining Effort', IntegerAttribute, false, false, true, nil ], [ 'end', 'End', DateAttribute, false, false, true, nil ], @@ -284,7 +285,7 @@ false, false, true, nil ], [ 'id', 'ID', StringAttribute, false, false, false, nil ], - [ 'index', 'Index', FixnumAttribute, + [ 'index', 'Index', IntegerAttribute, false, false, false, -1 ], [ 'length', 'Length', DurationAttribute, false, false, true, 0 ], @@ -308,7 +309,7 @@ false, false, true, 0.0 ], [ 'precedes', 'Following tasks', DependencyListAttribute, true, false, true, [] ], - [ 'priority', 'Priority', FixnumAttribute, + [ 'priority', 'Priority', IntegerAttribute, true, true, true, 500 ], [ 'projectid', 'Project ID', SymbolAttribute, true, true, true, nil ], @@ -318,7 +319,7 @@ true, false, true, false ], [ 'projectionmode', 'Projection Mode', BooleanAttribute, true, false, true, false ], - [ 'seqno', 'No', FixnumAttribute, + [ 'seqno', 'No', IntegerAttribute, false, false, false, nil ], [ 'shifts', 'Shifts', ShiftAssignmentsAttribute, true, false, true, nil ], @@ -361,6 +362,8 @@ true, false, false, KeywordArray.new([ '*' ]) ], [ 'end', 'End', DateAttribute, true, true, false, nil ], + [ 'markdate', 'Markdate', DateAttribute, + true, true, false, nil ], [ 'epilog', 'Epilog', RichTextAttribute, true, false, false, nil ], [ 'flags', 'Flags', FlagListAttribute, @@ -383,11 +386,11 @@ true, false, false, nil ], [ 'hideTask', 'Hide Task', LogicalExpressionAttribute, true, false, false, nil ], - [ 'height', 'Height', FixnumAttribute, + [ 'height', 'Height', IntegerAttribute, false, false, false, 480 ], [ 'id', 'ID', StringAttribute, false, false, false, nil ], - [ 'index', 'Index', FixnumAttribute, + [ 'index', 'Index', IntegerAttribute, false, false, false, -1 ], [ 'interactive', 'Interactive', BooleanAttribute, false, false, false, false ], @@ -429,7 +432,7 @@ true, false, false, [ 0 ] ], [ 'selfcontained', 'Selfcontained', BooleanAttribute, true, false, false, false ], - [ 'seqno', 'No', FixnumAttribute, + [ 'seqno', 'No', IntegerAttribute, false, false, false, nil ], [ 'shortTimeFormat', 'Short Time Format', StringAttribute, true, true, false, nil ], @@ -461,8 +464,10 @@ false, false, false, "" ], [ 'weekStartsMonday', 'Week Starts Monday', BooleanAttribute, true, true, false, false ], - [ 'width', 'Width', FixnumAttribute, - true, false, false, 640 ] + [ 'width', 'Width', IntegerAttribute, + true, false, false, 640 ], + [ 'novevents', 'No vevents in icalreports', BooleanAttribute, + true, false, false, false ] ] attrs.each { |a| @reports.addAttributeType(AttributeDefinition.new(*a)) } @@ -560,7 +565,7 @@ # # Return the Scenario with the given _id_ or _index_. def scenario(arg) - if arg.is_a?(Fixnum) + if arg.is_a?(Integer) @scenarios.each do |sc| return sc if sc.sequenceNo - 1 == arg end @@ -866,7 +871,7 @@ # isWorkingTime(startTime, endTime) -> true or false # isWorkingTime(interval) -> true or false # - # Return true if the slot or interval is withing globally defined working + # Return true if the slot or interval is within globally defined working # time or false if not. If the argument is a TimeInterval, all slots of # the interval must be working time to return true as result. Global work # time means, no global leaves defined and the slot lies within a @@ -874,7 +879,7 @@ def isWorkingTime(*args) # Normalize argument(s) to TimeInterval if args.length == 1 - if args[0].is_a?(Fixnum) || args[0].is_a?(Bignum) + if args[0].is_a?(Integer) return @scoreboard[args[0]].nil? elsif args[0].is_a?(TjTime) return @scoreboard[dateToIdx(args[0])].nil? @@ -969,7 +974,7 @@ def collectTimeOffIntervals(iv, minDuration) @scoreboard.collectIntervals(iv, minDuration) do |val| - val.is_a?(Fixnum) && (val & 0x3E) != 0 + val.is_a?(Integer) && (val & 0x3E) != 0 end end diff -Nru tj3-3.6.0/lib/taskjuggler/PropertyList.rb tj3-3.7.1/lib/taskjuggler/PropertyList.rb --- tj3-3.6.0/lib/taskjuggler/PropertyList.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/PropertyList.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = PropertyList.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -271,10 +271,16 @@ @query.property = a @query.process + unless @query.ok + fatal "List sort failed: #{@query.errorMessage}" + end aVal = @query.to_sort @query.property = b @query.process + unless @query.ok + fatal "List sort failed: #{@query.errorMessage}" + end bVal = @query.to_sort else # In case we don't have a query, we use the static mechanism. diff -Nru tj3-3.6.0/lib/taskjuggler/PropertySet.rb tj3-3.7.1/lib/taskjuggler/PropertySet.rb --- tj3-3.6.0/lib/taskjuggler/PropertySet.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/PropertySet.rb 2020-03-14 16:26:45.000000000 +0000 @@ -51,7 +51,7 @@ [ [ 'id', 'ID', StringAttribute, false, false, false, '' ], [ 'name', 'Name', StringAttribute, false, false, false, '' ], - [ 'seqno', 'Seq. No', FixnumAttribute, false, false, false, 0 ] + [ 'seqno', 'Seq. No', IntegerAttribute, false, false, false, 0 ] ].each { |a| addAttributeType(AttributeDefinition.new(*a)) } end diff -Nru tj3-3.6.0/lib/taskjuggler/PropertyTreeNode.rb tj3-3.7.1/lib/taskjuggler/PropertyTreeNode.rb --- tj3-3.6.0/lib/taskjuggler/PropertyTreeNode.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/PropertyTreeNode.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = PropertyTreeNode.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -331,7 +331,7 @@ end # Return the 'index' attributes of this property, prefixed by the 'index' - # attributes of all its parents. The result is an Array of Fixnums. + # attributes of all its parents. The result is an Array of Integers. def getIndicies idcs = [] p = self @@ -702,11 +702,13 @@ res += '-' * 75 + "\n" end + alias to_str to_s + # Many PropertyTreeNode functions are scenario specific. These functions are # provided by the class *Scenario classes. In case we can't find a function # called for the base class we try to find it in corresponding *Scenario # class. - def method_missing(func, scenarioIdx, *args, &block) + def method_missing(func, scenarioIdx = 0, *args, &block) @data[scenarioIdx].send(func, *args, &block) end diff -Nru tj3-3.6.0/lib/taskjuggler/PTNProxy.rb tj3-3.7.1/lib/taskjuggler/PTNProxy.rb --- tj3-3.6.0/lib/taskjuggler/PTNProxy.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/PTNProxy.rb 2020-03-14 16:26:45.000000000 +0000 @@ -104,7 +104,7 @@ end # Return the 'index' attributes of this property, prefixed by the 'index' - # attributes of all its parents. The result is an Array of Fixnums. + # attributes of all its parents. The result is an Array of Integers. def getIndicies idcs = [] p = self diff -Nru tj3-3.6.0/lib/taskjuggler/Query.rb tj3-3.7.1/lib/taskjuggler/Query.rb --- tj3-3.6.0/lib/taskjuggler/Query.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Query.rb 2020-03-14 16:26:45.000000000 +0000 @@ -81,7 +81,7 @@ end def startIdx=(idx) - if idx.is_a?(Fixnum) + if idx.is_a?(Integer) @startIdx = idx @start = @project.idxToDate(idx) else @@ -99,7 +99,7 @@ end def endIdx=(idx) - if idx.is_a?(Fixnum) + if idx.is_a?(Integer) @endIdx = idx @end = @project.idxToDate(idx) else @@ -239,7 +239,7 @@ @attr ? @attr.to_s(self) : (@rti ? @rti.to_s : (@string || '')) end - # Return the result of the Query as Fixnum or Float. The result may be + # Return the result of the Query as Integer or Float. The result may be # nil. def to_num @attr ? @attr.to_num : @numerical diff -Nru tj3-3.6.0/lib/taskjuggler/RealFormat.rb tj3-3.7.1/lib/taskjuggler/RealFormat.rb --- tj3-3.6.0/lib/taskjuggler/RealFormat.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/RealFormat.rb 2020-03-14 16:26:45.000000000 +0000 @@ -24,7 +24,7 @@ # thousandsSeparator: Separator used after 3 integer digits. (String) # fractionSeparator: Separator used between the inter part and the # fractional part. (String) - # fractionDigits: Number of fractional digits to show. (Fixnum) + # fractionDigits: Number of fractional digits to show. (Integer) class RealFormat attr_reader :signPrefix, :signSuffix, :thousandsSeparator, diff -Nru tj3-3.6.0/lib/taskjuggler/reports/ChartPlotter.rb tj3-3.7.1/lib/taskjuggler/reports/ChartPlotter.rb --- tj3-3.6.0/lib/taskjuggler/reports/ChartPlotter.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/ChartPlotter.rb 2020-03-14 16:26:45.000000000 +0000 @@ -163,7 +163,7 @@ @yMinDate = cell if @yMinDate.nil? || cell < @yMinDate @yMaxDate = cell if @yMaxDate.nil? || cell > @yMaxDate - elsif cell.is_a?(Fixnum) || cell.is_a?(Float) + elsif cell.is_a?(Integer) || cell.is_a?(Float) if @dataType && @dataType != :number error("Column #{colIdx} contains non-number (#{cell}). " + "The columns will be ignored.") diff -Nru tj3-3.6.0/lib/taskjuggler/reports/CSVFile.rb tj3-3.7.1/lib/taskjuggler/reports/CSVFile.rb --- tj3-3.6.0/lib/taskjuggler/reports/CSVFile.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/CSVFile.rb 2020-03-14 16:26:45.000000000 +0000 @@ -157,7 +157,7 @@ end when :fieldEnd # We've completed processing a field. Add the field to the list of - # fields. Convert Fixnums and Floats in native types. + # fields. Convert Integers and Floats in native types. fields << unMarshal(field, quoted) if c == "\n" @@ -198,7 +198,7 @@ if str.nil? nil elsif /^[-+]?\d+$/ =~ str - # field is a Fixnum + # field is an Integer str.to_i elsif /^[-+]?\d*\.?\d+([eE][-+]?\d+)?$/ =~ str # field is a Float @@ -216,7 +216,7 @@ def marshal(field) if field.nil? '' - elsif field.is_a?(Fixnum) || field.is_a?(Float) || field.is_a?(Bignum) + elsif field.is_a?(Integer) || field.is_a?(Float) # Numbers don't have to be quoted. field.to_s else diff -Nru tj3-3.6.0/lib/taskjuggler/reports/GanttChart.rb tj3-3.7.1/lib/taskjuggler/reports/GanttChart.rb --- tj3-3.6.0/lib/taskjuggler/reports/GanttChart.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/GanttChart.rb 2020-03-14 16:26:45.000000000 +0000 @@ -35,7 +35,7 @@ include HTMLGraphics attr_reader :start, :end, :now, :weekStartsMonday, :header, :width, - :scale, :scales, :table + :scale, :scales, :table, :markdate attr_writer :viewWidth # Create the GanttChart object, but don't do much right now. We still need @@ -43,13 +43,14 @@ # is the date that should be used as current date. _weekStartsMonday_ is # true if the weeks should start on Mondays instead of Sundays. _table_ is a # reference to the TableReport that the chart is part of. - def initialize(now, weekStartsMonday, columnDef, table = nil) + def initialize(now, weekStartsMonday, columnDef, table = nil, markdate = nil) # The start and end dates of the reported interval. @start = nil @end = nil @now = now @columnDef = columnDef @table = table + @markdate = markdate # This defines the possible horizontal scales that the Gantt chart can # have. The scales differ in their resolution and the amount of detail @@ -256,6 +257,11 @@ # Also protect the current date line from other vertical lines. @router.addZone(@header.nowLineX - 1, 0, 3, @height - 1, false, true) + # Protect the date set in custom reference line from other vertical lines. + if @header.markdateLineX + @router.addZone(@header.markdateLineX - 1, 0, 3, @height - 1, false, true) + end + # Generate the dependency arrows for all visible tasks. @tasks.each do |task, lines| generateDepLines(task, lines) diff -Nru tj3-3.6.0/lib/taskjuggler/reports/GanttHeader.rb tj3-3.7.1/lib/taskjuggler/reports/GanttHeader.rb --- tj3-3.6.0/lib/taskjuggler/reports/GanttHeader.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/GanttHeader.rb 2020-03-14 16:26:45.000000000 +0000 @@ -21,7 +21,7 @@ # holds the small scale (e. g. week or day). class GanttHeader - attr_reader :gridLines, :nowLineX, :cellStartDates + attr_reader :gridLines, :nowLineX, :cellStartDates, :markdateLineX attr_accessor :height # Create a GanttHeader object and generate the scales for the header. @@ -39,6 +39,10 @@ # X coordinate of the "now" line. nil if "now" is off-chart. @nowLineX = nil + # X coordinate of the custom "markdate" line with date specified by user. + # nil if "markdate" is off-chart. + @markdateLineX = nil + # The x coordinates and width of the cells created by the small scale. The # values are stored as [ x, w ]. @cellStartDates = [] @@ -103,6 +107,12 @@ nlx = @chart.dateToX(@chart.now) @nowLineX = nlx if nlx + + if @chart.markdate + flx = @chart.dateToX(@chart.markdate) + @markdateLineX = flx if flx + end + end # Generate the actual scale cells. diff -Nru tj3-3.6.0/lib/taskjuggler/reports/GanttLine.rb tj3-3.7.1/lib/taskjuggler/reports/GanttLine.rb --- tj3-3.6.0/lib/taskjuggler/reports/GanttLine.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/GanttLine.rb 2020-03-14 16:26:45.000000000 +0000 @@ -49,6 +49,7 @@ @y = y + chart.header.height + 1 # The height of the line in screen pixels. @height = height + # The index of the line in the chart. It starts with 0 and is # incremented for each line by one. @lineIndex = lineIndex @@ -95,6 +96,11 @@ div << rectToHTML(@chart.header.nowLineX, 0, 1, @height, 'nowline') end + # Render the 'markdate' line + if @chart.header.markdateLineX + div << rectToHTML(@chart.header.markdateLineX, 0, 1, @height, 'markdateline') + end + div end diff -Nru tj3-3.6.0/lib/taskjuggler/reports/ICalReport.rb tj3-3.7.1/lib/taskjuggler/reports/ICalReport.rb --- tj3-3.6.0/lib/taskjuggler/reports/ICalReport.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/ICalReport.rb 2020-03-14 16:26:45.000000000 +0000 @@ -96,7 +96,7 @@ # Generate an additional VEVENT entry for all leaf tasks that aren't # milestones. - if task.leaf? && !task['milestone', scenarioIdx] + if task.leaf? && !task['milestone', scenarioIdx] && @report.get('novevents') == [false] event = ICalendar::Event.new( @ical, "#{task['projectid', scenarioIdx]}-#{task.fullId}", task.name, task['start', scenarioIdx], task['end', scenarioIdx]) diff -Nru tj3-3.6.0/lib/taskjuggler/reports/Report.rb tj3-3.7.1/lib/taskjuggler/reports/Report.rb --- tj3-3.6.0/lib/taskjuggler/reports/Report.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/Report.rb 2020-03-14 16:26:45.000000000 +0000 @@ -297,7 +297,7 @@ if @name == '.' $stdout.write(@content.to_tjp) else - fileName = absoluteFileName(@name) + fileName = @name fileName += a('definitions').include?('project') ? '.tjp' : '.tji' File.open(fileName, 'w') { |f| f.write(@content.to_tjp) } end diff -Nru tj3-3.6.0/lib/taskjuggler/reports/ReportTableCell.rb tj3-3.7.1/lib/taskjuggler/reports/ReportTableCell.rb --- tj3-3.6.0/lib/taskjuggler/reports/ReportTableCell.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/ReportTableCell.rb 2020-03-14 16:26:45.000000000 +0000 @@ -60,7 +60,7 @@ @alignment = :center # Horizontal padding between frame and cell content @padding = 3 - # Whether or not to indent the cell. If not nil, it is a Fixnum + # Whether or not to indent the cell. If not nil, it is an Integer # indicating the indentation level. @indent = nil # The basename of the icon file diff -Nru tj3-3.6.0/lib/taskjuggler/reports/TableReport.rb tj3-3.7.1/lib/taskjuggler/reports/TableReport.rb --- tj3-3.6.0/lib/taskjuggler/reports/TableReport.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/TableReport.rb 2020-03-14 16:26:45.000000000 +0000 @@ -32,6 +32,7 @@ 'activetasks' => [ 'Active Tasks', true, :right, true ], 'annualleave' => [ 'Annual Leave', true, :right, true ], 'annualleavebalance'=> [ 'Annual Leave Balance', false, :right, true ], + 'annualleavelist' => [ 'Annual Leave List', false, :left, true ], 'alert' => [ 'Alert', true, :left, false ], 'alertmessages' => [ 'Alert Messages', false, :left, false ], 'alertsummaries' => [ 'Alert Summaries', false, :left, false ], @@ -79,7 +80,7 @@ @@propertiesByType = { # Type Indent Align DateAttribute => [ false, :left ], - FixnumAttribute => [ false, :right ], + IntegerAttribute => [ false, :right ], FloatAttribute => [ false, :right ], ResourceListAttribute => [ false, :left ], RichTextAttribute => [ false, :left ], @@ -338,9 +339,9 @@ when 'chart' # For the 'chart' column we generate a GanttChart object. The sizes are # set so that the lines of the Gantt chart line up with the lines of the - # table. + # table gantt = GanttChart.new(a('now'), - a('weekStartsMonday'), columnDef, self) + a('weekStartsMonday'), columnDef, self, a('markdate')) gantt.generateByScale(rStart, rEnd, columnDef.scale) # The header consists of 2 lines separated by a 1 pixel boundary. @@ -867,12 +868,6 @@ # the next cell. def genCalChartTaskCell(query, line, columnDef, t, sameTimeNextFunc) task = line.property - # Find out if we have an enclosing resource scope. - if line.scopeLine && line.scopeLine.property.is_a?(Resource) - resource = line.scopeLine.property - else - resource = nil - end # Get the interval of the task. In case a date is invalid due to a # scheduling problem, we use the full project interval. @@ -1048,11 +1043,11 @@ 'busy' elsif workLoad > 0.0 && freeLoad > 0.0 'loaded' - elsif workLoad == 0.0 && freeLoad > 0.0 - 'free' - else + elsif workLoad == 0.0 && freeLoad == 0.0 cell.tooltip = nil 'offduty' + else + 'free' end end cell.category += line.subLineNo % 2 == 1 ? '1' : '2' diff -Nru tj3-3.6.0/lib/taskjuggler/reports/TjpExportRE.rb tj3-3.7.1/lib/taskjuggler/reports/TjpExportRE.rb --- tj3-3.6.0/lib/taskjuggler/reports/TjpExportRE.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/reports/TjpExportRE.rb 2020-03-14 16:26:45.000000000 +0000 @@ -265,11 +265,7 @@ if isLeafTask a('scenarios').each do |scenarioIdx| generateAttribute(task, 'start', indent + 2, scenarioIdx) - if task['milestone', scenarioIdx] - if task['scheduled', scenarioIdx] - generateAttributeText('milestone', indent + 2, scenarioIdx) - end - else + if !task['milestone', scenarioIdx] generateAttribute(task, 'end', indent + 2, scenarioIdx) generateAttributeText('scheduling ' + (task['forward', scenarioIdx] ? diff -Nru tj3-3.6.0/lib/taskjuggler/Resource.rb tj3-3.7.1/lib/taskjuggler/Resource.rb --- tj3-3.6.0/lib/taskjuggler/Resource.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Resource.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = Resource.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -37,7 +37,7 @@ # provided by the class ResourceScenario. In case we can't find a # function called for the Resource class we try to find it in # ResourceScenario. - def method_missing(func, scenarioIdx, *args, &block) + def method_missing(func, scenarioIdx = 0, *args, &block) @data[scenarioIdx].method(func).call(*args, &block) end diff -Nru tj3-3.6.0/lib/taskjuggler/ResourceScenario.rb tj3-3.7.1/lib/taskjuggler/ResourceScenario.rb --- tj3-3.6.0/lib/taskjuggler/ResourceScenario.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/ResourceScenario.rb 2020-03-14 16:26:45.000000000 +0000 @@ -20,7 +20,7 @@ def initialize(resource, scenarioIdx, attributes) super - # Scoreboard may be nil, a Task, or a bit vector encoded as a Fixnum + # Scoreboard may be nil, a Task, or a bit vector encoded as an Integer # nil: Value has not been determined yet. # Task: A reference to a Task object # Bit 0: Reserved @@ -279,6 +279,23 @@ query.string = query.scaleLoad(val) end + # Compute a list of the annual leave days within the period specified by + # the _query_. The result is a list of dates and how much of that day was + # taken. + def query_annualleavelist(query) + iv_list = collectLeaveIntervals(Interval.new(query.start, query.end), :annual) + iv_list.map! do |iv| + # The interval is at most one working day. We list the date of that + # day. + day = iv.start.strftime(@project['timeFormat']) + # And how much of the working day was taken. A full working day is + # 1.0, a half working day 0.5. + days = (iv.end - iv.start) / (60 * 60 * @project['dailyworkinghours']) + "#{day} (#{'%.1f' % days})" + end + query.assignList(iv_list) + end + def query_annualleavebalance(query) if @property.leaf? leave = getLeave(query.startIdx, query.endIdx, :annual) @@ -685,7 +702,22 @@ initScoreboard if @scoreboard.nil? @scoreboard.collectIntervals(iv, minDuration) do |val| - val.is_a?(Fixnum) && (val & 0x3E) != 0 + val.is_a?(Integer) && (val & 0x3E) != 0 + end + end + + # Return a list of scoreboard intervals that are at least _minDuration_ long + # and only contain leave slots of the given type. The result is an Array of + # [ start, end ] TjTime values. + def collectLeaveIntervals(iv, type) + # Time-off intervals are only useful for leaf resources. Group resources + # would just default to the global working hours. + return [] unless @property.leaf? + + initScoreboard if @scoreboard.nil? + + @scoreboard.collectIntervals(iv, 60 * 60) do |val| + val.is_a?(Integer) && (val & 0x3E) == (Leave::Types[type] << 2) end end @@ -723,7 +755,7 @@ # leave. def getLeaveSlots(startIdx, endIdx, type) countSlots(startIdx, endIdx) do |val| - val.is_a?(Fixnum) && (val & 0x3E) == (Leave::Types[type] << 2) + val.is_a?(Integer) && (val & 0x3E) == (Leave::Types[type] << 2) end end @@ -739,7 +771,7 @@ def getTimeOffSlots(startIdx, endIdx) countSlots(startIdx, endIdx) do |val| # Bit 1 needs to be unset and the leave bits must not be 0. - val.is_a?(Fixnum) && (val & 0x2) == 0 && (val & 0x3C) != 0 + val.is_a?(Integer) && (val & 0x2) == 0 && (val & 0x3C) != 0 end end @@ -900,7 +932,7 @@ initScoreboard unless @scoreboard val = @scoreboard[sbIdx] - return true unless val.is_a?(Fixnum) + return true unless val.is_a?(Integer) leave_type = (val >> 2) & 0xF leave_type < Leave::Types[:unemployed] diff -Nru tj3-3.6.0/lib/taskjuggler/RichText/Snip.rb tj3-3.7.1/lib/taskjuggler/RichText/Snip.rb --- tj3-3.6.0/lib/taskjuggler/RichText/Snip.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/RichText/Snip.rb 2020-03-14 16:26:45.000000000 +0000 @@ -27,7 +27,7 @@ # Create a RichTextSnip object. _document_ is a reference to the # RichTextDocument. _fileName_ is the name of the structured text file - # using RichText syntax. _sectionCounter_ is an 3 item Fixnum Array. These + # using RichText syntax. _sectionCounter_ is an 3 item Integer Array. These # 3 numbers are used to store the section counters over multiple # RichTextSnip objects. def initialize(document, fileName, sectionCounter) diff -Nru tj3-3.6.0/lib/taskjuggler/RuntimeConfig.rb tj3-3.7.1/lib/taskjuggler/RuntimeConfig.rb --- tj3-3.6.0/lib/taskjuggler/RuntimeConfig.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/RuntimeConfig.rb 2020-03-14 16:26:45.000000000 +0000 @@ -45,7 +45,7 @@ def configure(object, section) debug("Configuring object of type #{object.class}") sections = section.split('.') - p = @config + return false unless (p = @config) sections.each do |sec| p = p['_' + sec] unless p diff -Nru tj3-3.6.0/lib/taskjuggler/Scoreboard.rb tj3-3.7.1/lib/taskjuggler/Scoreboard.rb --- tj3-3.6.0/lib/taskjuggler/Scoreboard.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Scoreboard.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = Scoreboard.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -175,9 +175,12 @@ end def inspect + s = '' 0.upto(@sb.length - 1) do |i| - puts "#{idxToDate(i)}: #{@sb[i]}" + s << "#{idxToDate(i)}: #{@sb[i]}" end + + s end end diff -Nru tj3-3.6.0/lib/taskjuggler/ShiftAssignments.rb tj3-3.7.1/lib/taskjuggler/ShiftAssignments.rb --- tj3-3.6.0/lib/taskjuggler/ShiftAssignments.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/ShiftAssignments.rb 2020-03-14 16:26:45.000000000 +0000 @@ -79,7 +79,7 @@ # To optimize memory usage and computation time the Scoreboard objects for # similar ShiftAssignments are shared. # - # Scoreboard may be nil or a bit vector encoded as a Fixnum + # Scoreboard may be nil or a bit vector encoded as an Integer # nil: Value has not been determined yet. # Bit 0: 0: No assignment # 1: Has assignement diff -Nru tj3-3.6.0/lib/taskjuggler/Shift.rb tj3-3.7.1/lib/taskjuggler/Shift.rb --- tj3-3.6.0/lib/taskjuggler/Shift.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Shift.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,7 @@ # # = Shift.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -34,7 +34,7 @@ # provided by the class ShiftScenario. In case we can't find a # function called for the Shift class we try to find it in # ShiftScenario. - def method_missing(func, scenarioIdx, *args) + def method_missing(func, scenarioIdx = 0, *args) @data[scenarioIdx].method(func).call(*args) end diff -Nru tj3-3.6.0/lib/taskjuggler/TaskJuggler.rb tj3-3.7.1/lib/taskjuggler/TaskJuggler.rb --- tj3-3.6.0/lib/taskjuggler/TaskJuggler.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/TaskJuggler.rb 2020-03-14 16:26:45.000000000 +0000 @@ -29,7 +29,7 @@ attr_accessor :maxCpuCores, :warnTsDeltas, :generateTraces # Create a new TaskJuggler object. _console_ is a boolean that determines - # whether or not messsages can be written to $stderr. + # whether or not messages can be written to $stderr. def initialize @project = nil @parser = nil @@ -141,7 +141,7 @@ res end - # Generate all specified reports. The project must have be scheduled before + # Generate all specified reports. The project must have been scheduled before # this method can be called. It returns true if no error occured, false # otherwise. def generateReports(outputDir = nil) @@ -289,7 +289,7 @@ end # Check the content of the file _fileName_ and interpret it as a time sheet. - # If the sheet is syntaxtically correct and matches the loaded project, true + # If the sheet is syntactically correct and matches the loaded project, true # is returned. Otherwise false. def checkTimeSheet(fileName) begin @@ -333,7 +333,7 @@ end # Check the content of the file _fileName_ and interpret it as a status - # sheet. If the sheet is syntaxtically correct and matches the loaded + # sheet. If the sheet is syntactically correct and matches the loaded # project, true is returned. Otherwise false. def checkStatusSheet(fileName) begin diff -Nru tj3-3.6.0/lib/taskjuggler/TextParser/Scanner.rb tj3-3.7.1/lib/taskjuggler/TextParser/Scanner.rb --- tj3-3.6.0/lib/taskjuggler/TextParser/Scanner.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/TextParser/Scanner.rb 2020-03-14 16:26:45.000000000 +0000 @@ -43,9 +43,9 @@ # This class is used to handle the low-level input operations. It knows # whether it deals with a text buffer or a file and abstracts this to the - # Scanner. For each nested file the scanner puts an StreamHandle on the + # Scanner. For each nested file the scanner puts a StreamHandle on the # stack while the file is scanned. With this stack the scanner can resume - # the processing of the enclosing file once the included files has been + # the processing of the enclosing file once the included files have been # completely processed. class StreamHandle @@ -281,7 +281,7 @@ end - # Start the processing. if _fileNameIsBuffer_ is true, we operate on a + # Start the processing. If _fileNameIsBuffer_ is true, we operate on a # String, else on a File. def open(fileNameIsBuffer = false) @fileNameIsBuffer = fileNameIsBuffer diff -Nru tj3-3.6.0/lib/taskjuggler/TextParser.rb tj3-3.7.1/lib/taskjuggler/TextParser.rb --- tj3-3.6.0/lib/taskjuggler/TextParser.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/TextParser.rb 2020-03-14 16:26:45.000000000 +0000 @@ -123,7 +123,7 @@ # Add a new rule to the rule set. _name_ must be a unique identifier. The # function also sets the class variable @cr to the new rule. Subsequent # calls to TextParser#pattern, TextParser#optional or - # TextParser#repeatable will then implicitely operate on the most recently + # TextParser#repeatable will then implicitly operate on the most recently # added rule. def newRule(name) # Use a symbol instead of a String. diff -Nru tj3-3.6.0/lib/taskjuggler/TimeSheets.rb tj3-3.7.1/lib/taskjuggler/TimeSheets.rb --- tj3-3.6.0/lib/taskjuggler/TimeSheets.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/TimeSheets.rb 2020-03-14 16:26:45.000000000 +0000 @@ -46,11 +46,11 @@ @sourceFileInfo = nil end - # Store the number of worked time slots. If the value is a Fixnum, it can + # Store the number of worked time slots. If the value is an Integer, it can # be directly assigned. A Float is interpreted as percentage and must be # in the rage of 0.0 to 1.0. def work=(value) - if value.is_a?(Fixnum) + if value.is_a?(Integer) @work = value else # Must be percent value diff -Nru tj3-3.6.0/lib/taskjuggler/Tj3AppBase.rb tj3-3.7.1/lib/taskjuggler/Tj3AppBase.rb --- tj3-3.6.0/lib/taskjuggler/Tj3AppBase.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Tj3AppBase.rb 2020-03-14 16:26:45.000000000 +0000 @@ -51,16 +51,15 @@ @opts.summary_width = @optsSummaryWidth @opts.summary_indent = ' ' * @optsSummaryIndent - @opts.banner = "#{AppConfig.softwareName} v#{AppConfig.version} - " + - "#{AppConfig.packageInfo}\n\n" + - "Copyright (c) #{AppConfig.copyright.join(', ')}\n" + + @opts.banner = "Copyright (c) #{AppConfig.copyright.join(', ')}\n" + " by #{AppConfig.authors.join(', ')}\n\n" + "#{AppConfig.license}\n" + "For more info about #{AppConfig.softwareName} see " + "#{AppConfig.contact}\n\n" + "Usage: #{AppConfig.appName} [options] " + "#{@mandatoryArgs}\n\n" - @opts.separator "" + + @opts.separator "\nOptions:" @opts.on('-c', '--config ', String, format('Use the specified YAML configuration file')) do |arg| @configFile = arg @@ -75,7 +74,7 @@ format(<<'EOT' Don't use ANSI contol sequences to color the terminal output. Colors should only be used when spooling to an ANSI terminal. In case the detection fails, -you can this option to force colors to be off. +you can use this option to force colors to be off. EOT )) do Term::ANSIColor::coloring = false @@ -91,8 +90,23 @@ quit end @opts.on_tail('--version', format('Show version info')) do - puts "#{AppConfig.softwareName} v#{AppConfig.version} - " + - "#{AppConfig.packageInfo}" +# Display the software name and version in GNU format +# as expected by help2man +# https://www.gnu.org/prep/standards/standards.html#g_t_002d_002dversion + puts "#{AppConfig.appName} (#{AppConfig.softwareName}) #{AppConfig.version}\n" +# To also display the copyright and license statements in GNU format +# uncomment the following and remove the equivalent statements from +# --help +# + +#<<'EOT' +#Copyright (C) 2016 Chris Schlaeger +#License GPLv2: GNU GPL version 2 +#This is free software; you can redistribute it and/or modify it under +#the terms of version 2 of the GNU General Public License as published by the +#Free Software Foundation. +# +#For more info about TaskJuggler see http://www.taskjuggler.org +#EOT quit end @@ -128,7 +142,7 @@ args = processArguments(argv) # If DEBUG mode has been enabled, we restore the INT trap handler again - # to get Ruby backtrackes. + # to get Ruby backtraces. Kernel.trap('INT', intHandler) if $DEBUG unless @silent @@ -146,7 +160,7 @@ retVal = appMain(args) MessageHandlerInstance.instance.trapSetup = false rescue TjRuntimeError - # We have hit a sitatuation that we can't recover from. A message + # We have hit a situation that we can't recover from. A message # was severed via the MessageHandler to inform the user and we now # abort the program. return 1 diff -Nru tj3-3.6.0/lib/taskjuggler/Tj3Config.rb tj3-3.7.1/lib/taskjuggler/Tj3Config.rb --- tj3-3.6.0/lib/taskjuggler/Tj3Config.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/Tj3Config.rb 2020-03-14 16:26:45.000000000 +0000 @@ -3,7 +3,8 @@ # # = Tj3Config.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016 +# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, +# 2020 # by Chris Schlaeger # # This program is free software; you can redistribute it and/or modify @@ -13,12 +14,13 @@ require 'taskjuggler/UTF8String' require 'taskjuggler/AppConfig' +require 'taskjuggler/version' -AppConfig.version = '3.6.0' +AppConfig.version = VERSION AppConfig.packageName = 'taskjuggler' AppConfig.softwareName = 'TaskJuggler' AppConfig.packageInfo = 'A Project Management Software' -AppConfig.copyright = [ (2006..2016).to_a ] +AppConfig.copyright = [ (2006..2020).to_a ] AppConfig.authors = [ 'Chris Schlaeger ' ] AppConfig.contact = 'http://www.taskjuggler.org' AppConfig.license = <<'EOT' diff -Nru tj3-3.6.0/lib/taskjuggler/TjpExample.rb tj3-3.7.1/lib/taskjuggler/TjpExample.rb --- tj3-3.6.0/lib/taskjuggler/TjpExample.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/TjpExample.rb 2020-03-14 16:26:45.000000000 +0000 @@ -75,7 +75,9 @@ @file.each_line do |line| if line[0, mark.length] == mark # We've found an annotation line. Get the tag and indicator. - dum, dum, dum, tag, indicator = line.split + tokens = line.split + tag = tokens[3] + indicator = tokens[4] if indicator == '+' # Start a new snip diff -Nru tj3-3.6.0/lib/taskjuggler/TjpSyntaxRules.rb tj3-3.7.1/lib/taskjuggler/TjpSyntaxRules.rb --- tj3-3.6.0/lib/taskjuggler/TjpSyntaxRules.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/TjpSyntaxRules.rb 2020-03-14 16:26:45.000000000 +0000 @@ -76,7 +76,7 @@ def rule_accountHeader pattern(%w( _account !optionalID $STRING ), lambda { if @property.nil? && !@accountprefix.empty? - @property = @project.accout(@accountprefix) + @property = @project.account(@accountprefix) end if @val[1] && @project.account(@val[1]) error('account_exists', "Account #{@val[1]} has already been defined.", @@ -239,7 +239,7 @@ inherited allocations or flags. For effort-based tasks the task duration is clipped to only extend from the -begining of the first allocation to the end of the last allocation. This is +beginning of the first allocation to the end of the last allocation. This is done to optimize for an overall minimum project duration as dependent tasks can potentially use the unallocated, clipped slots. EOT @@ -287,7 +287,7 @@ @allocate.setSelectionMode(@val[1]) }) doc('select', <<'EOT' -The select functions controls which resource is picked from an allocation and +The select function controls which resource is picked from an allocation and it's alternatives. The selection is re-evaluated each time the resource used in the previous time slot becomes unavailable. @@ -301,7 +301,7 @@ @allocate.persistent = true }) doc('persistent', <<'EOT' -Specifies that once a resource is picked from the list of alternatives this +Specifies that once a resource is picked from the list of alternatives, this resource is used for the whole task. This is useful when several alternative resources have been specified. Normally the selected resource can change after each break. A break is an interval of at least one timeslot where no resources @@ -389,7 +389,7 @@ descr(<<'EOT' Pick the resource that has the smallest allocation factor. The allocation factor is calculated from the various allocations of the resource -across the tasks. This is the default setting.) +across the tasks. This is the default setting. EOT ) @@ -748,7 +748,7 @@ Normally, columns with calculated values take the specified report period into account when calculating their values. With this attribute, the user can specify an end date for the period that should be used when calculating the -values of this column. It does not have an impact on column with time +values of this column. It does not have an impact on columns with time invariant values. EOT ) @@ -781,7 +781,7 @@ @column.listItem = @val[1] }) doc('listitem.column', <<'EOT' -Specifies a RichText pattern that is used to generate the text for the list +Specifies a [[Rich_Text_Attributes|Rich Text]] pattern that is used to generate the text for the list items. The pattern should contain at least one ''''<-query attribute='XXX'->'''' element that will be replaced with the value of attribute XXX. For the replacement, the property of the query will be the list @@ -824,7 +824,7 @@ Normally, columns with calculated values take the specified report period into account when calculating their values. With this attribute, the user can specify a start date for the period that should be used when calculating the -values of this column. It does not have an impact on column with time +values of this column. It does not have an impact on columns with time invariant values. EOT ) @@ -930,19 +930,19 @@ ''''+HHMM'''' or ''''-HHMM''''. Dates must always be aligned with the [[timingresolution]]. -TaskJuggler also supports simple date calculations. You can add or substract a +TaskJuggler also supports simple date calculations. You can add or subtract a given interval from a fixed date. %{2009-11-01 + 8m} -This will result in an actual date of around 2009-07-01. Keep in mind that due +This will result in an actual date of around 2010-07-01. Keep in mind that due to the varying lengths of months TaskJuggler cannot add exactly 8 calendar months. The date calculation functionality makes most sense when used with macros. %{${now} - 2w} -This is result in a date 2 weeks earlier than the current (or specified) date. +This results in a date 2 weeks earlier than the current (or specified) date. See [[duration]] for a complete list of supported time intervals. Don't forget to put at least one space character after the date to prevent TaskJuggler from interpreting the interval as an hour. @@ -1065,11 +1065,11 @@ @property.set('definitions', @val[1]) }) doc('definitions', <<"EOT" -This attributes controls what definitions will be contained in the report. If +This attribute controls what definitions will be contained in the report. If the list includes ''project'', the generated file will have a ''''.tjp'''' extension. Otherwise it will have a ''''.tji'''' extension. -By default, the report contains everything and the generated files has a ''''.tjp'''' extension. +By default, the report contains everything and the generated files have a ''''.tjp'''' extension. EOT ) allOrNothingListRule('exportDefinitions', @@ -1188,13 +1188,13 @@ descr(<<'EOT' Export of the scheduled project in Microsoft Project XML format. This will export the data of the fully scheduled project. The exported data include the -tasks, resources and the assignments of resources to task. This is only a +tasks, resources and the assignments of resources to tasks. This is only a small subset of the data that TaskJuggler can manage. This export is intended to share resource assignment data with other teams using Microsoft Project. -TaskJuggler manages assignments with a larger accuracy than the Microsft +TaskJuggler manages assignments with a larger accuracy than the Microsoft Project XML format can represent. This will inevitably lead to some rounding errors and different interpretation of the data. The numbers you will see in -Project are not necessarily an exact match of the numbers you see in +Microsoft Project are not necessarily an exact match of the numbers you see in TaskJuggler. The XML file format requires the sequence of the tasks in the file to follow the work breakdown structure. Hence all user provided sorting directions will be ignored for this format. @@ -1385,7 +1385,7 @@ singlePattern('_inherit') doc('inherit.extend', <<'EOT' -If the this attribute is used, the property extension will be inherited by +If this attribute is used, the property extension will be inherited by child properties from their parent property. EOT ) @@ -1457,7 +1457,7 @@ operations. The final result of a logical expression is always true or false. Logical expressions are used the reduce the properties in a report to a certain subset or to select alternatives for the cell content of a table. When -used with attributes like [[hidejournalentry]] the logical expression +the logical expression is used with attributes like [[hidejournalentry]] and evaluates to true for a certain property, this property is hidden or rolled-up in the report. @@ -1507,7 +1507,7 @@ }) arg(0, 'operand', <<'EOT' An operand is a declared flag. An operand can be a negated operand by -prefixing a ~ charater or it can be another logical expression enclosed in +prefixing a ~ character or it can be another logical expression enclosed in braces. EOT ) @@ -1527,7 +1527,7 @@ }) arg(1, 'operand', <<'EOT' An operand is a declared flag. An operand can be a negated operand by -prefixing a ~ charater or it can be another logical expression enclosed in +prefixing a ~ character or it can be another logical expression enclosed in braces. EOT ) @@ -1582,18 +1582,18 @@ All functions may operate on the current property and the scope property. The scope property is the enclosing property in reports with nested properties. -Imagine e. g a task report with nested resources. When the function is called +Imagine e. g. a task report with nested resources. When the function is called for a task line, the task is the property and we don't have a scope property. When the function is called for a resource line, the resource is the property and the enclosing task is the scope property. -These number of arguments that are passed in brackets to the function depends +The number of arguments that are passed in brackets to the function depends on the specific function. See the reference for details on each function. All functions can be suffixed with an underscore character. In that case, the function is operating on the scope property as if it were the property. The original property is ignored in that case. In our task report example from -above, calling a function with an appended dash would mean that a task +above, calling a function with an appended underscore would mean that a task line would be evaluated for the enclosing resource. In the example below you can see how this can be used. To generate a task @@ -1684,7 +1684,7 @@ pattern(%w( _isongoing _( $ID _) )) doc('isongoing', <<'EOT' -Will evaluate to true for tasks that overlap with the report period in given +Will evaluate to true for tasks that overlap with the report period in the given scenario. EOT ) @@ -1825,6 +1825,11 @@ pattern(%w( !reportStart )) pattern(%w( !rollupresource )) pattern(%w( !rolluptask )) + pattern(%w( _novevents), lambda { @property.set('novevents', [ true ]) }) + doc('novevents', <<'EOT' +Don't add VEVENT entries to generated [[icalreport]]s. +EOT + ) pattern(%w( _scenario !scenarioId ), lambda { # Don't include disabled scenarios in the report @@ -1837,8 +1842,8 @@ end }) doc('scenario.ical', <<'EOT' -Id of the scenario that should be included in the report. By default, the -top-level scenario will be included. This attribute can be used select another +ID of the scenario that should be included in the report. By default, the +top-level scenario will be included. This attribute can be used to select another scenario. EOT ) @@ -1863,6 +1868,8 @@ # Show all journal entries. @property.set('hideJournalEntry', LogicalExpression.new(LogicalOperation.new(0))) + # Add VEVENT entries to icalreports by default + @property.set('novevents', [ false ]) end }) arg(1, 'file name', <<'EOT' @@ -2021,7 +2028,7 @@ end date without a time is expanded to midnight that day. So the day of the end date is not included in the interval! The start and end dates must be separated by a hyphen character. -In the second form specifies the start date and an interval duration. The +The second form specifies the start date and an interval duration. The duration must be prefixed by a plus character. EOT ) @@ -2161,7 +2168,7 @@ pattern(%w( _alerts_dep ), lambda { :alerts_dep }) descr(<<'EOT' In this mode only the last entries before the report end date for the context -property and all its sub-properties and their dependencies is included. If +property and all its sub-properties and their dependencies are included. If there are multiple entries at the exact same date, then all these entries are included. In contrast to the ''''status_down'''' mode, only entries with an alert level above the default level, and only those with the highest overall @@ -2190,7 +2197,7 @@ during the project. Depending on the context, a journal entry may or may not be associated with a specific property or author. -A journal entry can consists of up to three parts. The headline is mandatory +A journal entry can consist of up to three parts. The headline is mandatory and should be only 5 to 10 words long. The introduction is optional and should be only one or two sentences long. All other details should be put into the third part. @@ -2209,7 +2216,7 @@ @journalEntry.alertLevel = @val[1] }) doc('alert', <<'EOT' -Specify the alert level for this entry. This attribute is inteded to be used for +Specify the alert level for this entry. This attribute is intended to be used for status reporting. When used for a journal entry that is associated with a property, the value can be reported in the alert column. When multiple entries have been specified for the property, the entry with the date closest to the @@ -2330,7 +2337,7 @@ used to report the current annual leave balance. Leaves outside of the project period are silently ignored and will not be -considered in the leave balance calculation. Therefor, leave allowances are +considered in the leave balance calculation. Therefore, leave allowances are only allowed within the project period. EOT ) @@ -2352,7 +2359,7 @@ and intervals may overlap. The leave types have different priorities. A higher priority leave type can overwrite a lower priority type. This means that resource level leaves can overwrite global leaves when they have a higher -priority. A sub resource can overwrite a leave of a enclosing resource. +priority. A sub resource can overwrite a leave of an enclosing resource. Leave periods outside of the project interval are silently ignored. For leave periods that are partially outside of the project period only the part inside @@ -2469,7 +2476,7 @@ doc('dailymin', <<'EOT' Minimum required effort for any calendar day. This value cannot be guaranteed by the scheduler. It is only checked after the schedule is complete. In case the -minium required amount has not been reached, a warning will be generated. +minimum required amount has not been reached, a warning will be generated. EOT ) example('Limits-1', '4') @@ -2506,7 +2513,7 @@ doc('monthlymin', <<'EOT' Minimum required effort for any calendar month. This value cannot be guaranteed by the scheduler. It is only checked after the schedule is -complete. In case the minium required amount has not been reached, a warning +complete. In case the minimum required amount has not been reached, a warning will be generated. EOT ) @@ -2525,7 +2532,7 @@ doc('weeklymin', <<'EOT' Minimum required effort for any calendar week. This value cannot be guaranteed by the scheduler. It is only checked after the schedule is complete. In case the -minium required amount has not been reached, a warning will be generated. +minimum required amount has not been reached, a warning will be generated. EOT ) end @@ -2632,8 +2639,8 @@ A logical expression is a combination of operands and mathematical operations. The final result of a logical expression is always true or false. Logical expressions are used the reduce the properties in a report to a certain subset -or to select alternatives for the cell content of a table. When used with -attributes like [[hidetask]] or [[hideresource]] the logical expression +or to select alternatives for the cell content of a table. When the +logical expression is used with attributes like [[hidetask]] or [[hideresource]] and evaluates to true for a certain property, this property is hidden or rolled-up in the report. @@ -2655,7 +2662,7 @@ the validity first. E. g. to compare the end date of the ''''plan'''' scenario with the ''''maxend'''' value use ''''isvalid(plan.maxend) & (plan.end > plan.maxend)''''. The ''''&'''' and ''''|'''' operators are lazy. -If the result is already known after evaluation the first operand, the second +If the result is already known after evaluation of the first operand, the second operand will not be evaluated any more. EOT ) @@ -2690,9 +2697,9 @@ will expand to ''''This stupid text'''' if called as ''''${FOO "stupid"}''''. Macros may call other macros. All macro arguments must be enclosed by double quotes. In case the argument contains a double quote, it must be escaped by a -slash (''''/''''). +backslash (''''\''''). -User defined macro IDs must have at least one uppercase letter as all +User defined macro IDs should start with one uppercase letter as all lowercase letter IDs are reserved for built-in macros. To terminate the macro definition, the '''']'''' must be the @@ -3018,7 +3025,7 @@ of list attributes is not recommended. User defined attributes are available as well. -An operand can be a negated operand by prefixing a ~ charater or it can be +An operand can be a negated operand by prefixing a ~ character or it can be another logical expression enclosed in braces. EOT ) @@ -3037,7 +3044,7 @@ [ @val[0], @val[1] ] }) arg(1, 'operand', <<'EOT' -An operand can consist of a date, a text string or a numerical value. It can also be the name of a declared flag. Finally, an operand can be a negated operand by prefixing a ~ charater or it can be another operation enclosed in braces. +An operand can consist of a date, a text string or a numerical value. It can also be the name of a declared flag. Finally, an operand can be a negated operand by prefixing a ~ character or it can be another operation enclosed in braces. EOT ) end @@ -3075,7 +3082,7 @@ }) arg(0, 'id', <<"EOT" An optional ID. If you ever want to reference this property, you must specify -your own unique ID. If no ID is specified one will be automatically generated. +your own unique ID. If no ID is specified, one will be automatically generated. These IDs may become visible in reports, but may change at any time. You may never rely on automatically generated IDs. EOT @@ -3140,7 +3147,7 @@ pattern(%w( _niku ), lambda { :niku }) - descr('Generate a XOG XML file to be used with Clarity.') + descr('Generate an XOG XML file to be used with Clarity.') end def rule_outputFormats @@ -3238,7 +3245,7 @@ doc('extend', <<'EOT' Often it is desirable to collect more information in the project file than is necessary for task scheduling and resource allocation. To add such information -to tasks, resources or accounts the user can extend these properties with +to tasks, resources or accounts, the user can extend these properties with user-defined attributes. The new attributes can be of various types such as text, date or reference to capture various types of data. Optionally the user can specify if the attribute value should be inherited from the enclosing @@ -3267,6 +3274,21 @@ arg(1, 'date', 'Alternative date to be used as current date for all ' + 'computations') + pattern(%w( _markdate !date ), lambda { + @project['markdate'] = @val[1] + @scanner.addMacro(TextParser::Macro.new('markdate', @val[1].to_s, + @sourceFileInfo[0])) + @scanner.addMacro(TextParser::Macro.new( + 'today', @val[1].to_s(@project['timeFormat']), @sourceFileInfo[0])) + }) + doc('markdate', <<'EOT' +Specify the reference date that TaskJuggler uses as date that can be specified +and set by the user. It can be used as additional point in time to help with +tracking tasks. If no value is specified, the current value of the system clock is used. +EOT + ) + arg(1, 'date', 'Alternative date to be used as custom date specified by the user') + pattern(%w( !numberFormat ), lambda { @project['numberFormat'] = @val[0] }) @@ -3285,8 +3307,8 @@ }) doc('outputdir', 'Specifies the directory into which the reports should be generated. ' + - 'This will not affect reports whos name start with a slash. This ' + - 'setting can be overwritten by the command line option.') + 'This will not affect reports whose name start with a slash. This ' + + 'setting can be overwritten by the command line option -o or --output-dir.') arg(1, 'directory', 'Path to an existing directory') pattern(%w( !scenario )) @@ -3294,8 +3316,8 @@ @project['shortTimeFormat'] = @val[1] }) doc('shorttimeformat', - 'Specifies time format for time short specifications. This is normal' + - 'just the hour and minutes.') + 'Specifies time format for short time specifications. This is normal ' + + 'just hours and minutes.') arg(1, 'format', 'strftime like format string') pattern(%w( !timeformat ), lambda { @@ -3352,7 +3374,7 @@ tracking scenario and may not have any bookings of their own. The tracking scenario must also be specified to use time and status sheet reports. -The tracking scenario must be defined after all scenario have been defined. +The tracking scenario must be defined after all scenarios have been defined. The tracking scenario and all scenarios derived from it will be scheduled in projection mode. This means that the scheduler will only add bookings after @@ -3472,7 +3494,7 @@ # documentation. pattern(%w( !projectPropertiesBody )) doc('properties', <<'EOT' -The project properties. Every project must consists of at least one task. The other properties are optional. To save the scheduled data at least one output generating property should be used. +The project properties. Every project must consist of at least one task. The other properties are optional. To save the scheduled data at least one output generating property should be used. EOT ) end @@ -3489,7 +3511,7 @@ doc('include.project', <<'EOT' Includes the specified file name as if its contents would be written instead of the include property. When the included files contains other -include statements or report definitions, the filenames are relative to file +include statements or report definitions, the filenames are relative to the file where they are defined in. This version of the include directive may only be used inside the [[project]] @@ -3506,7 +3528,7 @@ Includes the specified file name as if its contents would be written instead of the include property. The only exception is the include statement itself. When the included files contains other include -statements or report definitions, the filenames are relative to file +statements or report definitions, the filenames are relative to the file where they are defined in. The included file may only contain macro definitions. This version of the @@ -3667,7 +3689,7 @@ Includes the specified file name as if its contents would be written instead of the include property. The only exception is the include statement itself. When the included files contains other include -statements or report definitions, the filenames are relative to file +statements or report definitions, the filenames are relative to the file where they are defined in. include commands can be used in the project header, at global scope or between property declarations of tasks, resources, and accounts. @@ -3689,13 +3711,11 @@ end if attributeDefinition.scenarioSpecific @scenarioIdx = 0 unless @val[1] - attr = @property[attrId, 0] else if @val[1] error('purge_non_sc_spec_attr', 'Scenario specified for a non-scenario specific attribute') end - attr = @property.get(attrId) end if @property.attributeDefinition(attrId).scenarioSpecific @property.getAttribute(attrId, @scenarioIdx).reset @@ -3779,6 +3799,13 @@ EOT ) + singlePattern('_annualleavelist') + descr(<<'EOT' +A list with all annual leave intervals. The list can be customized with the +[[listtype.column|listtype]] attribute. +EOT + ) + singlePattern('_alert') descr(<<'EOT' The alert level of the property that was reported with the date closest to the @@ -3802,7 +3829,7 @@ singlePattern('_alerttrend') descr(<<'EOT' Shows how the alert level at the end of the report period compares to the -alert level at the begining of the report period. Possible values are +alert level at the beginning of the report period. Possible values are ''''Up'''', ''''Down'''' or ''''Flat''''. EOT ) @@ -3839,7 +3866,7 @@ singlePattern('_closedtasks') descr(<<'EOT' The number of sub-tasks (including the current task) that have been closed -during the reported time period. Closed means that they have and end date +during the reported time period. Closed means that they have an end date before the current time or [[now]] date. EOT ) @@ -3860,12 +3887,12 @@ singlePattern('_complete') descr(<<'EOT' The completion degree of a task. Unless a completion degree is manually -provided, this is a computed value relative the [[now]] date of the project. A +provided, this is a computed value relative to the [[now]] date of the project. A task that has ended before the now date is always 100% complete. A task that -starts at or after the now date is always 0%. For [[effort]] based task the +starts at or after the now date is always 0%. For [[effort]] based tasks the computation degree is the percentage of done effort of the overall effort. For -other leaf task, the completion degree is the percentage of the already passed -duration of the overall task duration. For container task, it's always the +other leaf tasks, the completion degree is the percentage of the already passed +duration of the overall task duration. For container tasks, it's always the average of the direct sub tasks. If the sub tasks consist of a mixture of effort and non-effort tasks, the completion value is only of limited value. EOT @@ -3879,8 +3906,8 @@ descr('Deprecated alias for complete') singlePattern('_criticalness') - descr('A measure for how much effort the resource is allocated for, or' + - 'how strained the allocated resources of a task are') + descr('A measure for how much effort the resource is allocated for, or ' + + 'how strained the allocated resources of a task are.') singlePattern('_cost') descr(<<'EOT' @@ -3932,7 +3959,7 @@ descr(<<'EOT' A list of tasks that depend on the current task. The list contains the names, the IDs, the date and the type of dependency. For the type the following -symbols are used for . +symbols are used for : * ''']->[''': End-to-Start dependency * '''[->[''': Start-to-Start dependency @@ -3941,7 +3968,7 @@ The list can be customized by the [[listitem.column|listitem]] and [[listtype.column]] attributes. The dependency symbol can be generated via -the ''''dependency'''' attribute inthe query, the target date via the +the ''''dependency'''' attribute in the query, the target date via the ''''date'''' attribute. EOT ) @@ -4019,7 +4046,7 @@ singlePattern('_journal') descr(<<'EOT' The journal entries for the task or resource for the reported interval. The -generated text can be customized with the [[journalmode]], +generated text can be customized with [[journalmode]], [[journalattributes]], [[hidejournalentry]] and [[sortjournalentries]]. If used in queries without a property context, the journal for the complete project is generated. @@ -4080,7 +4107,7 @@ singlePattern('_opentasks') descr(<<'EOT' The number of sub-tasks (including the current task) that have not yet been -closed during the reported time period. Closed means that they have and end +closed during the reported time period. Closed means that they have an end date before the current time or [[now]] date. EOT ) @@ -4102,7 +4129,7 @@ The list can be customized by the [[listitem.column|listitem]] and [[listtype.column|listtype]] attributes. The dependency symbol can be -generated via the ''''dependency'''' attribute inthe query, the target date +generated via the ''''dependency'''' attribute in the query, the target date via the ''''date'''' attribute. EOT ) @@ -4364,7 +4391,7 @@ }) doc('height', <<'EOT' Set the height of the report in pixels. This attribute is only used for -reports that cannot determine the height based on the content. Such report can +reports that cannot determine the height based on the content. Such reports can be freely resized to fit in. The vast majority of reports can determine their height based on the provided content. These reports will simply ignore this setting. @@ -4421,7 +4448,7 @@ @property.set('rawHtmlHead', @val[1]) }) doc('rawhtmlhead', <<'EOT' -Define a HTML fragment that will be inserted at the end of the HTML head +Define an HTML fragment that will be inserted at the end of the HTML head section. EOT ) @@ -4485,7 +4512,7 @@ doc('resourceroot', <<'EOT' Only resources below the specified root-level resources are exported. The exported resources will have the ID of the root-level resource stripped from -their ID, so that the sub-resourcess of the root-level resource become +their ID, so that the sub-resources of the root-level resource become top-level resources in the report file. EOT ) @@ -4534,7 +4561,7 @@ }) doc('width', <<'EOT' Set the width of the report in pixels. This attribute is only used for -reports that cannot determine the width based on the content. Such report can +reports that cannot determine the width based on the content. Such reports can be freely resized to fit in. The vast majority of reports can determine their width based on the provided content. These reports will simply ignore this setting. @@ -4796,9 +4823,9 @@ }) doc('resourcereport', <<'EOT' The report lists resources and their respective values in a table. The task -that are the resources are allocated to can be listed as well. To reduce the +that the resources are allocated to can be listed as well. To reduce the list of included resources, you can use the [[hideresource]], -[[rollupresource]] or [[resourceroot]] attributes. The order of the task can +[[rollupresource]] or [[resourceroot]] attributes. The order of the tasks can be controlled with [[sortresources]]. If the first sorting criteria is tree sorting, the parent resources will always be included to form the tree. Tree sorting is the default. You need to change it if you do not want certain @@ -4857,7 +4884,7 @@ efficiency of 5.0. Keep in mind that you cannot track the members of the team individually if you use this feature. They always act as a group. -The other use is to model performance variations between your resources. Again, this is a fairly crude mechanism and should be used with care. A resource that isn't every good at some task might be pretty good at another. This can't be taken into account as the resource efficiency can only set globally for all tasks. +The other use is to model performance variations between your resources. Again, this is a fairly crude mechanism and should be used with care. A resource that isn't very good at some task might be pretty good at another. This can't be taken into account as the resource efficiency can only be set globally for all tasks. All resources that do not contribute effort to the task, should have an efficiency of 0.0. A typical example would be a conference room. It's necessary for a meeting, but it does not contribute any work. @@ -4874,7 +4901,7 @@ pattern(%w( _booking !resourceBooking )) doc('booking.resource', <<'EOT' The booking attribute can be used to report actually completed work. A task -with bookings must be [[scheduling|scheduled]] in ''''asap'''' mode. If the +with bookings must be [[scheduling|scheduled]] in ''''ASAP'''' mode. If the scenario is not the [[trackingscenario|tracking scenario]] or derived from it, the scheduler will not allocate resources prior to the current date or the date specified with [[now]] when a task has at least one booking. @@ -4960,7 +4987,7 @@ @shiftAssignments = nil }) level(:deprecated) - also('shift.resource') + also('shifts.resource') doc('shift.resource', <<'EOT' This keyword has been deprecated. Please use [[shifts.resource|shifts (resource)]] instead. @@ -5070,10 +5097,10 @@ scenarios. A nested scenario uses all attributes from the enclosing scenario unless the user has specified a different value for this attribute. -By default, the scheduler assigns resources to task beginning with the project +By default, the scheduler assigns resources to tasks beginning with the project start date. If the scenario is switched to projection mode, no assignments will be made prior to the current date or the date specified by [[now]]. In -this case, TaskJuggler assumes, that all assignements prior to the +this case, TaskJuggler assumes, that all assignments prior to the current date have been provided by [[booking.task]] statements. EOT ) @@ -5088,7 +5115,7 @@ }) doc('active', <<'EOT' Enable the scenario to be scheduled or not. By default, all scenarios will be -scheduled. If a scenario is marked as inactive, it not be scheduled and will +scheduled. If a scenario is marked as inactive, it cannot be scheduled and will be ignored in the reports. EOT ) @@ -5703,7 +5730,7 @@ @property = @propertyStack.pop }) doc('task.statussheet', <<'EOT' -Opens the task with the specified ID to add a status report. Child task can be +Opens the task with the specified ID to add a status report. Child tasks can be opened inside this context by specifying their relative ID to this parent. EOT ) @@ -6043,7 +6070,7 @@ ) singlePattern('$ID') - arg(0, 'ID', 'Just the ID of the task without and parent IDs.') + arg(0, 'ID', 'Just the ID of the task without any parent IDs.') pattern(%w( !relativeId ), lambda { task = @property @@ -6159,7 +6186,7 @@ doc('taskreport', <<'EOT' The report lists tasks and their respective values in a table. To reduce the list of included tasks, you can use the [[hidetask]], [[rolluptask]] or -[[taskroot]] attributes. The order of the task can be controlled with +[[taskroot]] attributes. The order of the tasks can be controlled with [[sorttasks]]. If the first sorting criteria is tree sorting, the parent tasks will always be included to form the tree. Tree sorting is the default. You need to change it if you do not want certain parent tasks to be included in @@ -6218,7 +6245,7 @@ pattern(%w( _booking !taskBooking )) doc('booking.task', <<'EOT' The booking attribute can be used to report actually completed work. A task -with bookings must be [[scheduling|scheduled]] in ''''asap'''' mode. If the +with bookings must be [[scheduling|scheduled]] in ''''ASAP'''' mode. If the scenario is not the [[trackingscenario|tracking scenario]] or derived from it, the scheduler will not allocate resources prior to the current date or the date specified with [[now]] when a task has at least one booking. @@ -6321,7 +6348,7 @@ finished. By using the 'depends' attribute, the scheduling policy is automatically set -to asap. If both depends and precedes are used, the last policy counts. +to ASAP. If both depends and precedes are used, the last policy counts. EOT ) example('Depends1') @@ -6418,10 +6445,10 @@ The end attribute provides a guideline to the scheduler when the task should end. It will never end later, but it may end earlier when allocated resources are not available that long. When an end date is provided for a -container task, it will be passed down to ALAP task that don't have a well +container task, it will be passed down to ALAP tasks that don't have a well defined end criteria. -Setting an end date will implicitely set the scheduling policy for this task +Setting an end date will implicitly set the scheduling policy for this task to ALAP. EOT ) @@ -6434,7 +6461,7 @@ level(:deprecated) doc('endcredit', <<'EOT' Specifies an amount that is credited to the accounts specified by the -[[chargeset]] attributes at the moment the tasks ends. +[[chargeset]] attributes at the moment the task ends. EOT ) also('charge') @@ -6466,7 +6493,7 @@ For the length calculation, the global working hours and the global leaves matter unless the task has [[shifts.task|shifts]] assigned. In the latter case the working hours and leaves of the shift apply for the specified period to -determine if a slot is working time or not. If a resource has additinal +determine if a slot is working time or not. If a resource has additional working hours defined, it's quite possible that a task with a length of 5d will have an allocated effort larger than 40 hours. Resource working hours only have an impact on whether an allocation is made or not for a particular @@ -6514,7 +6541,7 @@ }) doc('milestone', <<'EOT' Turns the task into a special task that has no duration. You may not specify a -duration, length, effort or subtasks for a milestone task. +duration, length, effort or subtask for a milestone task. A task that only has a start or an end specification and no duration specification, inherited start or end dates, no dependencies or sub tasks, @@ -6551,7 +6578,7 @@ level(:deprecated) doc('startcredit', <<'EOT' Specifies an amount that is credited to the account specified by the -[[chargeset]] attributes at the moment the tasks starts. +[[chargeset]] attributes at the moment the task starts. EOT ) also('charge') @@ -6566,14 +6593,14 @@ end }) doc('precedes', <<'EOT' -Specifies that the tasks with the specified IDs cannot start before the task +Specifies that the tasks with the specified IDs cannot start before this task has been finished. If multiple IDs are specified, they must be separated by commas. IDs must be either global or relative. A relative ID starts with a number of '!'. Each '!' moves the scope to the parent task. Global IDs do not contain '!', but have IDs separated by dots. By using the 'precedes' attribute, the scheduling policy is automatically set -to alap. If both depends and precedes are used within a task, the last policy +to ALAP. If both depends and precedes are used within a task, the last policy counts. EOT ) @@ -6589,13 +6616,13 @@ Specifies the priority of the task. A task with higher priority is more likely to get the requested resources. The default priority value of all tasks is 500. Don't confuse the priority of a tasks with the importance or urgency -of a task. It only increases the chances that the tasks gets the requested +of a task. It only increases the chances that the task gets the requested resources. It does not mean that the task happens earlier, though that is usually the effect you will see. It also does not have any effect on tasks that don't have any resources assigned (e.g. milestones). -For milestones it will raise or lower the chances that task leading up the -milestone will get their resources over task with equal priority that compete +For milestones, it will raise or lower the chances that tasks leading up the +milestone will get their resources over tasks with equal priority that compete for the same resources. This attribute is inherited by subtasks if specified prior to the definition @@ -6613,12 +6640,12 @@ begin @property['projectid', @scenarioIdx] = @val[1] rescue AttributeOverwrite - # This attribute always overwrites the implicitely provided ID. + # This attribute always overwrites the implicitly provided ID. end }) doc('projectid.task', <<'EOT' -In larger projects it may be desireable to work with different project IDs for -parts of the project. This attribute assignes a new project ID to this task an +In larger projects it may be desirable to work with different project IDs for +parts of the project. This attribute assignes a new project ID to this task and all subsequently defined sub tasks. The project ID needs to be declared first using [[projectid]] or [[projectids]]. EOT ) @@ -6662,8 +6689,8 @@ }) doc('scheduling', <<'EOT' Specifies the scheduling policy for the task. A task can be scheduled from -start to end (As Soon As Possible, asap) or from end to start (As Late As -Possible, alap). +start to end (As Soon As Possible, ASAP) or from end to start (As Late As +Possible, ALAP). A task can be scheduled from start to end (ASAP mode) when it has a hard (start) or soft (depends) criteria for the start time. A task can be scheduled @@ -6672,21 +6699,21 @@ Some task attributes set the scheduling policy implicitly. This attribute can be used to explicitly set the scheduling policy of the task to a certain -direction. To avoid it being overwritten again by an implicit attribute this +direction. To avoid it being overwritten again by an implicit attribute, this attribute should always be the last attribute of the task. A random mixture of ASAP and ALAP tasks can have unexpected side effects on the scheduling of the project. It increases significantly the scheduling complexity and results in much longer scheduling times. Especially in projects -with many hundreds of tasks the scheduling time of a project with a mixture of -ASAP and ALAP times can be 2 to 10 times longer. When the projects contains -chains of ALAP and ASAP tasks the tasks further down the dependency chain will -be served much later than other non-chained task even when they have a much +with many hundreds of tasks, the scheduling time of a project with a mixture of +ASAP and ALAP times can be 2 to 10 times longer. When the project contains +chains of ALAP and ASAP tasks, the tasks further down the dependency chain will +be served much later than other non-chained tasks, even when they have a much higher priority. This can result in situations where high priority tasks do -not get their resources even though the parallel competing tasks have a much +not get their resources, even though the parallel competing tasks have a much lower priority. -ALAP tasks may not have [[booking.task|bookings]] since the first booked slot +ALAP tasks may not have [[booking.task|bookings]], since the first booked slot determines the start date of the task and prevents it from being scheduled from end to start. @@ -6745,7 +6772,7 @@ Limits the working time for this task during the specified interval to the working hours of the given shift. Multiple shifts can be defined, but shift intervals may not overlap. This is an additional working time -restriction ontop of the working hours of the allocated resources. It does not +restriction on top of the working hours of the allocated resources. It does not replace the resource working hour restrictions. For a resource to be assigned to a time slot, both the respective task shift as well as the resource working hours must declare the time slot as duty slot. @@ -6763,10 +6790,10 @@ The start attribute provides a guideline to the scheduler when the task should start. It will never start earlier, but it may start later when allocated resources are not available immediately. When a start date is provided for a -container task, it will be passed down to ASAP task that don't have a well +container task, it will be passed down to ASAP tasks that don't have a well defined start criteria. -Setting a start date will implicitely set the scheduling policy for this task +Setting a start date will implicitly set the scheduling policy for this task to ASAP. EOT ) @@ -6794,7 +6821,7 @@ @property = @property.parent }) doc('textreport', <<'EOT' -This report consists of 5 RichText sections, a header, a center section with a +This report consists of 5 [[Rich_Text_Attributes|Rich Text]] sections, a header, a center section with a left and right margin and a footer. The sections may contain the output of other defined reports. EOT @@ -6819,7 +6846,7 @@ arg(1, 'format', <<'EOT' Ordinary characters placed in the format string are copied without conversion. Conversion specifiers are introduced by a `%' character, and are -replaced in s as follows: +replaced as follows: * ''''%a'''' The abbreviated weekday name according to the current locale. @@ -6979,7 +7006,7 @@ The intended use for time sheets is to have all resources report a time sheet every day, week or month. All time sheets can be added to the project plan. -The status information is always used to determin the current status of the +The status information is always used to determine the current status of the project. The [[work]], [[remaining]] and [[end.timesheet|end]] attributes are ignored if there are also [[booking.task|bookings]] for the resource in the time sheet period. The non-ignored attributes of the time sheets will be @@ -7014,7 +7041,7 @@ }) doc('newtask', <<'EOT' The keyword can be used to request a new task to the project. If the task ID -requires further parent task that don't exist yet, these tasks will be +requires further parent tasks that don't exist yet, these tasks will be requested as well. If the task exists already, an error will be generated. The newly requested task can be used immediately to report progress and status against it. These tasks will not automatically be added to the project plan. @@ -7148,14 +7175,14 @@ that are not hidden by [[hideaccount]], [[hideresource]] and [[hidetask]]. By default, all properties are excluded. You must provide at least one of the ''''hide...'''' attributes to select the properties you want to have included -in the report. Please be aware that total number of columns is the product of +in the report. Please be aware that the total number of columns is the product of attributes defined with [[columns]] times the number of included properties. -Select you values carefully or you will end up with very large reports. +Select your values carefully or you will end up with very large reports. The column headers can be customized by using the [[title.column|title]] attribute. When you include multiple properties, these headers are not unique -unless you include mini-queries to modify them based on the property they -colum is represeting. You can use the queries +unless you include mini-queries to modify them based on the property the +column is representing. You can use the queries ''''<-id->'''', ''''<-name->'''', ''''<-scenario->'''' and ''''<-attribute->''''. ''''<-id->'''' is @@ -7170,12 +7197,12 @@ all kinds of values that are being tracked. Report formats that don't support a mix of different values will just show the values of the second column. -The values in the CSV files are fixed units and cannot be formated. Effort +The values in the CSV files are fixed units and cannot be formatted. Effort values are always in resource-days. This allows other software to interpret the file without any need for additional context information. The HTML version generates SVG graphs that are embedded in the HTML page. -These graphs are only visble if the web browser supports HTML5. This is true +These graphs are only visible if the web browser supports HTML5. This is true for the latest generation of browsers, but older browsers may not support this format. EOT @@ -7187,7 +7214,7 @@ pattern(%w( _tracereport !optionalID !reportName ), lambda { newReport(@val[1], @val[2], :tracereport, @sourceFileInfo[0]) do # The top-level always inherits the global timeFormat setting. This is - # not desireable in this case, so we ignore this. + # not desirable in this case, so we ignore this. if (@property.level == 0 && !@property.provided('timeFormat')) || (@property.level > 0 && !@property.modified?('timeFormat')) # CSV readers such of Libre-/OpenOffice can't deal with time zones. We @@ -7370,7 +7397,7 @@ }) doc('end.timesheet', <<'EOT' The expected end date for the task. This can only be used for duration based -task. For effort based task [[remaining]] has to be used. +tasks. For effort based tasks [[remaining]] has to be used. EOT ) example('TimeSheet1', '5') @@ -7386,7 +7413,7 @@ }) doc('priority.timesheet', <<'EOT' The priority is a value between 1 and 1000. It is used to determine the -sequence of task when converting [[work]] to [[booking.task|bookings]]. Tasks +sequence of tasks when converting [[work]] to [[booking.task|bookings]]. Tasks that need to finish earlier in the period should have a high priority, tasks that end later in the period should have a low priority. For tasks that don't get finished in the reported period the priority should be set to 1. @@ -7400,7 +7427,7 @@ The remaining effort for the task. This value is ignored if there are [[booking.task|bookings]] for the resource that overlap with the time sheet period. If there are no bookings, the value is compared with the [[effort]] -specification of the task. If there a mismatch between the accumulated effort +specification of the task. If there is a mismatch between the accumulated effort specified with bookings, [[work]] and [[remaining]] on one side and the specified [[effort]] on the other, a warning is generated. @@ -7416,7 +7443,7 @@ @timeSheetRecord.work = @val[1] }) doc('work', <<'EOT' -The amount of time that the resource has spend with the task during the +The amount of time that the resource has spent with the task during the reported period. This value is ignored when there are [[booking.task|bookings]] for the resource overlapping with the time sheet period. If there are no bookings, TaskJuggler will try to convert the work @@ -7552,7 +7579,7 @@ midnight that day. So the day of the end date is not included in the interval! The start and end dates must be separated by a hyphen character. -In the second form specifies the start date and an interval duration. The +The second form specifies the start date and an interval duration. The duration must be prefixed by a plus character. EOT ) @@ -7572,7 +7599,7 @@ doc('warn', <<'EOT' The warn attribute adds a [[logicalexpression|logical expression]] to the property. The condition described by the logical expression is checked after -the scheduling and an warning is generated if the condition evaluates to true. +the scheduling and a warning is generated if the condition evaluates to true. This attribute is primarily intended for testing purposes. EOT ) @@ -7708,7 +7735,7 @@ pattern(%w( !workinghours )) doc('workinghours.project', <<'EOT' Set the default working hours for all subsequent resource definitions. The -standard working hours are 9:00am - 12:00am, 1:00pm - 18:00pm, Monday to +standard working hours are 9:00am - 12:00am, 1:00pm - 6:00pm, Monday to Friday. The working hours specification limits the availability of resources to certain time slots of week days. diff -Nru tj3-3.6.0/lib/taskjuggler/UTF8String.rb tj3-3.7.1/lib/taskjuggler/UTF8String.rb --- tj3-3.6.0/lib/taskjuggler/UTF8String.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/UTF8String.rb 2020-03-14 16:26:45.000000000 +0000 @@ -18,7 +18,7 @@ # This is an extension and modification of the standard String class. We do a # lot of UTF-8 character processing in the parser. Ruby 1.8 does not have good # enough UTF-8 support and Ruby 1.9 only handles UTF-8 characters as Strings. -# This is very inefficient compared to representing them as Fixnum objects. +# This is very inefficient compared to representing them as Integer objects. # Some of these hacks can be removed once we have switched to 1.9 support # only. class String @@ -58,8 +58,8 @@ alias old_double_left_angle << # Replacement for the existing << operator that also works for characters - # above Fixnum 255 (UTF-8 characters). - def << (obj) + # above Integer 255 (UTF-8 characters). + def <<(obj) if obj.is_a?(String) || (obj < 256) # In this case we can use the built-in concat. concat(obj) diff -Nru tj3-3.6.0/lib/taskjuggler/version.rb tj3-3.7.1/lib/taskjuggler/version.rb --- tj3-3.6.0/lib/taskjuggler/version.rb 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/version.rb 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1 @@ +VERSION = '3.7.1' diff -Nru tj3-3.6.0/lib/taskjuggler/WorkingHours.rb tj3-3.7.1/lib/taskjuggler/WorkingHours.rb --- tj3-3.6.0/lib/taskjuggler/WorkingHours.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/WorkingHours.rb 2020-03-14 16:26:45.000000000 +0000 @@ -17,7 +17,7 @@ class TaskJuggler # Class to store the working hours for each day of the week. The working hours - # are stored as Arrays of Fixnum intervals for each day of the week. A day off + # are stored as Arrays of Integer intervals for each day of the week. A day off # is modelled as empty Array for that week day. The start end end times of # each working period are stored as seconds after midnight. class WorkingHours @@ -100,7 +100,7 @@ # Set the working hours for a given week day. +dayOfWeek+ must be 0 for # Sunday, 1 for Monday and so on. +intervals+ must be an Array that - # contains an Array with 2 Fixnums for each working period. Each value + # contains an Array with 2 Integers for each working period. Each value # specifies the time of day as minutes after midnight. The first value is # the start time of the interval, the second the end time. def setWorkingHours(dayOfWeek, intervals) @@ -133,7 +133,7 @@ # Return the working hour intervals for a given day of the week. # +dayOfWeek+ must 0 for Sunday, 1 for Monday and so on. The result is an - # Array that contains Arrays of 2 Fixnums. + # Array that contains Arrays of 2 Integers. def getWorkingHours(dayOfWeek) @days[dayOfWeek] end diff -Nru tj3-3.6.0/lib/taskjuggler/XMLElement.rb tj3-3.7.1/lib/taskjuggler/XMLElement.rb --- tj3-3.6.0/lib/taskjuggler/XMLElement.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/lib/taskjuggler/XMLElement.rb 2020-03-14 16:26:45.000000000 +0000 @@ -204,7 +204,18 @@ end def to_s(indent) - '\n#{' ' * indent}" + '\n#{' ' * indent}" + end + + private + + # It is crucial to canonicalize xml comment text because xml + # comment syntax forbids having a -- in the comment body. I + # picked emacs's "M-x comment-region" approach of putting a + # backslash between the two. + def canonicalize_comment(text) + new_text = text.gsub("--", "-\\-") + new_text end end diff -Nru tj3-3.6.0/manual/Day_To_Day_Juggling tj3-3.7.1/manual/Day_To_Day_Juggling --- tj3-3.6.0/manual/Day_To_Day_Juggling 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/Day_To_Day_Juggling 2020-03-14 16:26:45.000000000 +0000 @@ -4,7 +4,7 @@ To analyze the impact that a small variation can have on a project, TaskJuggler supports an unlimited amount of scenarios. Each -additional scenario is a slight derivation of the it's parent. The +additional scenario is a slight derivation of it's parent. The task tree structure needs to be the same for all scenarios, but most attributes can vary from one scenario to another. Several report types support comparative listing of multiple [[scenarios]]. @@ -223,12 +223,12 @@ contributors that have not submitted their report. # On Monday the project managers need to review the time sheets and -update the plan accordingly. TaskJuggler can compile a list changes +update the plan accordingly. TaskJuggler can compile a list of changes compared to the plan. This makes it easy to update the plan according to the actual progress that was made. The closer the actuals match the plan the less work this is. The project managers now generate bookings for the last week and add them to the database with previous -bookings. Doing so, will prevent changes to the plan to affect the +bookings. Doing so will prevent changes to the plan to affect the past. Only the future will be modified. # Once the plan has been updated, managers will receive their status @@ -696,7 +696,7 @@ When you run ''''tj3 --freeze'''' again, it will update the header and booking files. Since you have included your booking file, any -modifications you have made, will be preserved. That is, the actual +modifications you have made will be preserved. That is, the actual data will be preserved, not the formatting since the file will be completely re-generated again. @@ -722,11 +722,11 @@ report template. Each manager will get one template that includes the status reports for the tasks they are responsible for. -It's not the managers task to prepare the report for the next level +It's the managers task to prepare the report for the next level of management. To do this, the manager has 3 options: * Forward the status report of a task directly to the next level. The -original authorship can be keep or removed. The content can also be +original authorship can be kept or removed. The content can also be edited if needed. * Similar reports for a task or a whole task sub-tree can be combined @@ -747,7 +747,7 @@ ==== The Status Sheet Template Sender ==== To send out the time sheets, the command ''''tj3ts_sender'''' must be -used. It will use the ''''tj3client'''' program to do retrieve the +used. It will use the ''''tj3client'''' program to retrieve the necessary data from the TaskJuggler server. Before the program can be used, a new section must be added to the @@ -813,7 +813,7 @@ ==== The Status Sheet Receiver ==== -Similarly to the time sheets a the completed status sheets must be +Similarly to the time sheets, the completed status sheets must be send back by email. We already described how the necessary email aliases should be configured. For status sheets the address ''''statussheets@taskjuggler.your_company.com'''' can be used. diff -Nru tj3-3.6.0/manual/Installation tj3-3.7.1/manual/Installation --- tj3-3.6.0/manual/Installation 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/Installation 2020-03-14 16:26:45.000000000 +0000 @@ -88,7 +88,7 @@ you can also install it into your home or data directory. This does not require root or admin permissions. -The following steps are describe the installation on a Linux system +The following steps describe the installation on a Linux system with the bash shell. You may have to use slightly different commands on a different operating system. @@ -119,7 +119,7 @@ The last two settings should also be added to your .profile file to make them permanent. -That's it. You now should be run TaskJuggler. +That's it. You now should run TaskJuggler. tj3 --version @@ -187,7 +187,7 @@ git clone git@github.com/taskjuggler/TaskJuggler.git -Make sure, you have removed all previously installed instances of +Make sure you have removed all previously installed instances of TaskJuggler from your system before doing so. It is a common mistake to have an old version of the TaskJuggler installed and then use parts of the old and new version together. @@ -323,7 +323,7 @@ which ruby -should show return the path to the link to your +should return the path to the link to your ''''${HOME}/bin/ruby''''. You now have the latest Ruby installed and are ready to use TaskJuggler. @@ -343,7 +343,7 @@ file editing. If you don't have a preference yet, we recommend to try the [http://www.vim.org Vim] text editor. It's a very powerful editor and it has been customized for better integration with TaskJuggler. -This section describes, how to activate and use the Vim integration. +This section describes how to activate and use the Vim integration. Vim is provided by pretty much any Linux distribution and also works well on MacOX and Windows. See the web page for how to install it if you don't have it yet. @@ -366,7 +366,7 @@ cp `gem contents taskjuggler | fgrep tjp.vim` .vim/syntax -Now we have to make sure, Vim detects the file. Edit the +Now we have to make sure Vim detects the file. Edit the ''''.vim/filetype.vim'''' file to contain the following section. augroup filetypedetect diff -Nru tj3-3.6.0/manual/List_Attributes tj3-3.7.1/manual/List_Attributes --- tj3-3.6.0/manual/List_Attributes 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/List_Attributes 2020-03-14 16:26:45.000000000 +0000 @@ -29,7 +29,7 @@ ''''f2'''' assigned. The same works for scenarios as well. Even though the syntax may not -look like inheritance is at play the scenario ''''s2'''' inherits all +look like inheritance is at play, the scenario ''''s2'''' inherits all values from ''''s1''''. <[example file="ListAttributes" tag="scenario"]> diff -Nru tj3-3.6.0/manual/Rich_Text_Attributes tj3-3.7.1/manual/Rich_Text_Attributes --- tj3-3.6.0/manual/Rich_Text_Attributes 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/Rich_Text_Attributes 2020-03-14 16:26:45.000000000 +0000 @@ -126,7 +126,7 @@ You can also insert raw HTML code by enclosing it in '''...''' tags. For all other output formats, this content will be ignored. There is also no error checking -if the code is valid! Use this feature very carefully. +whether the code is valid! Use this feature very carefully. ==== Block and Inline Generators ==== @@ -179,12 +179,13 @@ * ''''attributes'''': A set of attributes that override the original attributes of the referenced report. All report attributes -are supported. Since the value of attributes already must be enclosed +are supported. Since the values of attributes already must be enclosed by single or double quotes, all single or double quotes contained in the string must be escaped with backslashes. This feature enables reports with content that is customized based on where they have been referenced from. It requires the reports to be dynamically generated -and is only available when used with the ''''tj3d'''' web server. +and is only available when used with the ''''tj3d'''' web server +''''tj3webd''''. The ''''tj3'''' application will ignore the attributes setting. taskreport "All" { @@ -254,8 +255,8 @@ predefined values. When used in the header section of a report, the context does not provide a property or scope property. Start and end dates as well the formatting options are taken from the report -context. But when used e. g. in [[celltext.column]] the cell -provides, that property and the attribute and possibly even the scope +context. But when used e. g. in [[celltext.column]], the cell +provides that property and the attribute and possibly even the scope property. diff -Nru tj3-3.6.0/manual/Software tj3-3.7.1/manual/Software --- tj3-3.6.0/manual/Software 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/Software 2020-03-14 16:26:45.000000000 +0000 @@ -1,6 +1,6 @@ == The TaskJuggler Software == -After the installation of a software package the first questions that +After the installation of a software package the first question that most users have is ''"How do I run it?"''. Many users expect to find an icon on their desktop or an entry in the start menu hierarchy. Don't bother looking for them, you won't find any for TaskJuggler. As @@ -80,7 +80,7 @@ The latter defaults to using the [http://www.mozilla.com/en-US/firefox/new/ Mozilla Firefox] web -browser . Please see +browser. Please see tj3man --help @@ -102,12 +102,12 @@ automatically disconnects from the terminal and runs in the background. All interactions with the server are done via the TCP/IP protocol. For security reasons, only connections from the same -machine (localhost) are accepted. To get access all clients must +machine (localhost) are accepted. To get access, all clients must provide an authentication key. A TaskJuggler server can serve any number of projects. Once a project has been loaded successfully, clients can retrieve the data in form of reports. Projects are identified by their project ID. If a newly added project has the same -ID such as an already loaded project, the new project will replace +ID as an already loaded project, the new project will replace the old project once it was scheduled successfully. Before you start the server, you need to provide a configuration file with some basic settings. @@ -147,7 +147,7 @@ * 3: Like 2, but additionally with information messages * 4: Like 3, but additionally with debug messages -The configuration file will be searched in the current directory, +The configuration file will be searched for in the current directory, the current user's home directory or ''''/etc''''. You can also explicitly tell the server where to find the configuration file with the ''''-c'''' option. See @@ -210,7 +210,7 @@ authKey: topsecret webServerPort: 8080 -To access the HTML reports point your web browser to +To access the HTML reports, point your web browser to ''''http://localhost:8080/taskjuggler''''. This assumes that the server is running on your local machine. You will then see a list of all loaded projects. Click on the project name to get a list of all diff -Nru tj3-3.6.0/manual/TaskJuggler_Internals tj3-3.7.1/manual/TaskJuggler_Internals --- tj3-3.6.0/manual/TaskJuggler_Internals 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/TaskJuggler_Internals 2020-03-14 16:26:45.000000000 +0000 @@ -26,7 +26,7 @@ The scheduler needs to determine the start and end date for all tasks that don't have such dates yet. To deal with multiple concurrent time zones, all time related events are stored internally as UTC -time.Additionally, it allocates resources to tasks. All events such +time. Additionally, it allocates resources to tasks. All events such as start or end of a task, or allocation of a resource can only happen aligned with the [[timingresolution|timing resolution]]. This determines the smallest possible allocation period that we call a time @@ -57,7 +57,7 @@ resources have been assigned for all time slots. The goal of the scheduler is to transfer all tasks in the completed -state. Until this goal has been reached, at least one tasks needs to +state. Until this goal has been reached, at least one task needs to be in the ready state. If that's not the case, the project schedule cannot be determined and an error is raised. In case there are more than one task in the ready state, we need to have a well defined @@ -103,7 +103,7 @@ the tasks of the path is computed. The largest sum is the path criticalness of that task. -This heuristic will favor allocations to task with critical resources +This heuristic will favor allocations to tasks with critical resources and long dependency chains. As a result, the critical paths of the project are tried to be kept short. The user can use the '''criticalness''' and '''pathcriticalness''' [[columnid|columns]] to @@ -111,7 +111,7 @@ When the criticalness and pathcriticalness for all leaf resources and tasks has been determined, the leaf tasks are sorted by priority -(hight to low), then by pathcricialness (high to low) and then by the +(high to low), then by pathcricialness (high to low) and then by the index (low to high). In a loop that is terminated when all tasks have been scheduled or an error condition has been detected, the first task that is ready for scheduling is completely scheduled. This means diff -Nru tj3-3.6.0/manual/The_TaskJuggler_Syntax tj3-3.7.1/manual/The_TaskJuggler_Syntax --- tj3-3.6.0/manual/The_TaskJuggler_Syntax 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/The_TaskJuggler_Syntax 2020-03-14 16:26:45.000000000 +0000 @@ -34,7 +34,7 @@ keyword ( foo | bar | foobar ) Some keywords take one or more arguments. These are known as list -attributes. The arguments are comma separated. The tree dots in the +attributes. The arguments are comma separated. The three dots in the syntax description mean that the sequence before the dots can be repeated if needed. Inheritable list attributes will append the new list values to the inherited list. Use can use the [[purge]] @@ -73,7 +73,7 @@ Strings are character sequences that are enclosed by special character marks. There are three different marks supported. For -short strings that fit on one lines, you can either use single or +short strings that fit on one line, you can either use single or double quotes. 'This is a single quoted string.' @@ -112,7 +112,7 @@ === Predefined Macros === TaskJuggler supports a few predefined macros. These are available -after the project header. They values correspond to the values +after the project header. Their values correspond to the values provided in the project header. * ''''projectstart'''' The start date of the project. @@ -128,6 +128,6 @@ === Environment Variable Expansions === By using the $(VAR) syntax, you can insert the value of the -environment variable name VAR. The name of the variable must consists -only of uppercase ASCII letters, underscore or decimal digits. +environment variable name VAR. The name of the variable must consist +only of uppercase ASCII letters, underscores or decimal digits. diff -Nru tj3-3.6.0/manual/Tutorial tj3-3.7.1/manual/Tutorial --- tj3-3.6.0/manual/Tutorial 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/manual/Tutorial 2020-03-14 16:26:45.000000000 +0000 @@ -13,7 +13,7 @@ TaskJuggler software installation. You can use the following command to find the base directory of the example projects. - ruby19 -e "puts Gem::Specification.find_by_name('taskjuggler').gem_dir" + ruby -e "puts Gem::Specification.find_by_name('taskjuggler').gem_dir" The file for the tutorial project is called ''''examples/Tutorial/tutorial.tjp''''. You can use any plain text @@ -31,7 +31,7 @@ <[example file="tutorial" tag="header1"]> -All TaskJuggler properties have a unique ID ,a name, and a set of +All TaskJuggler properties have a unique ID, a name, and a set of optional attributes. The name must always be specified. The ID can be omitted if you never have to reference the property from another context. If you omit the ID, TaskJuggler will automatically generate a @@ -75,7 +75,7 @@ <[example file="tutorial" tag="currency"]> Because each culture has its own way of specifying dates and numbers, -the format for these are configurable. Use the [[timeformat]] +the format for these is configurable. Use the [[timeformat]] attribute to specify the default format for dates. This format is used for reports, it does not affect the way you specify dates in the project files. Here you always need to use the [[date|TaskJuggler date @@ -148,7 +148,7 @@ Use the [[leaves]] attribute to define a global holiday. Global holidays may have a name and must have a date or date range. Other leaves for -individual resources or groups of resources can be defines similarly. +individual resources or groups of resources can be defined similarly. === Macros === @@ -189,6 +189,8 @@ [[account|accounts]] to credit the amounts to. We create one account for the development costs, one for the documentation costs, and one for the customer payments. +Actually, there is a fourth account consisting of two accounts nested +into it. <[example file="tutorial" tag="accounts"]> @@ -308,7 +310,7 @@ resources could be allocated long enough to reach the specified effort. Tasks with ''''length'''' or ''''duration'''' criteria and allocated resources will last exactly as long as requested. Resources -will be allocated only if available. It's possible that such a tasks +will be allocated only if available. It's possible that such a task ends up with no allocations at all if the resources are always assigned to other tasks for that period. Each task can only have one of the three duration criteria. Container tasks may never have a @@ -331,7 +333,7 @@ specification. The start and end criteria can either be fixed dates or relative dates. Relative dates are specifications of the type ''task B starts after task A has finished''. Or in other words, task B depends -on task A. In this example the spec task depends on a subtasks of the +on task A. In this example the spec task depends on a subtask of the deliveries task. We have not specified it yet, but it has the local ID ''''start''''. @@ -347,7 +349,7 @@ Relative IDs always start with one or more exclamation marks. Each exclamation mark moves the scope to the next enclosing task. So ''''!deliveries.start'''' is expanded to ''''AcSo.deliveries.start'''' -since ''''AcSo'''' is the enclosing task of deliveries. Relative task +since ''''AcSo'''' is the enclosing task of ''''deliveries''''. Relative task IDs are a little bit confusing at first, but have a real advantage over absolute IDs. Sooner or later you want to move tasks around in your project and then it's a lot less likely that you have to fix @@ -362,7 +364,7 @@ the tasks. 500 is the default priority of top-level tasks. Setting the priority to 1000 marks the task as most important task, since the possible range is 1 (not important at all) to 1000 (ultimately -important). priority is an attribute that is passed down to subtasks +important). ''''priority'''' is an attribute that is passed down to subtasks if specified before the subtasks' declaration. So all subtasks of software have a priority of 1000 as well, unless they have their own priority definition. @@ -486,7 +488,7 @@ === Visualizing the Project === -To see and share the project data you reports can be generated. You +To see and share the project data, reports can be generated. You can generate any number of reports and you can select from a variety of report types and output formats. To have a report generated after the project scheduling has been completed, you need include a report @@ -645,7 +647,7 @@ report file. For the [[footer]] we can proceed accordingly. We just add a few more -paragraphs of text the describe certain aspects of the project. By +paragraphs of text to describe certain aspects of the project. By putting it all together, we end up with the following report definition. @@ -653,7 +655,7 @@ The generated report can be found [http://www.taskjuggler.org/tj3/examples/Tutorial/Overview.html -here]. It servers as an entry page for the other reports. While it +here]. It serves as an entry page for the other reports. While it already contains some references, a navigator bar would be handy as well. Fortunately, there is a block generator called 'navigator' to take care of this. But before we can include the navigator in the diff -Nru tj3-3.6.0/spec/ProjectBroker_spec.rb tj3-3.7.1/spec/ProjectBroker_spec.rb --- tj3-3.6.0/spec/ProjectBroker_spec.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/spec/ProjectBroker_spec.rb 2020-03-14 16:26:45.000000000 +0000 @@ -82,7 +82,7 @@ it "should fail with bad authentication key" do TaskJuggler::runBroker(@pb, @authKey) do - @pbi.command('bad key', :status, []).should be_false + @pbi.command('bad key', :status, []).should be false end end @@ -105,14 +105,14 @@ stdOut = StringIO.new stdErr = StringIO.new args = [ Dir.getwd, [ '.' ], stdOut, stdErr, stdIn, true ] - @pbi.command(@authKey, :addProject, args).should be_true + @pbi.command(@authKey, :addProject, args).should be true stdErr.string.should be_empty # Can't remove non-existing project bar - @pbi.command(@authKey, :removeProject, 'bar').should be_false - @pbi.command(@authKey, :removeProject, 'foo').should be_true + @pbi.command(@authKey, :removeProject, 'bar').should be false + @pbi.command(@authKey, :removeProject, 'foo').should be true # Can't remove foo twice - @pbi.command(@authKey, :removeProject, 'foo').should be_false + @pbi.command(@authKey, :removeProject, 'foo').should be false end end @@ -123,7 +123,7 @@ it "should fail with bad authentication key" do TaskJuggler::runBroker(@pb, @authKey) do @pbi.updateState('bad key', 'foo', 'foo', :status, true).should \ - be_false + be false end end diff -Nru tj3-3.6.0/spec/StatusSheets_spec.rb tj3-3.7.1/spec/StatusSheets_spec.rb --- tj3-3.6.0/spec/StatusSheets_spec.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/spec/StatusSheets_spec.rb 2020-03-14 16:26:45.000000000 +0000 @@ -230,7 +230,7 @@ it 'should have matching status sheets in body and attachment' do @sss_mails.each do |mail| bodySheet = extractStatusSheet(mail.parts[0].decoded) - attachedSheet = extractStatusSheet(mail.part[1].decoded) + attachedSheet = extractStatusSheet(mail.part[1].decoded).tr("\r", '') bodySheet.should == attachedSheet end end diff -Nru tj3-3.6.0/spec/TimeSheets_spec.rb tj3-3.7.1/spec/TimeSheets_spec.rb --- tj3-3.6.0/spec/TimeSheets_spec.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/spec/TimeSheets_spec.rb 2020-03-14 16:26:45.000000000 +0000 @@ -216,7 +216,7 @@ it 'should have matching timesheets in body and attachment' do @tss_mails.each do |mail| bodySheet = extractTimeSheet(mail.parts[0].decoded) - attachedSheet = extractTimeSheet(mail.part[1].decoded) + attachedSheet = extractTimeSheet(mail.part[1].decoded).tr("\r", '') bodySheet.should == attachedSheet end end diff -Nru tj3-3.6.0/taskjuggler.gemspec tj3-3.7.1/taskjuggler.gemspec --- tj3-3.6.0/taskjuggler.gemspec 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/taskjuggler.gemspec 2020-03-14 16:26:45.000000000 +0000 @@ -35,16 +35,16 @@ s.summary = 'A Project Management Software' s.description = <<'EOT' TaskJuggler is a modern and powerful, Free and Open Source Software project -management tool. Its new approach to project planing and tracking is more +management tool. It's new approach to project planning and tracking is more flexible and superior to the commonly used Gantt chart editing tools. TaskJuggler is project management software for serious project managers. It covers the complete spectrum of project management tasks from the first idea to the completion of the project. It assists you during project scoping, -resource assignment, cost and revenue planing, risk and communication +resource assignment, cost and revenue planning, risk and communication management. EOT - + s.license = 'GPL-2.0' s.require_path = 'lib' s.files = (`git ls-files -- lib`).split("\n") + (`git ls-files -- data`).split("\n") + @@ -53,7 +53,7 @@ (`git ls-files -- tasks`).split("\n") + %w( .gemtest taskjuggler.gemspec Rakefile ) + # Generated files, not contained in Git repository. - %w( data/tjp.vim ) + Dir.glob('manual/html/**/*') + %w( data/tjp.vim ) + Dir.glob('manual/html/**/*') + Dir.glob('man/*.1') s.bindir = 'bin' s.executables = (`git ls-files -- bin`).split("\n"). map { |fn| File.basename(fn) } @@ -63,9 +63,9 @@ s.has_rdoc = true s.extra_rdoc_files = %w( README.rdoc COPYING CHANGELOG ) - s.add_dependency('mail', '>= 2.4.3') - s.add_dependency('term-ansicolor', '>= 1.0.7') - s.add_development_dependency('rspec', '>= 2.5.0') + s.add_dependency('mail', '~> 2.7', '>= 2.7.1') + s.add_runtime_dependency('term-ansicolor', '~> 1.7', '>= 1.7.1') + s.add_development_dependency('rspec', '~> 2.5', '>= 2.5.0') s.platform = Gem::Platform::RUBY s.required_ruby_version = '>= 2.0.0' } diff -Nru tj3-3.6.0/tasks/changelog.rake tj3-3.7.1/tasks/changelog.rake --- tj3-3.6.0/tasks/changelog.rake 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/tasks/changelog.rake 2020-03-14 16:26:45.000000000 +0000 @@ -1,5 +1,7 @@ require 'time' +CLOBBER.include "CHANGELOG" + desc 'Generate the CHANGELOG file' task :changelog do diff -Nru tj3-3.6.0/tasks/gem.rake tj3-3.7.1/tasks/gem.rake --- tj3-3.6.0/tasks/gem.rake 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/tasks/gem.rake 2020-03-14 16:26:45.000000000 +0000 @@ -3,6 +3,8 @@ require 'rubygems' require 'rubygems/package' +CLOBBER.include "pkg/" + # Unfortunately Rake::GemPackageTest cannot deal with files that are generated # by Rake targets. So we have to write our own packaging task. desc 'Build the gem package' @@ -11,6 +13,7 @@ Rake::Task[:manual].invoke Rake::Task[:changelog].invoke Rake::Task[:permissions].invoke + Rake::Task[:help2man].invoke load 'taskjuggler.gemspec'; diff -Nru tj3-3.6.0/tasks/help2man.rake tj3-3.7.1/tasks/help2man.rake --- tj3-3.6.0/tasks/help2man.rake 1970-01-01 00:00:00.000000000 +0000 +++ tj3-3.7.1/tasks/help2man.rake 2020-03-14 16:26:45.000000000 +0000 @@ -0,0 +1,18 @@ +# TASK MAN GENERATE + +CLOBBER.include "man" + +directory "man" + +desc 'Generate man pages from help' +task :help2man => 'man' do + help2man = %x{which help2man} + help2man.chomp! + Dir.foreach('bin') do |prog| + next if prog == '.' or prog == '..' + system help2man,"--output=man/#{prog}.1","--no-info","--manual=TaskJuggler",*("--include=h2m/#{prog}.h2m" unless !File.exists?("h2m/#{prog}.h2m")),"bin/#{prog}" + FileUtils.chmod(0644, "man/#{prog}.1") + end + FileUtils.chmod(0755, 'man') +end + diff -Nru tj3-3.6.0/tasks/kate.rake tj3-3.7.1/tasks/kate.rake --- tj3-3.6.0/tasks/kate.rake 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/tasks/kate.rake 2020-03-14 16:26:45.000000000 +0000 @@ -2,6 +2,8 @@ require 'taskjuggler/KateSyntax' +CLOBBER.include "data/kate-tjp.xml" + desc 'Generate kate-tjp.xml Kate syntax file' task :kate do TaskJuggler::KateSyntax.new.generate('data/kate-tjp.xml') diff -Nru tj3-3.6.0/tasks/manual.rake tj3-3.7.1/tasks/manual.rake --- tj3-3.6.0/tasks/manual.rake 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/tasks/manual.rake 2020-03-14 16:26:45.000000000 +0000 @@ -2,6 +2,8 @@ require 'taskjuggler/apps/Tj3Man' +CLOBBER.include "manual/html/" + desc 'Generate User Manual' task :manual do htmldir = 'manual/html' diff -Nru tj3-3.6.0/tasks/test.rake tj3-3.7.1/tasks/test.rake --- tj3-3.6.0/tasks/test.rake 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/tasks/test.rake 2020-03-14 16:26:45.000000000 +0000 @@ -2,6 +2,11 @@ require 'rake/testtask' +CLEAN.include "test/TestSuite/Export-Reports/refs/Leave.tjp" +CLEAN.include "test/TestSuite/Export-Reports/refs/ListAttributes.tjp" +CLEAN.include "test/TestSuite/Export-Reports/refs/Macro-4.tjp" +CLEAN.include "test/TestSuite/Export-Reports/refs/TraceReport.tjp" + # TEST TASK desc 'Run all unit tests in the test directory' Rake::TestTask.new(:unittest) do |t| diff -Nru tj3-3.6.0/tasks/vim.rake tj3-3.7.1/tasks/vim.rake --- tj3-3.6.0/tasks/vim.rake 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/tasks/vim.rake 2020-03-14 16:26:45.000000000 +0000 @@ -2,6 +2,8 @@ require 'taskjuggler/VimSyntax' +CLOBBER.include "data/tjp.vim" + desc 'Generate vim.tjp Vim syntax file' task :vim do TaskJuggler::VimSyntax.new.generate('data/tjp.vim') diff -Nru tj3-3.6.0/test/test_ProjectFileScanner.rb tj3-3.7.1/test/test_ProjectFileScanner.rb --- tj3-3.6.0/test/test_ProjectFileScanner.rb 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/test_ProjectFileScanner.rb 2020-03-14 16:26:45.000000000 +0000 @@ -56,7 +56,7 @@ [:LITERAL, '-', 6], [:LITERAL, '$', 6], [:MACRO, 'A Macro', 6], - [:TIME, time(15, 23), 7], + [:TIME, mktime(15, 23), 7], [:STRING, 'A string', 7], [:STRING, "It's a string", 8], [:STRING, "A\nmult\"i line\nstring", 9], @@ -101,12 +101,12 @@ 24:00 EOT ref = [ - [:TIME, time(0, 0), 1], - [:TIME, time(0, 0), 2], - [:TIME, time(1, 0), 3], - [:TIME, time(11, 59), 4], - [:TIME, time(12, 1), 5], - [:TIME, time(24, 0), 6], + [:TIME, mktime(0, 0), 1], + [:TIME, mktime(0, 0), 2], + [:TIME, mktime(1, 0), 3], + [:TIME, mktime(11, 59), 4], + [:TIME, mktime(12, 1), 5], + [:TIME, mktime(24, 0), 6], [:eof, '', 7] ] @@ -172,7 +172,7 @@ private - def time(h, m) + def mktime(h, m) (h * 60 + m) * 60 end diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/AccountReport.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/AccountReport.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/AccountReport.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/AccountReport.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -45,7 +45,6 @@ task _Task_6 "Final Payment" { depends _Task_1.mf start 2012-10-22-17:00-+0000 - milestone scheduled } } diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/AdoptedTasks.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/AdoptedTasks.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/AdoptedTasks.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/AdoptedTasks.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,12 +10,10 @@ task t1 "T1" { start 2011-03-05-00:00-+0000 - milestone scheduled } task t2 "T2" { start 2011-03-05-00:00-+0000 - milestone scheduled } task t3 "T3" { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/AlertLevels.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/AlertLevels.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/AlertLevels.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/AlertLevels.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -15,7 +15,6 @@ task _Task_1 "Holiday Season" { start 2011-11-24-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Allocate-1.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Allocate-1.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Allocate-1.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Allocate-1.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -25,7 +25,6 @@ } task m1 "Milestone 1" { start 2003-06-05-06:00-+0000 - milestone scheduled } } diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/AutoID.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/AutoID.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/AutoID.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/AutoID.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -32,7 +32,6 @@ task _Task_1 "Foo" { task _Task_2 "Bar" { start 2009-10-04-00:00-+0000 - milestone scheduled } } diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/AutoMacros.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/AutoMacros.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/AutoMacros.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/AutoMacros.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task items "Project breakdown" { start 2006-09-22-00:00-+0000 - milestone scheduled } supplement task items { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Currencyformat.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Currencyformat.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Currencyformat.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Currencyformat.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task t "Task" { start 2007-01-01-00:00-+0000 - milestone scheduled } supplement task t { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/CustomAttributes.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/CustomAttributes.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/CustomAttributes.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/CustomAttributes.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -38,9 +38,7 @@ task _Task_1 "T" { start 2013-04-24-00:00-+0000 - milestone scheduled - two:milestone } supplement task _Task_1 { Claim "A '''big''' statement." diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Depends1.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Depends1.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Depends1.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Depends1.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -11,7 +11,6 @@ task foo1 "foo1" { task foo2 "foo2" { start 2007-12-04-07:00-+0000 - milestone scheduled } task foo3 "foo3" { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Durations.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Durations.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Durations.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Durations.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -18,7 +18,6 @@ } task intervalTask "Interval Task" { start 2007-06-17-06:00-+0000 - milestone scheduled } task lengthTask "Length Task" { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Efficiency.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Efficiency.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Efficiency.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Efficiency.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -14,7 +14,6 @@ task t "An important date" { start 2007-07-21-06:00-+0000 - milestone scheduled } supplement task t { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Gap.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Gap.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Gap.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Gap.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,19 +10,16 @@ task t1 "Task 1" { start 2005-05-29-06:00-+0000 - milestone scheduled } task t2 "Task 2" { depends t1 start 2005-06-03-06:00-+0000 - milestone scheduled } task t3 "Task 3" { depends t1 start 2005-06-03-23:00-+0000 - milestone scheduled } supplement task t1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Include.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Include.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Include.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Include.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -14,7 +14,6 @@ task _Task_1 "Foo" { start 2010-02-26-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Journal.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Journal.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Journal.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Journal.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -11,7 +11,6 @@ task t1 "Task1" { start 2009-05-05-06:00-+0000 - milestone scheduled } supplement task t1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Macro-1.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Macro-1.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Macro-1.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Macro-1.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -12,7 +12,6 @@ task t1 "Task1" { start 2008-01-18-00:00-+0000 - milestone scheduled } task t2 "Task2" { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Macro-2.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Macro-2.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Macro-2.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Macro-2.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,12 +10,10 @@ task _Task_1 " Crème brûlée Prepare " { start 2010-04-28-00:00-+0000 - milestone scheduled } task _Task_2 "task" { start 2010-04-28-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Macro-3.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Macro-3.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Macro-3.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Macro-3.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task _Task_1 "foo" { start 2009-12-01-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Manager.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Manager.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Manager.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Manager.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -23,7 +23,6 @@ task _Task_1 "T" { start 2010-04-03-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Milestone.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Milestone.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Milestone.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Milestone.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,12 +10,10 @@ task project_start "Project Start" { start 2005-07-15-06:00-+0000 - milestone scheduled } task deadline "Important Deadline" { start 2005-07-20-06:00-+0000 - milestone scheduled } supplement task project_start { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/navigator.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/navigator.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/navigator.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/navigator.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -11,24 +11,20 @@ task foo "Foo" { task _Task_2 "Foo 1" { start 2011-12-12-00:00-+0000 - milestone scheduled } task _Task_3 "Foo 2" { start 2011-12-12-00:00-+0000 - milestone scheduled } } task bar "Bar" { task _Task_5 "Bar 1" { start 2011-12-12-00:00-+0000 - milestone scheduled } task _Task_6 "Bar 2" { start 2011-12-12-00:00-+0000 - milestone scheduled } } diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Numberformat.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Numberformat.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Numberformat.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Numberformat.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task t "Task" { start 2000-01-01-00:00-+0000 - milestone scheduled } supplement task t { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Precedes1.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Precedes1.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Precedes1.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Precedes1.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -11,7 +11,6 @@ task foo1 "foo1" { task foo2 "foo2" { start 2003-12-04-07:00-+0000 - milestone scheduled } task foo3 "foo3" { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/ProjectIDs.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/ProjectIDs.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/ProjectIDs.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/ProjectIDs.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,17 +10,14 @@ task t1 "Task 1" { start 2006-08-22-06:00-+0000 - milestone scheduled } task t2 "Task 2" { start 2006-08-22-06:00-+0000 - milestone scheduled } task t3 "Task 3" { start 2006-08-22-06:00-+0000 - milestone scheduled } supplement task t1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Project.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Project.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Project.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Project.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task t "Task" { start 2007-01-01-07:00-+0000 - milestone scheduled } supplement task t { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Reports.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Reports.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Reports.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Reports.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -30,7 +30,6 @@ } task t3 "FooTask3" { start 2000-01-01-07:00-+0000 - milestone scheduled } supplement task t1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/ResourceRoot.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/ResourceRoot.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/ResourceRoot.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/ResourceRoot.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -19,7 +19,6 @@ task _Task_1 "T" { start 2010-11-10-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Resource.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Resource.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Resource.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Resource.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -15,7 +15,6 @@ task t "An important date" { start 2005-06-10-06:00-+0000 - milestone scheduled } supplement task t { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/RollupResource.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/RollupResource.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/RollupResource.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/RollupResource.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -19,7 +19,6 @@ task _Task_1 "T" { start 2010-11-10-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Scenario.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Scenario.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Scenario.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Scenario.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -16,10 +16,8 @@ task t "Task" { start 2007-05-29-06:00-+0000 - milestone scheduled actual:start 2007-06-03-06:00-+0000 - actual:milestone } supplement task t { priority 500 diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/template.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/template.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/template.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/template.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -18,12 +18,10 @@ task wp1 "Workpackage 1" { task t1 "Task 1" { start 2011-11-11-05:00-+0000 - milestone scheduled } task t2 "Task 2" { start 2011-11-11-05:00-+0000 - milestone scheduled } } @@ -31,12 +29,10 @@ depends project.wp1 task t1 "Task 1" { start 2011-11-11-05:00-+0000 - milestone scheduled } task t2 "Task 2" { start 2011-11-11-05:00-+0000 - milestone scheduled } } @@ -44,13 +40,11 @@ task _Task_9 "Item 1" { depends project.wp1 start 2011-11-11-05:00-+0000 - milestone scheduled } task _Task_10 "Item 2" { depends project.wp2 start 2011-11-11-05:00-+0000 - milestone scheduled } } diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/textreport.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/textreport.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/textreport.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/textreport.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task _Task_1 "Foo" { start 2011-12-11-00:00-+0000 - milestone scheduled } supplement task _Task_1 { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Timezone.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Timezone.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Timezone.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Timezone.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -10,7 +10,6 @@ task item "Project" { start 2005-06-06-09:00-+0000 - milestone scheduled } supplement task item { diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/tutorial.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/tutorial.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/tutorial.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/tutorial.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -104,34 +104,26 @@ task deliveries "Milestones" { task start "Project start" { start 2002-01-16-00:00-+0000 - milestone scheduled delayed:start 2002-01-19-23:00-+0000 - delayed:milestone } task prev "Technology Preview" { depends AcSo.software.backend start 2002-02-28-14:00-+0000 - milestone scheduled delayed:start 2002-03-05-14:00-+0000 - delayed:milestone } task beta "Beta version" { depends AcSo.test.alpha start 2002-04-03-10:00-+0000 - milestone scheduled delayed:start 2002-04-11-09:00-+0000 - delayed:milestone } task done "Ship Product to Customer" { depends AcSo.test.beta, AcSo.manual start 2002-04-18-13:00-+0000 - milestone scheduled delayed:start 2002-04-26-12:00-+0000 - delayed:milestone } } } diff -Nru tj3-3.6.0/test/TestSuite/Export-Reports/refs/Vacation.tjp tj3-3.7.1/test/TestSuite/Export-Reports/refs/Vacation.tjp --- tj3-3.6.0/test/TestSuite/Export-Reports/refs/Vacation.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Export-Reports/refs/Vacation.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -16,7 +16,6 @@ task t "An important date" { start 2005-07-22-06:00-+0000 - milestone scheduled } supplement task t { diff -Nru tj3-3.6.0/test/TestSuite/Syntax/Correct/Booking.tjp tj3-3.7.1/test/TestSuite/Syntax/Correct/Booking.tjp --- tj3-3.6.0/test/TestSuite/Syntax/Correct/Booking.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Syntax/Correct/Booking.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -20,7 +20,7 @@ 2007-01-09-13:00 +4h # This is a common mistake. With standard working hours, this will # yield a zero time booking! The interval is midnight to 8am. So - # it's outside of the working hours and 'sloppy 2' surpresses the + # it's outside of the working hours and 'sloppy 2' suppresses the # warning. booking test 2007-01-11 +8h { sloppy 2 } # Use 'overtime' to book off-hour slots. This booking will book the diff -Nru tj3-3.6.0/test/TestSuite/Syntax/Correct/Currencyformat.tjp tj3-3.7.1/test/TestSuite/Syntax/Correct/Currencyformat.tjp --- tj3-3.6.0/test/TestSuite/Syntax/Correct/Currencyformat.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Syntax/Correct/Currencyformat.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -1,7 +1,7 @@ project prj "Project" "1.0" 2007-01-01 - 2007-03-01 { timezone "Europe/Berlin" # German currency format: e. g. -10.000,20 5.014,11 - numberformat "-" "" "." "," 2 + currencyformat "-" "" "." "," 2 # US currency format: e. g. (10,000.20) 5,014.11 currencyformat "(" ")" "," "." 2 diff -Nru tj3-3.6.0/test/TestSuite/Syntax/Correct/tutorial.tjp tj3-3.7.1/test/TestSuite/Syntax/Correct/tutorial.tjp --- tj3-3.6.0/test/TestSuite/Syntax/Correct/tutorial.tjp 2016-03-12 20:10:13.000000000 +0000 +++ tj3-3.7.1/test/TestSuite/Syntax/Correct/tutorial.tjp 2020-03-14 16:26:45.000000000 +0000 @@ -33,6 +33,11 @@ # *** EXAMPLE: now + now 2002-03-05-13:00 # *** EXAMPLE: now - + # The date that is used to show additional line on a Gannt chart + # and can be specified by the user. +# *** EXAMPLE: markdate + + markdate 2002-08-07-03:00 +# *** EXAMPLE: markdate - # The currency for all money values is the Euro. # *** EXAMPLE: currency + currency "USD"