taskjuggler 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +44 -0
- data/bin/tj3webd +4 -0
- data/data/css/tjreport.css +14 -5
- data/data/tjp.vim +22 -7
- data/examples/Fedora-20/reports.tji +2 -4
- data/examples/Scrum/Product Burndown.csv +26 -0
- data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
- data/examples/Scrum/scrum.tjp +141 -0
- data/examples/Tutorial/tutorial.tjp +13 -7
- data/lib/taskjuggler/Attributes.rb +2 -3
- data/lib/taskjuggler/HTMLDocument.rb +25 -18
- data/lib/taskjuggler/Journal.rb +85 -65
- data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
- data/lib/taskjuggler/LeaveList.rb +1 -1
- data/lib/taskjuggler/Limits.rb +3 -5
- data/lib/taskjuggler/MessageHandler.rb +173 -19
- data/lib/taskjuggler/Painter.rb +75 -0
- data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
- data/lib/taskjuggler/Painter/Color.rb +273 -0
- data/lib/taskjuggler/Painter/Element.rb +56 -0
- data/lib/taskjuggler/Painter/FontData.rb +221 -0
- data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
- data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
- data/lib/taskjuggler/Painter/Group.rb +77 -0
- data/lib/taskjuggler/Painter/Points.rb +47 -0
- data/lib/taskjuggler/Painter/Primitives.rb +100 -0
- data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
- data/lib/taskjuggler/Painter/Text.rb +36 -0
- data/lib/taskjuggler/Project.rb +46 -29
- data/lib/taskjuggler/ProjectFileParser.rb +24 -22
- data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
- data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
- data/lib/taskjuggler/Query.rb +8 -5
- data/lib/taskjuggler/RealFormat.rb +3 -0
- data/lib/taskjuggler/Resource.rb +3 -5
- data/lib/taskjuggler/ResourceScenario.rb +19 -7
- data/lib/taskjuggler/RichText.rb +4 -6
- data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
- data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
- data/lib/taskjuggler/RichText/Parser.rb +4 -6
- data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
- data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
- data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
- data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
- data/lib/taskjuggler/RichText/Scanner.rb +6 -6
- data/lib/taskjuggler/RichText/Snip.rb +1 -2
- data/lib/taskjuggler/RuntimeConfig.rb +9 -6
- data/lib/taskjuggler/ScenarioData.rb +4 -3
- data/lib/taskjuggler/Scoreboard.rb +6 -0
- data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
- data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
- data/lib/taskjuggler/SyntaxReference.rb +1 -2
- data/lib/taskjuggler/TableColumnSorter.rb +84 -0
- data/lib/taskjuggler/Task.rb +3 -5
- data/lib/taskjuggler/TaskJuggler.rb +36 -29
- data/lib/taskjuggler/TaskScenario.rb +154 -66
- data/lib/taskjuggler/TextParser.rb +24 -17
- data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
- data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
- data/lib/taskjuggler/TimeSheets.rb +6 -12
- data/lib/taskjuggler/Tj3AppBase.rb +35 -16
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
- data/lib/taskjuggler/XMLElement.rb +9 -2
- data/lib/taskjuggler/apps/Tj3.rb +43 -37
- data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
- data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
- data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
- data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
- data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
- data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
- data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
- data/lib/taskjuggler/daemon/Daemon.rb +50 -10
- data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
- data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
- data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
- data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
- data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
- data/lib/taskjuggler/daemon/WebServer.rb +75 -22
- data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
- data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
- data/lib/taskjuggler/reports/CSVFile.rb +9 -2
- data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
- data/lib/taskjuggler/reports/Navigator.rb +1 -0
- data/lib/taskjuggler/reports/NikuReport.rb +4 -4
- data/lib/taskjuggler/reports/Report.rb +6 -18
- data/lib/taskjuggler/reports/ReportBase.rb +9 -9
- data/lib/taskjuggler/reports/ReportContext.rb +2 -2
- data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
- data/lib/taskjuggler/reports/TableReport.rb +24 -15
- data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
- data/lib/taskjuggler/reports/TraceReport.rb +251 -0
- data/lib/tj3webd.rb +17 -0
- data/manual/Day_To_Day_Juggling +10 -3
- data/manual/Installation +38 -19
- data/manual/Software +25 -19
- data/manual/Tutorial +119 -110
- data/manual/html/Day_To_Day_Juggling.html +7 -5
- data/manual/html/Getting_Started.html +4 -4
- data/manual/html/How_To_Contribute.html +4 -4
- data/manual/html/Installation.html +19 -11
- data/manual/html/Intro.html +4 -4
- data/manual/html/Reporting_Bugs.html +4 -4
- data/manual/html/Rich_Text_Attributes.html +4 -4
- data/manual/html/Software.html +15 -11
- data/manual/html/TaskJuggler_2x_Migration.html +4 -4
- data/manual/html/TaskJuggler_Internals.html +4 -4
- data/manual/html/The_TaskJuggler_Syntax.html +4 -4
- data/manual/html/Tutorial.html +41 -32
- data/manual/html/account.html +4 -4
- data/manual/html/account.task.html +4 -4
- data/manual/html/accountprefix.html +4 -4
- data/manual/html/accountreport.html +27 -9
- data/manual/html/accountroot.html +5 -5
- data/manual/html/active.html +4 -4
- data/manual/html/adopt.task.html +4 -4
- data/manual/html/aggregate.html +4 -4
- data/manual/html/alert.html +4 -4
- data/manual/html/alertlevels.html +4 -4
- data/manual/html/allocate.html +5 -5
- data/manual/html/alphabet.html +4 -4
- data/manual/html/alternative.html +4 -4
- data/manual/html/author.html +4 -4
- data/manual/html/balance.html +5 -5
- data/manual/html/booking.resource.html +4 -4
- data/manual/html/booking.task.html +4 -4
- data/manual/html/caption.html +5 -5
- data/manual/html/cellcolor.column.html +43 -8
- data/manual/html/celltext.column.html +4 -4
- data/manual/html/center.html +5 -5
- data/manual/html/charge.html +4 -4
- data/manual/html/chargeset.html +4 -4
- data/manual/html/columnid.html +27 -15
- data/manual/html/columns.html +5 -5
- data/manual/html/complete.html +4 -4
- data/manual/html/copyright.html +4 -4
- data/manual/html/credits.html +4 -4
- data/manual/html/css/tjreport.css +14 -5
- data/manual/html/currency.html +4 -4
- data/manual/html/currencyformat.html +5 -5
- data/manual/html/dailymax.html +5 -5
- data/manual/html/dailymin.html +5 -5
- data/manual/html/dailyworkinghours.html +4 -4
- data/manual/html/date.extend.html +4 -4
- data/manual/html/date.html +5 -5
- data/manual/html/definitions.html +4 -4
- data/manual/html/depends.html +4 -4
- data/manual/html/details.html +4 -4
- data/manual/html/disabled.html +4 -4
- data/manual/html/duration.html +4 -4
- data/manual/html/efficiency.html +4 -4
- data/manual/html/effort.html +4 -4
- data/manual/html/email.html +4 -4
- data/manual/html/enabled.html +4 -4
- data/manual/html/end.column.html +4 -4
- data/manual/html/end.html +4 -4
- data/manual/html/end.limit.html +4 -4
- data/manual/html/end.report.html +5 -5
- data/manual/html/end.timesheet.html +4 -4
- data/manual/html/endcredit.html +4 -4
- data/manual/html/epilog.html +5 -5
- data/manual/html/export.html +4 -4
- data/manual/html/extend.html +4 -4
- data/manual/html/fail.html +43 -8
- data/manual/html/fdl.html +4 -4
- data/manual/html/flags.account.html +4 -4
- data/manual/html/flags.html +4 -4
- data/manual/html/flags.journalentry.html +4 -4
- data/manual/html/flags.report.html +5 -5
- data/manual/html/flags.resource.html +4 -4
- data/manual/html/flags.statussheet.html +4 -4
- data/manual/html/flags.task.html +4 -4
- data/manual/html/flags.timesheet.html +4 -4
- data/manual/html/fontcolor.column.html +43 -8
- data/manual/html/footer.html +5 -5
- data/manual/html/formats.html +5 -5
- data/manual/html/functions.html +4 -4
- data/manual/html/gapduration.html +4 -4
- data/manual/html/gaplength.html +4 -4
- data/manual/html/halign.center.html +4 -4
- data/manual/html/halign.column.html +43 -8
- data/manual/html/halign.left.html +4 -4
- data/manual/html/halign.right.html +4 -4
- data/manual/html/hasalert.html +4 -4
- data/manual/html/header.html +5 -5
- data/manual/html/headline.html +7 -7
- data/manual/html/height.html +72 -0
- data/manual/html/hideaccount.html +46 -11
- data/manual/html/hidejournalentry.html +5 -5
- data/manual/html/hidereport.html +43 -8
- data/manual/html/hideresource.html +44 -9
- data/manual/html/hidetask.html +44 -9
- data/manual/html/icalreport.html +4 -4
- data/manual/html/include.macro.html +4 -4
- data/manual/html/include.project.html +4 -4
- data/manual/html/include.properties.html +4 -4
- data/manual/html/index.html +2 -1
- data/manual/html/inherit.extend.html +4 -4
- data/manual/html/interval1.html +4 -4
- data/manual/html/interval2.html +4 -4
- data/manual/html/interval3.html +4 -4
- data/manual/html/interval4.html +4 -4
- data/manual/html/isactive.html +4 -4
- data/manual/html/ischildof.html +4 -4
- data/manual/html/isdependencyof.html +4 -4
- data/manual/html/isdutyof.html +4 -4
- data/manual/html/isfeatureof.html +4 -4
- data/manual/html/isleaf.html +4 -4
- data/manual/html/ismilestone.html +4 -4
- data/manual/html/isongoing.html +4 -4
- data/manual/html/isresource.html +4 -4
- data/manual/html/isresponsibilityof.html +4 -4
- data/manual/html/istask.html +4 -4
- data/manual/html/journalattributes.html +11 -7
- data/manual/html/journalentry.html +4 -4
- data/manual/html/journalmode.html +5 -5
- data/manual/html/leaveallowance.html +5 -5
- data/manual/html/leaves.html +5 -6
- data/manual/html/left.html +5 -5
- data/manual/html/length.html +4 -4
- data/manual/html/limits.allocate.html +4 -4
- data/manual/html/limits.html +4 -4
- data/manual/html/limits.resource.html +4 -4
- data/manual/html/limits.task.html +4 -4
- data/manual/html/listitem.column.html +4 -4
- data/manual/html/listtype.column.html +4 -4
- data/manual/html/loadunit.html +5 -5
- data/manual/html/logicalexpression.html +8 -44
- data/manual/html/logicalflagexpression.html +4 -4
- data/manual/html/macro.html +4 -4
- data/manual/html/managers.html +4 -4
- data/manual/html/mandatory.html +4 -4
- data/manual/html/maxend.html +4 -4
- data/manual/html/maximum.html +5 -5
- data/manual/html/maxstart.html +4 -4
- data/manual/html/milestone.html +4 -4
- data/manual/html/minend.html +4 -4
- data/manual/html/minimum.html +5 -5
- data/manual/html/minstart.html +4 -4
- data/manual/html/monthlymax.html +5 -5
- data/manual/html/monthlymin.html +5 -5
- data/manual/html/navbar.html +10 -4
- data/manual/html/navigator.html +4 -4
- data/manual/html/newtask.html +4 -4
- data/manual/html/nikureport.html +4 -4
- data/manual/html/note.task.html +4 -4
- data/manual/html/now.html +4 -4
- data/manual/html/numberformat.html +5 -5
- data/manual/html/onend.html +4 -4
- data/manual/html/onstart.html +4 -4
- data/manual/html/opennodes.html +5 -5
- data/manual/html/overtime.booking.html +4 -4
- data/manual/html/period.column.html +4 -4
- data/manual/html/period.limit.html +4 -4
- data/manual/html/period.report.html +5 -5
- data/manual/html/period.task.html +4 -4
- data/manual/html/persistent.html +4 -4
- data/manual/html/precedes.html +4 -4
- data/manual/html/priority.html +4 -4
- data/manual/html/priority.timesheet.html +4 -4
- data/manual/html/project.html +4 -4
- data/manual/html/projectid.html +4 -4
- data/manual/html/projectid.task.html +4 -4
- data/manual/html/projectids.html +4 -4
- data/manual/html/projection.html +5 -7
- data/manual/html/prolog.html +5 -5
- data/manual/html/properties.html +11 -5
- data/manual/html/purge.html +5 -5
- data/manual/html/rate.html +4 -4
- data/manual/html/rate.resource.html +4 -4
- data/manual/html/reference.extend.html +4 -4
- data/manual/html/remaining.html +4 -4
- data/manual/html/replace.html +4 -4
- data/manual/html/reportprefix.html +4 -4
- data/manual/html/resource.html +4 -10
- data/manual/html/resourceattributes.html +4 -4
- data/manual/html/resourceprefix.html +4 -4
- data/manual/html/resourcereport.html +28 -10
- data/manual/html/resourceroot.html +5 -5
- data/manual/html/resources.limit.html +4 -4
- data/manual/html/responsible.html +4 -4
- data/manual/html/richtext.extend.html +4 -4
- data/manual/html/right.html +5 -5
- data/manual/html/rollupaccount.html +44 -9
- data/manual/html/rollupresource.html +44 -9
- data/manual/html/rolluptask.html +44 -9
- data/manual/html/scale.column.html +4 -4
- data/manual/html/scenario.html +4 -22
- data/manual/html/scenario.ical.html +4 -4
- data/manual/html/scenarios.export.html +4 -4
- data/manual/html/scenarios.html +5 -5
- data/manual/html/scenariospecific.extend.html +4 -4
- data/manual/html/scheduled.html +4 -4
- data/manual/html/scheduling.html +4 -4
- data/manual/html/select.html +4 -4
- data/manual/html/selfcontained.html +5 -5
- data/manual/html/shift.allocate.html +4 -4
- data/manual/html/shift.html +4 -4
- data/manual/html/shift.resource.html +5 -5
- data/manual/html/shift.task.html +4 -4
- data/manual/html/shift.timesheet.html +4 -4
- data/manual/html/shifts.allocate.html +4 -4
- data/manual/html/shifts.resource.html +4 -4
- data/manual/html/shifts.task.html +4 -4
- data/manual/html/shorttimeformat.html +4 -4
- data/manual/html/sloppy.booking.html +4 -4
- data/manual/html/sloppy.projection.html +5 -5
- data/manual/html/sortaccounts.html +5 -5
- data/manual/html/sortjournalentries.html +5 -5
- data/manual/html/sortresources.html +5 -5
- data/manual/html/sorttasks.html +5 -5
- data/manual/html/start.column.html +4 -4
- data/manual/html/start.html +4 -4
- data/manual/html/start.limit.html +4 -4
- data/manual/html/start.report.html +5 -5
- data/manual/html/startcredit.html +4 -4
- data/manual/html/status.statussheet.html +4 -4
- data/manual/html/status.timesheet.html +4 -4
- data/manual/html/statussheet.html +4 -4
- data/manual/html/statussheetreport.html +4 -4
- data/manual/html/strict.projection.html +5 -5
- data/manual/html/summary.html +4 -4
- data/manual/html/supplement.html +4 -4
- data/manual/html/supplement.resource.html +4 -10
- data/manual/html/supplement.task.html +4 -28
- data/manual/html/tagfile.html +4 -4
- data/manual/html/task.html +4 -28
- data/manual/html/task.statussheet.html +4 -4
- data/manual/html/task.timesheet.html +4 -4
- data/manual/html/taskattributes.html +4 -4
- data/manual/html/taskprefix.html +4 -4
- data/manual/html/taskreport.html +28 -10
- data/manual/html/taskroot.html +5 -5
- data/manual/html/text.extend.html +4 -4
- data/manual/html/textreport.html +27 -9
- data/manual/html/timeformat.html +5 -5
- data/manual/html/timeoff.nikureport.html +4 -4
- data/manual/html/timesheet.html +4 -4
- data/manual/html/timesheetreport.html +23 -5
- data/manual/html/timezone.export.html +4 -4
- data/manual/html/timezone.html +4 -4
- data/manual/html/timezone.report.html +5 -5
- data/manual/html/timezone.shift.html +4 -4
- data/manual/html/timingresolution.html +4 -4
- data/manual/html/title.column.html +4 -4
- data/manual/html/title.html +5 -5
- data/manual/html/toc.html +207 -179
- data/manual/html/tooltip.column.html +45 -10
- data/manual/html/tracereport.html +405 -0
- data/manual/html/trackingscenario.html +6 -6
- data/manual/html/treelevel.html +4 -4
- data/manual/html/vacation.html +4 -4
- data/manual/html/vacation.resource.html +4 -4
- data/manual/html/vacation.shift.html +4 -4
- data/manual/html/warn.html +43 -8
- data/manual/html/weeklymax.html +5 -5
- data/manual/html/weeklymin.html +5 -5
- data/manual/html/weekstartsmonday.html +4 -4
- data/manual/html/weekstartssunday.html +6 -6
- data/manual/html/width.column.html +6 -6
- data/manual/html/width.html +72 -0
- data/manual/html/work.html +4 -4
- data/manual/html/workinghours.project.html +4 -4
- data/manual/html/workinghours.resource.html +4 -4
- data/manual/html/workinghours.shift.html +4 -4
- data/manual/html/yearlyworkingdays.html +4 -4
- data/spec/Color_spec.rb +60 -0
- data/spec/ProjectBroker_spec.rb +3 -2
- data/spec/StatusSheets_spec.rb +5 -4
- data/spec/TableColumnSorter_spec.rb +78 -0
- data/spec/TimeSheets_spec.rb +6 -2
- data/spec/Tj3Daemon_spec.rb +2 -2
- data/spec/TraceReport_spec.rb +117 -0
- data/taskjuggler.gemspec +1 -1
- data/test/MessageChecker.rb +3 -1
- data/test/ReferenceGenerator.rb +1 -1
- data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
- data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
- data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
- data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
- data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
- data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
- data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
- data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
- data/test/test_CSV-Reports.rb +3 -3
- data/test/test_Export-Reports.rb +91 -86
- data/test/test_Journal.rb +15 -12
- data/test/test_Limits.rb +3 -3
- data/test/test_Project.rb +1 -2
- data/test/test_ProjectFileScanner.rb +1 -1
- data/test/test_PropertySet.rb +1 -1
- data/test/test_Query.rb +5 -6
- data/test/test_ReportGenerator.rb +15 -7
- data/test/test_RichText.rb +4 -3
- data/test/test_Scheduler.rb +19 -7
- data/test/test_ShiftAssignments.rb +2 -2
- data/test/test_SimpleQueryExpander.rb +29 -2
- data/test/test_Syntax.rb +14 -5
- metadata +49 -10
- data/lib/taskjuggler/LogFile.rb +0 -73
|
@@ -23,12 +23,17 @@ class TaskJuggler
|
|
|
23
23
|
def initialize(name, attributes = {}, selfClosing = false, &block)
|
|
24
24
|
if (name.nil? && attributes.length > 0) ||
|
|
25
25
|
(!name.nil? && !name.is_a?(String))
|
|
26
|
-
raise "Name must be nil or a String "
|
|
26
|
+
raise ArgumentError, "Name must be nil or a String "
|
|
27
27
|
end
|
|
28
28
|
@name = name
|
|
29
29
|
attributes.each do |n, v|
|
|
30
30
|
if n.nil? || v.nil?
|
|
31
|
-
raise
|
|
31
|
+
raise ArgumentError,
|
|
32
|
+
"Attribute name (#{n}) or value (#{v}) may not be nil"
|
|
33
|
+
end
|
|
34
|
+
unless v.is_a?(String)
|
|
35
|
+
raise ArgumentError,
|
|
36
|
+
"Attribute value of #{n} must be a String"
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
39
|
@attributes = attributes
|
|
@@ -91,6 +96,8 @@ class TaskJuggler
|
|
|
91
96
|
|
|
92
97
|
# Add or change _attribute_ to _value_.
|
|
93
98
|
def []=(attribute, value)
|
|
99
|
+
raise ArgumentError,
|
|
100
|
+
"Attribute value #{value} is not a String" unless value.is_a?(String)
|
|
94
101
|
@attributes[attribute] = value
|
|
95
102
|
end
|
|
96
103
|
|
data/lib/taskjuggler/apps/Tj3.rb
CHANGED
|
@@ -35,6 +35,8 @@ class TaskJuggler
|
|
|
35
35
|
@checkSyntax = false
|
|
36
36
|
# Don't generate reports when previous errors have been found.
|
|
37
37
|
@forceReports = false
|
|
38
|
+
# Don't generate trace reports by default
|
|
39
|
+
@generateTraces = false
|
|
38
40
|
# Should a booking file be generated?
|
|
39
41
|
@freeze = false
|
|
40
42
|
# The cut-off date for the freeze
|
|
@@ -87,7 +89,8 @@ EOT
|
|
|
87
89
|
begin
|
|
88
90
|
@freezeDate = TjTime.new(arg).align(3600)
|
|
89
91
|
rescue TjException => msg
|
|
90
|
-
error(
|
|
92
|
+
error('tj3_ivld_freeze_date',
|
|
93
|
+
"Invalid freeze date: #{msg.message}")
|
|
91
94
|
end
|
|
92
95
|
end
|
|
93
96
|
@opts.on('--freezebytask',
|
|
@@ -117,6 +120,10 @@ EOT
|
|
|
117
120
|
'reports.')) do
|
|
118
121
|
@noReports = true
|
|
119
122
|
end
|
|
123
|
+
@opts.on('--add-trace',
|
|
124
|
+
format('Append a current data set to all trace reports.')) do
|
|
125
|
+
@generateTraces = true
|
|
126
|
+
end
|
|
120
127
|
@opts.on('--abort-on-warnings',
|
|
121
128
|
format('Abort program on warnings like we do on errors.')) do
|
|
122
129
|
@abortOnWarning = true
|
|
@@ -133,49 +140,48 @@ EOT
|
|
|
133
140
|
end
|
|
134
141
|
|
|
135
142
|
def appMain(files)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
tj.maxCpuCores = @maxCpuCores
|
|
146
|
-
tj.warnTsDeltas = @warnTsDeltas
|
|
147
|
-
tj.messageHandler.abortOnWarning = @abortOnWarning
|
|
148
|
-
keepParser = !@timeSheets.empty? || !@statusSheets.empty?
|
|
149
|
-
return 1 unless tj.parse(files, keepParser)
|
|
143
|
+
if files.empty?
|
|
144
|
+
error('tj3_tjp_file_missing',
|
|
145
|
+
'You must provide at least one .tjp file')
|
|
146
|
+
end
|
|
147
|
+
if @outputDir != '' && !File.directory?(@outputDir)
|
|
148
|
+
error('tj3_outdir_missing',
|
|
149
|
+
"Output directory #{@outputDir} does not exist or is not " +
|
|
150
|
+
"a directory!")
|
|
151
|
+
end
|
|
150
152
|
|
|
151
|
-
|
|
153
|
+
tj = TaskJuggler.new
|
|
154
|
+
tj.maxCpuCores = @maxCpuCores
|
|
155
|
+
tj.warnTsDeltas = @warnTsDeltas
|
|
156
|
+
tj.generateTraces = @generateTraces
|
|
157
|
+
MessageHandlerInstance.instance.abortOnWarning = @abortOnWarning
|
|
158
|
+
keepParser = !@timeSheets.empty? || !@statusSheets.empty?
|
|
159
|
+
return 1 unless tj.parse(files, keepParser)
|
|
152
160
|
|
|
153
|
-
|
|
154
|
-
return 1 unless @forceReports
|
|
155
|
-
end
|
|
161
|
+
return 0 if @checkSyntax
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return 1 if !tj.checkTimeSheet(ts) || tj.errors > 0
|
|
161
|
-
end
|
|
162
|
-
@statusSheets.each do |ss|
|
|
163
|
-
return 1 if !tj.checkStatusSheet(ss) || tj.errors > 0
|
|
164
|
-
end
|
|
163
|
+
if !tj.schedule
|
|
164
|
+
return 1 unless @forceReports
|
|
165
|
+
end
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
# The checks of time and status sheets is probably only used for
|
|
168
|
+
# debugging. Normally, this function is provided by tj3client.
|
|
169
|
+
@timeSheets.each do |ts|
|
|
170
|
+
return 1 if !tj.checkTimeSheet(ts) || tj.errors > 0
|
|
171
|
+
end
|
|
172
|
+
@statusSheets.each do |ss|
|
|
173
|
+
return 1 if !tj.checkStatusSheet(ss) || tj.errors > 0
|
|
174
|
+
end
|
|
171
175
|
|
|
172
|
-
|
|
176
|
+
# Check for freeze mode and generate the booking file if requested.
|
|
177
|
+
if @freeze
|
|
178
|
+
return 1 unless tj.freeze(@freezeDate, @freezeByTask) &&
|
|
179
|
+
tj.errors == 0
|
|
180
|
+
end
|
|
173
181
|
|
|
174
|
-
|
|
182
|
+
return 0 if @noReports
|
|
175
183
|
|
|
176
|
-
|
|
177
|
-
return 1
|
|
178
|
-
end
|
|
184
|
+
return 1 if !tj.generateReports(@outputDir) || tj.errors > 0
|
|
179
185
|
|
|
180
186
|
0
|
|
181
187
|
end
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
require 'drb'
|
|
15
15
|
require 'drb/acl'
|
|
16
16
|
require 'taskjuggler/Tj3AppBase'
|
|
17
|
-
require 'taskjuggler/
|
|
17
|
+
require 'taskjuggler/daemon/DaemonConnector'
|
|
18
18
|
|
|
19
19
|
# Name of the application
|
|
20
20
|
AppConfig.appName = 'tj3client'
|
|
@@ -28,6 +28,8 @@ class TaskJuggler
|
|
|
28
28
|
# requires a properly configured tj3d to work.
|
|
29
29
|
class Tj3Client < Tj3AppBase
|
|
30
30
|
|
|
31
|
+
include DaemonConnectorMixin
|
|
32
|
+
|
|
31
33
|
def initialize
|
|
32
34
|
super
|
|
33
35
|
|
|
@@ -136,8 +138,8 @@ EOT
|
|
|
136
138
|
@uriFile = arg
|
|
137
139
|
end
|
|
138
140
|
@opts.on('-r', '--regexp',
|
|
139
|
-
format('The report IDs are not fixed but regular
|
|
140
|
-
'that match a set of reports')) do |arg|
|
|
141
|
+
format('The report IDs are not fixed but regular ' +
|
|
142
|
+
'expressions that match a set of reports')) do |arg|
|
|
141
143
|
@regExpMode = true
|
|
142
144
|
end
|
|
143
145
|
@opts.on('--unsafe',
|
|
@@ -151,8 +153,8 @@ EOT
|
|
|
151
153
|
format('Request the report to be generated in the specified' +
|
|
152
154
|
'format. Use multiple options to request multiple ' +
|
|
153
155
|
'formats. Supported formats are csv, html, niku and ' +
|
|
154
|
-
'tjp. By default, the formats specified in the
|
|
155
|
-
'definition are used.')) do |arg|
|
|
156
|
+
'tjp. By default, the formats specified in the ' +
|
|
157
|
+
'report definition are used.')) do |arg|
|
|
156
158
|
@formats = [] unless @formats
|
|
157
159
|
@formats << arg
|
|
158
160
|
end
|
|
@@ -160,21 +162,18 @@ EOT
|
|
|
160
162
|
end
|
|
161
163
|
|
|
162
164
|
def appMain(args)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
rescue TjRuntimeError
|
|
176
|
-
return 1
|
|
177
|
-
end
|
|
165
|
+
# Run a first check of the non-optional command line arguments.
|
|
166
|
+
checkCommand(args)
|
|
167
|
+
# Read some configuration variables. Except for the authKey, they are
|
|
168
|
+
# all optional.
|
|
169
|
+
@rc.configure(self, 'global')
|
|
170
|
+
|
|
171
|
+
@broker = connectDaemon
|
|
172
|
+
retVal = executeCommand(args[0], args[1..-1])
|
|
173
|
+
disconnectDaemon
|
|
174
|
+
@broker = nil
|
|
175
|
+
|
|
176
|
+
retVal
|
|
178
177
|
end
|
|
179
178
|
|
|
180
179
|
private
|
|
@@ -205,64 +204,7 @@ EOT
|
|
|
205
204
|
end
|
|
206
205
|
end
|
|
207
206
|
|
|
208
|
-
error(errorMessage)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def connectDaemon
|
|
212
|
-
unless @authKey
|
|
213
|
-
$stderr.puts <<'EOT'
|
|
214
|
-
You must set an authentication key in the configuration file. Create a file
|
|
215
|
-
named .taskjugglerrc or taskjuggler.rc that contains at least the following
|
|
216
|
-
lines. Replace 'your_secret_key' with some random character sequence.
|
|
217
|
-
|
|
218
|
-
_global:
|
|
219
|
-
authKey: your_secret_key
|
|
220
|
-
EOT
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
uri = "druby://#{@host}:#{@port}"
|
|
224
|
-
if @port == 0
|
|
225
|
-
# If the @port is configured to 0, we need to read the URI to connect
|
|
226
|
-
# to the server from the .tj3d.uri file that has been generated by the
|
|
227
|
-
# server.
|
|
228
|
-
begin
|
|
229
|
-
uri = File.read(@uriFile).chomp
|
|
230
|
-
rescue
|
|
231
|
-
error('The server port is configured to be 0, but no ' +
|
|
232
|
-
".tj3d.uri file can be found: #{$!}")
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
# We try to play it safe here. The client also starts a DRb server, so
|
|
237
|
-
# we need to make sure it's constricted to localhost only. We require
|
|
238
|
-
# the DRb server for the standard IO redirection to work.
|
|
239
|
-
$SAFE = 1 unless @unsafeMode
|
|
240
|
-
DRb.install_acl(ACL.new(%w[ deny all
|
|
241
|
-
allow 127.0.0.1 ]))
|
|
242
|
-
DRb.start_service('druby://127.0.0.1:0')
|
|
243
|
-
|
|
244
|
-
begin
|
|
245
|
-
# Get the ProjectBroker object from the tj3d.
|
|
246
|
-
@broker = DRbObject.new(nil, uri)
|
|
247
|
-
# Client and server should always come from the same Gem. Since we
|
|
248
|
-
# restict communication to localhost, that's probably not a problem.
|
|
249
|
-
if (check = @broker.apiVersion(@authKey, 1)) < 0
|
|
250
|
-
error('This client is too old for the server. Please ' +
|
|
251
|
-
'upgrade to a more recent version of the software.')
|
|
252
|
-
elsif check == 0
|
|
253
|
-
error('Authentication failed. Please check your authentication ' +
|
|
254
|
-
'key to match the server key.')
|
|
255
|
-
end
|
|
256
|
-
rescue
|
|
257
|
-
error("TaskJuggler server on host '#{@host}' port " +
|
|
258
|
-
"#{@port} is not responding")
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
def disconnectDaemon
|
|
263
|
-
@broker = nil
|
|
264
|
-
|
|
265
|
-
DRb.stop_service
|
|
207
|
+
error('tjc_cmd_error', errorMessage)
|
|
266
208
|
end
|
|
267
209
|
|
|
268
210
|
def executeCommand(command, args)
|
|
@@ -271,22 +213,28 @@ EOT
|
|
|
271
213
|
$stdout.puts callDaemon(:status, [])
|
|
272
214
|
when 'terminate'
|
|
273
215
|
callDaemon(:stop, [])
|
|
274
|
-
info('Daemon terminated')
|
|
216
|
+
info('tjc_daemon_term', 'Daemon terminated')
|
|
275
217
|
when 'add'
|
|
276
218
|
res = callDaemon(:addProject, [ Dir.getwd, args,
|
|
277
219
|
$stdout, $stderr, $stdin, @silent ])
|
|
278
|
-
|
|
279
|
-
|
|
220
|
+
if res
|
|
221
|
+
info('tjc_proj_added', "Project(s) #{args.join(', ')} added")
|
|
222
|
+
return 0
|
|
223
|
+
else
|
|
224
|
+
warning('tjc_proj_adding_failed',
|
|
225
|
+
"Projects(s) #{args.join(', ')} could not be added")
|
|
226
|
+
return 1
|
|
227
|
+
end
|
|
280
228
|
when 'remove'
|
|
281
229
|
args.each do |arg|
|
|
282
230
|
unless callDaemon(:removeProject, arg)
|
|
283
|
-
error("Project '#{arg}' not found in list")
|
|
231
|
+
error('tjc_prj_not_found', "Project '#{arg}' not found in list")
|
|
284
232
|
end
|
|
285
233
|
end
|
|
286
|
-
info('Project removed')
|
|
234
|
+
info('tjc_prj_removed', 'Project removed')
|
|
287
235
|
when 'update'
|
|
288
236
|
callDaemon(:update, [])
|
|
289
|
-
info('Reload requested')
|
|
237
|
+
info('tjc_reload_req', 'Reload requested')
|
|
290
238
|
when 'report'
|
|
291
239
|
# The first value of args is the project ID. The following values
|
|
292
240
|
# could be either report IDs or TJI file # names ('.' or '*.tji').
|
|
@@ -298,17 +246,22 @@ EOT
|
|
|
298
246
|
reportIds, tjiFiles = splitIdsAndFiles(args)
|
|
299
247
|
if reportIds.empty?
|
|
300
248
|
disconnectReportServer
|
|
301
|
-
error('You must provide at least one report ID')
|
|
249
|
+
error('tjc_no_rep_id', 'You must provide at least one report ID')
|
|
302
250
|
end
|
|
303
251
|
# Send the provided .tji files to the ReportServer.
|
|
304
252
|
failed = !addFiles(tjiFiles)
|
|
305
253
|
# Ask the ReportServer to generate the reports with the provided IDs.
|
|
306
254
|
unless failed
|
|
307
255
|
reportIds.each do |reportId|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
256
|
+
begin
|
|
257
|
+
unless @reportServer.generateReport(@rs_authKey, reportId,
|
|
258
|
+
@regExpMode, @formats, nil)
|
|
259
|
+
failed = true
|
|
260
|
+
break
|
|
261
|
+
end
|
|
262
|
+
rescue
|
|
263
|
+
error('tjc_gen_rep_failed',
|
|
264
|
+
"Could not generate report #{reportId}: #{$!}")
|
|
312
265
|
end
|
|
313
266
|
end
|
|
314
267
|
end
|
|
@@ -334,9 +287,15 @@ EOT
|
|
|
334
287
|
# Ask the ReportServer to generate the reports with the provided IDs.
|
|
335
288
|
unless failed
|
|
336
289
|
reportIds.each do |reportId|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
290
|
+
begin
|
|
291
|
+
unless @reportServer.listReports(@rs_authKey, reportId,
|
|
292
|
+
@regExpMode)
|
|
293
|
+
failed = true
|
|
294
|
+
break
|
|
295
|
+
end
|
|
296
|
+
rescue
|
|
297
|
+
error('tjc_report_list_failed',
|
|
298
|
+
"Getting report list failed: #{$!}")
|
|
340
299
|
end
|
|
341
300
|
end
|
|
342
301
|
end
|
|
@@ -348,7 +307,7 @@ EOT
|
|
|
348
307
|
begin
|
|
349
308
|
res = @reportServer.checkTimeSheet(@rs_authKey, args[1])
|
|
350
309
|
rescue
|
|
351
|
-
error("Time sheet check failed: #{$!}")
|
|
310
|
+
error('tjc_tschck_failed', "Time sheet check failed: #{$!}")
|
|
352
311
|
end
|
|
353
312
|
disconnectReportServer
|
|
354
313
|
return res ? 0 : 1
|
|
@@ -357,7 +316,7 @@ EOT
|
|
|
357
316
|
begin
|
|
358
317
|
res = @reportServer.checkStatusSheet(@rs_authKey, args[1])
|
|
359
318
|
rescue
|
|
360
|
-
error("Status sheet check failed: #{$!}")
|
|
319
|
+
error('tjc_sschck_failed', "Status sheet check failed: #{$!}")
|
|
361
320
|
end
|
|
362
321
|
disconnectReportServer
|
|
363
322
|
return res ? 0 : 1
|
|
@@ -370,19 +329,19 @@ EOT
|
|
|
370
329
|
def connectToReportServer(projectId)
|
|
371
330
|
@ps_uri, @ps_authKey = callDaemon(:getProject, projectId)
|
|
372
331
|
if @ps_uri.nil?
|
|
373
|
-
error("No project with ID #{projectId} loaded")
|
|
332
|
+
error('tjc_prj_id_not_loaded', "No project with ID #{projectId} loaded")
|
|
374
333
|
end
|
|
375
334
|
begin
|
|
376
335
|
@projectServer = DRbObject.new(nil, @ps_uri)
|
|
377
336
|
@rs_uri, @rs_authKey = @projectServer.getReportServer(@ps_authKey)
|
|
378
337
|
@reportServer = DRbObject.new(nil, @rs_uri)
|
|
379
338
|
rescue
|
|
380
|
-
error("Cannot get report server")
|
|
339
|
+
error('tjc_no_rep_srv', "Cannot get report server: #{$!}")
|
|
381
340
|
end
|
|
382
341
|
begin
|
|
383
342
|
@reportServer.connect(@rs_authKey, $stdout, $stderr, $stdin, @silent)
|
|
384
343
|
rescue
|
|
385
|
-
error("Can't connect IO: #{$!}")
|
|
344
|
+
error('tjc_no_io_connect', "Can't connect IO: #{$!}")
|
|
386
345
|
end
|
|
387
346
|
end
|
|
388
347
|
|
|
@@ -390,12 +349,12 @@ EOT
|
|
|
390
349
|
begin
|
|
391
350
|
@reportServer.disconnect(@rs_authKey)
|
|
392
351
|
rescue
|
|
393
|
-
error("Can't disconnect IO: #{$!}")
|
|
352
|
+
error('tjc_no_io_disconnect', "Can't disconnect IO: #{$!}")
|
|
394
353
|
end
|
|
395
354
|
begin
|
|
396
355
|
@reportServer.terminate(@rs_authKey)
|
|
397
356
|
rescue
|
|
398
|
-
error("Report server termination failed: #{$!}")
|
|
357
|
+
error('tjc_srv_term_failed', "Report server termination failed: #{$!}")
|
|
399
358
|
end
|
|
400
359
|
@reportServer = nil
|
|
401
360
|
@rs_uri = nil
|
|
@@ -411,7 +370,8 @@ EOT
|
|
|
411
370
|
begin
|
|
412
371
|
return @broker.command(@authKey, command, args)
|
|
413
372
|
rescue
|
|
414
|
-
error(
|
|
373
|
+
error('tjc_call_srv_failed',
|
|
374
|
+
"Call to TaskJuggler server on host '#{@host}' " +
|
|
415
375
|
"port #{@port} failed: #{$!}")
|
|
416
376
|
end
|
|
417
377
|
end
|
|
@@ -445,23 +405,13 @@ EOT
|
|
|
445
405
|
return false
|
|
446
406
|
end
|
|
447
407
|
rescue
|
|
448
|
-
error(
|
|
408
|
+
error('tjc_canont_add_file',
|
|
409
|
+
"Cannot add file #{file} to ReportServer")
|
|
449
410
|
end
|
|
450
411
|
end
|
|
451
412
|
true
|
|
452
413
|
end
|
|
453
414
|
|
|
454
|
-
def info(message)
|
|
455
|
-
return if @silent
|
|
456
|
-
$stdout.puts "#{message}"
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
def error(message, exitVal = 1)
|
|
460
|
-
$stderr.puts "ERROR: #{message}"
|
|
461
|
-
# Don't call exit in unsafe mode. Raise a StandardError instead.
|
|
462
|
-
raise TjRuntimeError
|
|
463
|
-
end
|
|
464
|
-
|
|
465
415
|
end
|
|
466
416
|
|
|
467
417
|
end
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
require 'drb'
|
|
15
15
|
require 'taskjuggler/Tj3AppBase'
|
|
16
|
-
require 'taskjuggler/
|
|
16
|
+
require 'taskjuggler/MessageHandler'
|
|
17
17
|
require 'taskjuggler/daemon/ProjectBroker'
|
|
18
18
|
|
|
19
19
|
# Name of the application
|
|
@@ -27,14 +27,17 @@ class TaskJuggler
|
|
|
27
27
|
super
|
|
28
28
|
@mandatoryArgs = '[<tjp file> [<tji file> ...] ...]'
|
|
29
29
|
|
|
30
|
-
@
|
|
31
|
-
@
|
|
32
|
-
@
|
|
30
|
+
@mhi = MessageHandlerInstance.instance
|
|
31
|
+
@mhi.logFile = File.join(Dir.getwd, "/#{AppConfig.appName}.log")
|
|
32
|
+
@mhi.appName = AppConfig.appName
|
|
33
|
+
# By default show only warnings and more serious messages.
|
|
34
|
+
@mhi.outputLevel = :warning
|
|
33
35
|
@daemonize = true
|
|
34
36
|
@uriFile = File.join(Dir.getwd, '.tj3d.uri')
|
|
35
37
|
@port = nil
|
|
36
38
|
@webServer = false
|
|
37
|
-
@webServerPort =
|
|
39
|
+
@webServerPort = 8080
|
|
40
|
+
@webdPidFile = File.join(Dir.getwd, ".tj3webd-#{$$}.pid").untaint
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def processArguments(argv)
|
|
@@ -69,33 +72,65 @@ EOT
|
|
|
69
72
|
'requests (Default: 8080).')) do |arg|
|
|
70
73
|
@webServerPort = arg
|
|
71
74
|
end
|
|
75
|
+
|
|
72
76
|
end
|
|
73
77
|
end
|
|
74
78
|
|
|
75
79
|
def appMain(files)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
80
|
+
broker = ProjectBroker.new
|
|
81
|
+
@rc.configure(self, 'global')
|
|
82
|
+
@rc.configure(@mhi, 'global.log')
|
|
83
|
+
@rc.configure(broker, 'global')
|
|
84
|
+
@rc.configure(broker, 'daemon')
|
|
85
|
+
|
|
86
|
+
# Set some config variables if corresponding data was provided via the
|
|
87
|
+
# command line.
|
|
88
|
+
broker.port = @port if @port
|
|
89
|
+
broker.uriFile = @uriFile.untaint
|
|
90
|
+
broker.projectFiles = sortInputFiles(files) unless files.empty?
|
|
91
|
+
broker.daemonize = @daemonize
|
|
92
|
+
# Create log files for standard IO for each child process if the daemon
|
|
93
|
+
# is not disconnected from the terminal.
|
|
94
|
+
broker.logStdIO = !@daemonize
|
|
95
|
+
|
|
96
|
+
if @webServer
|
|
97
|
+
webdCommand = "tj3webd --webserver-port #{@webServerPort} " +
|
|
98
|
+
"--pidfile #{@webdPidFile}"
|
|
99
|
+
# Also start the web server as a separate process. We keep the PID, so
|
|
100
|
+
# we can terminate that process again when we exit the daemon.
|
|
101
|
+
begin
|
|
102
|
+
`#{webdCommand}`
|
|
103
|
+
rescue
|
|
104
|
+
error('tj3webd_start_failed', "Could not start tj3webd: #{$!}")
|
|
105
|
+
end
|
|
106
|
+
info('web_server_started', "Web server started as '#{webdCommand}'")
|
|
98
107
|
end
|
|
108
|
+
|
|
109
|
+
broker.start
|
|
110
|
+
|
|
111
|
+
if @webServer
|
|
112
|
+
pid = nil
|
|
113
|
+
begin
|
|
114
|
+
# Read the PID of the web server from the PID file.
|
|
115
|
+
File.open(@webdPidFile, 'r') do |f|
|
|
116
|
+
pid = f.read.to_i
|
|
117
|
+
end
|
|
118
|
+
rescue
|
|
119
|
+
warning('cannot_read_webd_pidfile',
|
|
120
|
+
"Cannot read tj3webd PID file (#{@webdPidFile}): #{$!}")
|
|
121
|
+
end
|
|
122
|
+
# If we have started the web server, we are also trying to terminate
|
|
123
|
+
# that process again.
|
|
124
|
+
begin
|
|
125
|
+
Process.kill("TERM", pid)
|
|
126
|
+
rescue
|
|
127
|
+
warning('tj3webd_term_failed',
|
|
128
|
+
"Could not terminate web server: #{$!}")
|
|
129
|
+
end
|
|
130
|
+
info('web_server_terminated', "Web server with PID #{pid} terminated")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
0
|
|
99
134
|
end
|
|
100
135
|
|
|
101
136
|
private
|
|
@@ -128,11 +163,13 @@ EOT
|
|
|
128
163
|
# .tji files are optional. But if they are specified, they must
|
|
129
164
|
# always follow the master file in the list.
|
|
130
165
|
if project.nil?
|
|
131
|
-
error(
|
|
166
|
+
error('tj3d_tji_before_tjp',
|
|
167
|
+
"You must specify a '.tjp' file before the '.tji' files")
|
|
132
168
|
end
|
|
133
169
|
project << file
|
|
134
170
|
else
|
|
135
|
-
error(
|
|
171
|
+
error('tj3d_no_file_Ext',
|
|
172
|
+
"Project files must have a '.tjp' or '.tji' extension")
|
|
136
173
|
end
|
|
137
174
|
end
|
|
138
175
|
|