taskjuggler 3.7.1 → 3.7.2

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.
Files changed (336) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +18 -0
  3. data/Rakefile +4 -1
  4. data/data/tjp.vim +13 -13
  5. data/examples/ProjectTemplate/template.tjp +3 -3
  6. data/examples/Tutorial/tutorial.tjp +3 -3
  7. data/lib/taskjuggler/AppConfig.rb +1 -1
  8. data/lib/taskjuggler/BatchProcessor.rb +68 -57
  9. data/lib/taskjuggler/FileList.rb +1 -1
  10. data/lib/taskjuggler/MessageHandler.rb +0 -1
  11. data/lib/taskjuggler/ResourceScenario.rb +29 -1
  12. data/lib/taskjuggler/RuntimeConfig.rb +1 -1
  13. data/lib/taskjuggler/SheetHandlerBase.rb +5 -4
  14. data/lib/taskjuggler/StatusSheetReceiver.rb +2 -2
  15. data/lib/taskjuggler/StatusSheetSender.rb +1 -1
  16. data/lib/taskjuggler/TaskScenario.rb +7 -2
  17. data/lib/taskjuggler/TextParser/Scanner.rb +1 -1
  18. data/lib/taskjuggler/TimeSheetReceiver.rb +2 -2
  19. data/lib/taskjuggler/TimeSheetSender.rb +1 -1
  20. data/lib/taskjuggler/TimeSheets.rb +3 -2
  21. data/lib/taskjuggler/TjpSyntaxRules.rb +9 -3
  22. data/lib/taskjuggler/XMLDocument.rb +1 -1
  23. data/lib/taskjuggler/apps/Tj3Daemon.rb +2 -2
  24. data/lib/taskjuggler/apps/Tj3WebD.rb +1 -1
  25. data/lib/taskjuggler/daemon/ProjectServer.rb +2 -2
  26. data/lib/taskjuggler/reports/CSVFile.rb +1 -1
  27. data/lib/taskjuggler/reports/MspXmlRE.rb +5 -3
  28. data/lib/taskjuggler/reports/Report.rb +5 -5
  29. data/lib/taskjuggler/reports/TraceReport.rb +2 -2
  30. data/lib/taskjuggler/version.rb +1 -1
  31. data/man/tj3.1 +1 -1
  32. data/man/tj3client.1 +1 -1
  33. data/man/tj3d.1 +1 -1
  34. data/man/tj3man.1 +1 -1
  35. data/man/tj3ss_receiver.1 +1 -1
  36. data/man/tj3ss_sender.1 +2 -2
  37. data/man/tj3ts_receiver.1 +1 -1
  38. data/man/tj3ts_sender.1 +2 -2
  39. data/man/tj3ts_summary.1 +2 -2
  40. data/man/tj3webd.1 +1 -1
  41. data/manual/html/Day_To_Day_Juggling.html +1 -1
  42. data/manual/html/Getting_Started.html +1 -1
  43. data/manual/html/How_To_Contribute.html +1 -1
  44. data/manual/html/Installation.html +1 -1
  45. data/manual/html/Intro.html +1 -1
  46. data/manual/html/List_Attributes.html +1 -1
  47. data/manual/html/Reporting_Bugs.html +1 -1
  48. data/manual/html/Rich_Text_Attributes.html +1 -1
  49. data/manual/html/Software.html +1 -1
  50. data/manual/html/TaskJuggler_2x_Migration.html +1 -1
  51. data/manual/html/TaskJuggler_Internals.html +1 -1
  52. data/manual/html/The_TaskJuggler_Syntax.html +1 -1
  53. data/manual/html/Tutorial.html +1 -1
  54. data/manual/html/account.html +2 -2
  55. data/manual/html/account.task.html +1 -1
  56. data/manual/html/accountprefix.html +1 -1
  57. data/manual/html/accountreport.html +2 -2
  58. data/manual/html/accountroot.html +2 -2
  59. data/manual/html/active.html +1 -1
  60. data/manual/html/adopt.task.html +1 -1
  61. data/manual/html/aggregate.html +1 -1
  62. data/manual/html/alert.html +1 -1
  63. data/manual/html/alertlevels.html +1 -1
  64. data/manual/html/allocate.html +1 -1
  65. data/manual/html/alphabet.html +1 -1
  66. data/manual/html/alternative.html +1 -1
  67. data/manual/html/author.html +1 -1
  68. data/manual/html/auxdir.html +1 -1
  69. data/manual/html/auxdir.report.html +2 -2
  70. data/manual/html/balance.html +2 -2
  71. data/manual/html/booking.resource.html +1 -1
  72. data/manual/html/booking.task.html +1 -1
  73. data/manual/html/caption.html +2 -2
  74. data/manual/html/cellcolor.column.html +1 -1
  75. data/manual/html/celltext.column.html +1 -1
  76. data/manual/html/center.html +2 -2
  77. data/manual/html/charge.html +1 -1
  78. data/manual/html/chargeset.html +1 -1
  79. data/manual/html/columnid.html +5 -2
  80. data/manual/html/columns.html +2 -2
  81. data/manual/html/complete.html +1 -1
  82. data/manual/html/copyright.html +1 -1
  83. data/manual/html/credits.html +1 -1
  84. data/manual/html/currency.html +1 -1
  85. data/manual/html/currencyformat.html +2 -2
  86. data/manual/html/dailymax.html +1 -1
  87. data/manual/html/dailymin.html +1 -1
  88. data/manual/html/dailyworkinghours.html +1 -1
  89. data/manual/html/date.extend.html +1 -1
  90. data/manual/html/date.html +1 -1
  91. data/manual/html/definitions.html +1 -1
  92. data/manual/html/depends.html +1 -1
  93. data/manual/html/details.html +1 -1
  94. data/manual/html/disabled.html +1 -1
  95. data/manual/html/duration.html +1 -1
  96. data/manual/html/efficiency.html +1 -1
  97. data/manual/html/effort.html +1 -1
  98. data/manual/html/effortdone.html +1 -1
  99. data/manual/html/effortleft.html +1 -1
  100. data/manual/html/email.html +1 -1
  101. data/manual/html/enabled.html +1 -1
  102. data/manual/html/end.column.html +1 -1
  103. data/manual/html/end.html +1 -1
  104. data/manual/html/end.limit.html +1 -1
  105. data/manual/html/end.report.html +2 -2
  106. data/manual/html/end.timesheet.html +1 -1
  107. data/manual/html/endcredit.html +1 -1
  108. data/manual/html/epilog.html +2 -2
  109. data/manual/html/export.html +2 -2
  110. data/manual/html/extend.html +1 -1
  111. data/manual/html/fail.html +1 -1
  112. data/manual/html/fdl.html +1 -1
  113. data/manual/html/flags.account.html +1 -1
  114. data/manual/html/flags.html +1 -1
  115. data/manual/html/flags.journalentry.html +1 -1
  116. data/manual/html/flags.report.html +2 -2
  117. data/manual/html/flags.resource.html +1 -1
  118. data/manual/html/flags.statussheet.html +1 -1
  119. data/manual/html/flags.task.html +1 -1
  120. data/manual/html/flags.timesheet.html +1 -1
  121. data/manual/html/fontcolor.column.html +1 -1
  122. data/manual/html/footer.html +2 -2
  123. data/manual/html/formats.export.html +1 -1
  124. data/manual/html/formats.html +2 -2
  125. data/manual/html/functions.html +1 -1
  126. data/manual/html/gapduration.html +1 -1
  127. data/manual/html/gaplength.html +1 -1
  128. data/manual/html/halign.center.html +1 -1
  129. data/manual/html/halign.column.html +1 -1
  130. data/manual/html/halign.left.html +1 -1
  131. data/manual/html/halign.right.html +1 -1
  132. data/manual/html/hasalert.html +1 -1
  133. data/manual/html/header.html +2 -2
  134. data/manual/html/headline.html +2 -2
  135. data/manual/html/height.html +2 -2
  136. data/manual/html/hideaccount.html +2 -2
  137. data/manual/html/hidejournalentry.html +2 -2
  138. data/manual/html/hidereport.html +1 -1
  139. data/manual/html/hideresource.html +2 -2
  140. data/manual/html/hidetask.html +2 -2
  141. data/manual/html/icalreport.html +1 -1
  142. data/manual/html/include.macro.html +1 -1
  143. data/manual/html/include.project.html +1 -1
  144. data/manual/html/include.properties.html +1 -1
  145. data/manual/html/index.html +1 -1
  146. data/manual/html/inherit.extend.html +1 -1
  147. data/manual/html/interval1.html +1 -1
  148. data/manual/html/interval2.html +1 -1
  149. data/manual/html/interval3.html +1 -1
  150. data/manual/html/interval4.html +1 -1
  151. data/manual/html/isactive.html +1 -1
  152. data/manual/html/ischildof.html +1 -1
  153. data/manual/html/isdependencyof.html +1 -1
  154. data/manual/html/isdutyof.html +1 -1
  155. data/manual/html/isfeatureof.html +1 -1
  156. data/manual/html/isleaf.html +1 -1
  157. data/manual/html/ismilestone.html +1 -1
  158. data/manual/html/isongoing.html +1 -1
  159. data/manual/html/isresource.html +1 -1
  160. data/manual/html/isresponsibilityof.html +1 -1
  161. data/manual/html/istask.html +1 -1
  162. data/manual/html/isvalid.html +1 -1
  163. data/manual/html/journalattributes.html +2 -2
  164. data/manual/html/journalentry.html +1 -1
  165. data/manual/html/journalmode.html +2 -2
  166. data/manual/html/leaveallowance.html +1 -1
  167. data/manual/html/leaves.html +1 -1
  168. data/manual/html/left.html +2 -2
  169. data/manual/html/length.html +1 -1
  170. data/manual/html/limits.allocate.html +1 -1
  171. data/manual/html/limits.html +1 -1
  172. data/manual/html/limits.resource.html +1 -1
  173. data/manual/html/limits.task.html +1 -1
  174. data/manual/html/listitem.column.html +1 -1
  175. data/manual/html/listtype.column.html +1 -1
  176. data/manual/html/loadunit.html +2 -2
  177. data/manual/html/logicalexpression.html +1 -1
  178. data/manual/html/logicalflagexpression.html +1 -1
  179. data/manual/html/macro.html +1 -1
  180. data/manual/html/managers.html +1 -1
  181. data/manual/html/mandatory.html +1 -1
  182. data/manual/html/markdate.html +1 -1
  183. data/manual/html/maxend.html +1 -1
  184. data/manual/html/maximum.html +1 -1
  185. data/manual/html/maxstart.html +1 -1
  186. data/manual/html/milestone.html +1 -1
  187. data/manual/html/minend.html +1 -1
  188. data/manual/html/minimum.html +1 -1
  189. data/manual/html/minstart.html +1 -1
  190. data/manual/html/monthlymax.html +1 -1
  191. data/manual/html/monthlymin.html +1 -1
  192. data/manual/html/navbar.html +1 -1
  193. data/manual/html/navigator.html +1 -1
  194. data/manual/html/newtask.html +1 -1
  195. data/manual/html/nikureport.html +1 -1
  196. data/manual/html/note.task.html +1 -1
  197. data/manual/html/novevents.html +1 -1
  198. data/manual/html/now.html +1 -1
  199. data/manual/html/number.extend.html +1 -1
  200. data/manual/html/numberformat.html +2 -2
  201. data/manual/html/onend.html +1 -1
  202. data/manual/html/onstart.html +1 -1
  203. data/manual/html/opennodes.html +2 -2
  204. data/manual/html/outputdir.html +1 -1
  205. data/manual/html/overtime.booking.html +1 -1
  206. data/manual/html/period.column.html +1 -1
  207. data/manual/html/period.limit.html +1 -1
  208. data/manual/html/period.report.html +2 -2
  209. data/manual/html/period.task.html +1 -1
  210. data/manual/html/persistent.html +1 -1
  211. data/manual/html/precedes.html +1 -1
  212. data/manual/html/priority.html +1 -1
  213. data/manual/html/priority.timesheet.html +1 -1
  214. data/manual/html/project.html +1 -1
  215. data/manual/html/projectid.html +1 -1
  216. data/manual/html/projectid.task.html +1 -1
  217. data/manual/html/projectids.html +1 -1
  218. data/manual/html/projection.html +1 -1
  219. data/manual/html/prolog.html +2 -2
  220. data/manual/html/properties.html +1 -1
  221. data/manual/html/purge.html +2 -2
  222. data/manual/html/rate.html +1 -1
  223. data/manual/html/rate.resource.html +1 -1
  224. data/manual/html/rawhtmlhead.html +2 -2
  225. data/manual/html/reference.extend.html +1 -1
  226. data/manual/html/remaining.html +1 -1
  227. data/manual/html/replace.html +1 -1
  228. data/manual/html/reportprefix.html +1 -1
  229. data/manual/html/resource.html +1 -1
  230. data/manual/html/resourceattributes.html +1 -1
  231. data/manual/html/resourceprefix.html +1 -1
  232. data/manual/html/resourcereport.html +2 -2
  233. data/manual/html/resourceroot.html +2 -2
  234. data/manual/html/resources.limit.html +1 -1
  235. data/manual/html/responsible.html +1 -1
  236. data/manual/html/richtext.extend.html +1 -1
  237. data/manual/html/right.html +2 -2
  238. data/manual/html/rollupaccount.html +2 -2
  239. data/manual/html/rollupresource.html +2 -2
  240. data/manual/html/rolluptask.html +2 -2
  241. data/manual/html/scale.column.html +1 -1
  242. data/manual/html/scenario.html +1 -1
  243. data/manual/html/scenario.ical.html +1 -1
  244. data/manual/html/scenarios.export.html +1 -1
  245. data/manual/html/scenarios.html +2 -2
  246. data/manual/html/scenariospecific.extend.html +1 -1
  247. data/manual/html/scheduled.html +1 -1
  248. data/manual/html/scheduling.html +1 -1
  249. data/manual/html/schedulingmode.html +1 -1
  250. data/manual/html/select.html +1 -1
  251. data/manual/html/selfcontained.html +2 -2
  252. data/manual/html/shift.allocate.html +1 -1
  253. data/manual/html/shift.html +1 -1
  254. data/manual/html/shift.resource.html +1 -1
  255. data/manual/html/shift.task.html +1 -1
  256. data/manual/html/shift.timesheet.html +1 -1
  257. data/manual/html/shifts.allocate.html +1 -1
  258. data/manual/html/shifts.resource.html +1 -1
  259. data/manual/html/shifts.task.html +1 -1
  260. data/manual/html/shorttimeformat.html +1 -1
  261. data/manual/html/sloppy.booking.html +1 -1
  262. data/manual/html/sloppy.projection.html +1 -1
  263. data/manual/html/sortaccounts.html +2 -2
  264. data/manual/html/sortjournalentries.html +2 -2
  265. data/manual/html/sortresources.html +2 -2
  266. data/manual/html/sorttasks.html +2 -2
  267. data/manual/html/start.column.html +1 -1
  268. data/manual/html/start.html +1 -1
  269. data/manual/html/start.limit.html +1 -1
  270. data/manual/html/start.report.html +2 -2
  271. data/manual/html/startcredit.html +1 -1
  272. data/manual/html/status.statussheet.html +1 -1
  273. data/manual/html/status.timesheet.html +1 -1
  274. data/manual/html/statussheet.html +1 -1
  275. data/manual/html/statussheetreport.html +1 -1
  276. data/manual/html/strict.projection.html +1 -1
  277. data/manual/html/summary.html +1 -1
  278. data/manual/html/supplement.html +1 -1
  279. data/manual/html/supplement.resource.html +1 -1
  280. data/manual/html/supplement.task.html +1 -1
  281. data/manual/html/tagfile.html +1 -1
  282. data/manual/html/task.html +1 -1
  283. data/manual/html/task.statussheet.html +1 -1
  284. data/manual/html/task.timesheet.html +1 -1
  285. data/manual/html/taskattributes.html +1 -1
  286. data/manual/html/taskprefix.html +1 -1
  287. data/manual/html/taskreport.html +2 -2
  288. data/manual/html/taskroot.export.html +1 -1
  289. data/manual/html/taskroot.html +2 -2
  290. data/manual/html/text.extend.html +1 -1
  291. data/manual/html/textreport.html +2 -2
  292. data/manual/html/timeformat.html +2 -2
  293. data/manual/html/timeformat1.html +1 -1
  294. data/manual/html/timeformat2.html +1 -1
  295. data/manual/html/timeoff.nikureport.html +1 -1
  296. data/manual/html/timesheet.html +1 -1
  297. data/manual/html/timesheetreport.html +1 -1
  298. data/manual/html/timezone.export.html +1 -1
  299. data/manual/html/timezone.html +1 -1
  300. data/manual/html/timezone.report.html +2 -2
  301. data/manual/html/timezone.shift.html +1 -1
  302. data/manual/html/timingresolution.html +1 -1
  303. data/manual/html/title.column.html +1 -1
  304. data/manual/html/title.html +2 -2
  305. data/manual/html/toc.html +3 -3
  306. data/manual/html/tooltip.column.html +1 -1
  307. data/manual/html/tracereport.html +2 -2
  308. data/manual/html/trackingscenario.html +1 -1
  309. data/manual/html/treelevel.html +1 -1
  310. data/manual/html/vacation.html +1 -1
  311. data/manual/html/vacation.resource.html +1 -1
  312. data/manual/html/vacation.shift.html +1 -1
  313. data/manual/html/warn.html +1 -1
  314. data/manual/html/weeklymax.html +1 -1
  315. data/manual/html/weeklymin.html +1 -1
  316. data/manual/html/weekstartsmonday.html +1 -1
  317. data/manual/html/weekstartssunday.html +1 -1
  318. data/manual/html/width.column.html +1 -1
  319. data/manual/html/width.html +2 -2
  320. data/manual/html/work.html +1 -1
  321. data/manual/html/workinghours.project.html +1 -1
  322. data/manual/html/workinghours.resource.html +1 -1
  323. data/manual/html/workinghours.shift.html +1 -1
  324. data/manual/html/yearlyworkingdays.html +1 -1
  325. data/spec/TraceReport_spec.rb +1 -1
  326. data/spec/support/DaemonControl.rb +2 -3
  327. data/taskjuggler.gemspec +0 -3
  328. data/tasks/gem.rake +0 -1
  329. data/tasks/help2man.rake +1 -1
  330. data/tasks/manual.rake +1 -1
  331. data/test/TestSuite/CSV-Reports/quotes.tjp +20 -0
  332. data/test/TestSuite/CSV-Reports/refs/quotes.csv +5 -0
  333. data/test/TestSuite/Syntax/Correct/template.tjp +3 -3
  334. data/test/TestSuite/Syntax/Correct/tutorial.tjp +3 -3
  335. data/test/test_BatchProcessor.rb +6 -3
  336. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5a0de8b9d1e062a746ba217051e7351d2481644f649f585528c7caabd6b69a9
4
- data.tar.gz: 6223c62cafa2db90ae8d4cc8759f5b5cff458b884833a4b6355284df450459c5
3
+ metadata.gz: ac8d1b5b2a3a8a3de01a39de2ef9533e1c86ade627b4a27ccf83427dac988093
4
+ data.tar.gz: 7dea4a421b72b1a6645b0699bfb4076eaa4fc46fcd1274066503dc2c36d7a343
5
5
  SHA512:
6
- metadata.gz: 70a76a0185eba07950375e0b44bcb32f74bada5b652d96f131fe4bf62cba6dabbd3d90b6f3216159e3d826836a74e228e1ef278b43f4bfbc6743c10aee41a48c
7
- data.tar.gz: 76324478980524c4c7a6be0039388d6116db7891037d179e094723c7ca74d7b19325c9668a0dc626e78e7b2346614a32b24a48aa53d1430c70773aa18a35c462
6
+ metadata.gz: a07a210795fb27f09a3a8cc09fcef2ceb21c0f08d47cedb8655b3cc1df8201b7f309278dd1464961a5c9e06164d12ae85f979435a3007701428fe852801ffccc
7
+ data.tar.gz: dd87f1321f59cbd9399a2b25ab7d5f3d16a01952579f3b54abfb7e2794a0f322c047e4bfb93434569eaea9cf1fd98a7ca6737ed20bea9e5c00816c6ab0f64bc4
data/CHANGELOG CHANGED
@@ -1,3 +1,21 @@
1
+ = Release 3.7.2 (2023-02-25)
2
+
3
+ == New Features
4
+
5
+ * The 'duties' column now supports the 'listitem' attribute.
6
+
7
+ == Bug Fixes
8
+
9
+ * File.exists? is no longer supported in Ruby 3.2.x
10
+ * Attempt to fix MS Project XML export for newer MSP versions.
11
+ * Eliminate use of useless variable
12
+ * Fix race condition that surfaces when using Ruby 3.x.
13
+ * Don't crash on division by zero for timesheets shorter than 1 week
14
+ * Properly escape double quotes in CSV file strings.
15
+ * Don't crash if task is overspeficied.
16
+ * Queries in listitems for some columns now respect scope property
17
+
18
+
1
19
  = Release 3.7.1 (2020-03-14)
2
20
 
3
21
  * Bumping version to 3.7.1
data/Rakefile CHANGED
@@ -4,10 +4,13 @@ $:.unshift File.join(File.dirname(__FILE__))
4
4
  lib = File.expand_path('../lib', __FILE__)
5
5
  $:.unshift lib unless $:.include?(lib)
6
6
 
7
+ require 'rake'
8
+ require 'rspec'
7
9
  require 'rake/clean'
10
+ require 'bundler/gem_tasks'
8
11
 
9
12
  Dir.glob( 'tasks/*.rake').each do |fn|
10
- begin
13
+ begin
11
14
  load fn;
12
15
  rescue LoadError
13
16
  puts "#{fn.split('/')[1]} tasks unavailable: #{$!}"
data/data/tjp.vim CHANGED
@@ -1,7 +1,7 @@
1
1
  " Vim syntax file
2
2
  " Language: TaskJuggler
3
3
  " Maintainer: TaskJuggler Developers <taskjuggler-devel@googlegroups.com>
4
- " Last Change: 2020-03-14 17:32:05 +0100
4
+ " Last Change: 2023-02-25 11:11:12 +0100
5
5
  " This file was automatically generated by VimSyntax.rb
6
6
 
7
7
  if exists("b:current_syntax")
@@ -21,6 +21,10 @@ syn keyword tjp_macro macro contained
21
21
  syn keyword tjp_project project contained
22
22
  syn keyword tjp_supplement supplement contained
23
23
 
24
+ syn keyword tjp_account account contained
25
+ hi def link tjp_account Function
26
+ syn keyword tjp_accountreport accountreport contained
27
+ hi def link tjp_accountreport Function
24
28
  syn keyword tjp_export export contained
25
29
  hi def link tjp_export Function
26
30
  syn keyword tjp_nikureport nikureport contained
@@ -47,11 +51,13 @@ syn keyword tjp_timesheetreport timesheetreport contained
47
51
  hi def link tjp_timesheetreport Function
48
52
  syn keyword tjp_tracereport tracereport contained
49
53
  hi def link tjp_tracereport Function
50
- syn keyword tjp_account account contained
51
- hi def link tjp_account Function
52
- syn keyword tjp_accountreport accountreport contained
53
- hi def link tjp_accountreport Function
54
54
 
55
+ syn keyword tjp_aggregate aggregate contained
56
+ hi def link tjp_aggregate Type
57
+ syn keyword tjp_credits credits contained
58
+ hi def link tjp_credits Type
59
+ syn keyword tjp_flags_account flags contained
60
+ hi def link tjp_flags_account Type
55
61
  syn keyword tjp_allocate allocate contained
56
62
  hi def link tjp_allocate Type
57
63
  syn keyword tjp_alternative alternative contained
@@ -646,12 +652,6 @@ syn keyword tjp_workinghours_resource workinghours contained
646
652
  hi def link tjp_workinghours_resource Type
647
653
  syn keyword tjp_workinghours_shift workinghours contained
648
654
  hi def link tjp_workinghours_shift Type
649
- syn keyword tjp_aggregate aggregate contained
650
- hi def link tjp_aggregate Type
651
- syn keyword tjp_credits credits contained
652
- hi def link tjp_credits Type
653
- syn keyword tjp_flags_account flags contained
654
- hi def link tjp_flags_account Type
655
655
 
656
656
  syn match tjparg contained /\${.*}/
657
657
  syn match tjpcomment /#.*$/
@@ -662,6 +662,8 @@ syn match tjpdate /\s\d\{4}-\d\{1,2}-\d\{1,2}\(-\d\{1,2}:\d\{1,2}\(:\d\{1,2}\)\?
662
662
  syn match tjptime /\s\d\{1,2}:\d\d\(:\d\d\)\?/
663
663
 
664
664
  syn cluster tjpcommon contains=tjpcomment,tjpdate,tjptime,tjpstring,tjpnumber
665
+ syn region tjpblk_account start=/^\s*account\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_account,tjp_account,tjpblk_account,tjp_aggregate,tjp_credits,tjp_flags_account
666
+ syn region tjpblk_accountreport start=/^\s*accountreport\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_accountreport,tjp_accountroot,tjp_auxdir_report,tjp_balance,tjp_caption,tjp_center,tjp_columns,tjpblk_columns,tjp_currencyformat,tjp_end_report,tjp_epilog,tjp_flags_report,tjp_footer,tjp_formats,tjp_header,tjp_headline,tjp_hidejournalentry,tjp_hideaccount,tjp_hideresource,tjp_hidetask,tjp_height,tjp_journalattributes,tjp_journalmode,tjp_left,tjp_loadunit,tjp_numberformat,tjp_opennodes,tjp_period_report,tjp_prolog,tjp_purge,tjp_rawhtmlhead,tjp_accountreport,tjpblk_accountreport,tjp_export,tjpblk_export,tjp_resourcereport,tjpblk_resourcereport,tjp_taskreport,tjpblk_taskreport,tjp_textreport,tjpblk_textreport,tjp_tracereport,tjpblk_tracereport,tjp_right,tjp_rollupaccount,tjp_rollupresource,tjp_rolluptask,tjp_scenarios,tjp_selfcontained,tjp_sortaccounts,tjp_sortjournalentries,tjp_sortresources,tjp_sorttasks,tjp_start_report,tjp_resourceroot,tjp_taskroot,tjp_timeformat,tjp_timezone_report,tjp_title,tjp_width
665
667
  syn region tjpblk_allocate start=/^\s*allocate\s.*{\s*$/ end=/^\s*}\s*$/ transparent contains=@tjpcommon,tjp_allocate,tjp_alternative,tjp_select,tjp_persistent,tjp_mandatory,tjp_shifts_allocate contained
666
668
  syn region tjpblk_export start=/^\s*export\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_export,tjp_definitions,tjp_formats_export,tjp_hideresource,tjp_hidetask,tjp_loadunit,tjp_purge,tjp_end_report,tjp_period_report,tjp_accountreport,tjpblk_accountreport,tjp_export,tjpblk_export,tjp_resourcereport,tjpblk_resourcereport,tjp_taskreport,tjpblk_taskreport,tjp_textreport,tjpblk_textreport,tjp_tracereport,tjpblk_tracereport,tjp_start_report,tjp_resourceattributes,tjp_rollupresource,tjp_rolluptask,tjp_scenarios_export,tjp_taskattributes,tjp_taskroot_export,tjp_timezone_export
667
669
  syn region tjpblk_date_extend start=/^\s*date\s.*{\s*$/ end=/^\s*}\s*$/ transparent contains=@tjpcommon,tjp_date_extend,tjp_inherit_extend,tjp_scenariospecific_extend contained
@@ -712,8 +714,6 @@ syn region tjpblk_task_timesheet start=/^\s*task\s.*{\s*$/ end=/^\s*}\s*$/ trans
712
714
  syn region tjpblk_timesheetreport start=/^\s*timesheetreport\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_timesheetreport,tjp_hideresource,tjp_hidetask,tjp_end_report,tjp_period_report,tjp_start_report,tjp_sortresources,tjp_sorttasks
713
715
  syn region tjpblk_tracereport start=/^\s*tracereport\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_tracereport,tjp_accountroot,tjp_auxdir_report,tjp_balance,tjp_caption,tjp_center,tjp_columns,tjpblk_columns,tjp_currencyformat,tjp_end_report,tjp_epilog,tjp_flags_report,tjp_footer,tjp_formats,tjp_header,tjp_headline,tjp_hidejournalentry,tjp_hideaccount,tjp_hideresource,tjp_hidetask,tjp_height,tjp_journalattributes,tjp_journalmode,tjp_left,tjp_loadunit,tjp_numberformat,tjp_opennodes,tjp_period_report,tjp_prolog,tjp_purge,tjp_rawhtmlhead,tjp_accountreport,tjpblk_accountreport,tjp_export,tjpblk_export,tjp_resourcereport,tjpblk_resourcereport,tjp_taskreport,tjpblk_taskreport,tjp_textreport,tjpblk_textreport,tjp_tracereport,tjpblk_tracereport,tjp_right,tjp_rollupaccount,tjp_rollupresource,tjp_rolluptask,tjp_scenarios,tjp_selfcontained,tjp_sortaccounts,tjp_sortjournalentries,tjp_sortresources,tjp_sorttasks,tjp_start_report,tjp_resourceroot,tjp_taskroot,tjp_timeformat,tjp_timezone_report,tjp_title,tjp_width
714
716
  syn region tjpblk_status_timesheet start=/^\s*status\s.*{\s*$/ end=/^\s*}\s*$/ transparent contains=@tjpcommon,tjp_status_timesheet,tjp_details,tjp_flags_timesheet,tjp_summary contained
715
- syn region tjpblk_account start=/^\s*account\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_account,tjp_account,tjpblk_account,tjp_aggregate,tjp_credits,tjp_flags_account
716
- syn region tjpblk_accountreport start=/^\s*accountreport\s.*{\s*$/ end=/^\s*}\s*$/ transparent fold contains=@tjpcommon,tjp_accountreport,tjp_accountroot,tjp_auxdir_report,tjp_balance,tjp_caption,tjp_center,tjp_columns,tjpblk_columns,tjp_currencyformat,tjp_end_report,tjp_epilog,tjp_flags_report,tjp_footer,tjp_formats,tjp_header,tjp_headline,tjp_hidejournalentry,tjp_hideaccount,tjp_hideresource,tjp_hidetask,tjp_height,tjp_journalattributes,tjp_journalmode,tjp_left,tjp_loadunit,tjp_numberformat,tjp_opennodes,tjp_period_report,tjp_prolog,tjp_purge,tjp_rawhtmlhead,tjp_accountreport,tjpblk_accountreport,tjp_export,tjpblk_export,tjp_resourcereport,tjpblk_resourcereport,tjp_taskreport,tjpblk_taskreport,tjp_textreport,tjpblk_textreport,tjp_tracereport,tjpblk_tracereport,tjp_right,tjp_rollupaccount,tjp_rollupresource,tjp_rolluptask,tjp_scenarios,tjp_selfcontained,tjp_sortaccounts,tjp_sortjournalentries,tjp_sortresources,tjp_sorttasks,tjp_start_report,tjp_resourceroot,tjp_taskroot,tjp_timeformat,tjp_timezone_report,tjp_title,tjp_width
717
717
  syn region tjpblk_macro start=/macro\s\+\h\w*\s*\[/ end=/\]$/ transparent fold contains=ALL
718
718
  syn region tjpstring start=/"/ skip=/\\"/ end=/"/
719
719
  syn region tjpstring start=/'/ skip=/\\'/ end=/'/
@@ -242,9 +242,9 @@ taskreport overview "" {
242
242
  # Macro to set the background color of a cell according to the alert
243
243
  # level of the task.
244
244
  macro AlertColor [
245
- cellcolor plan.alert = 0 "#00D000" # green
246
- cellcolor plan.alert = 1 "#D0D000" # yellow
247
- cellcolor plan.alert = 2 "#D00000" # red
245
+ cellcolor plan.alert = 0 "#90FF90" # green
246
+ cellcolor plan.alert = 1 "#FFFF90" # yellow
247
+ cellcolor plan.alert = 2 "#FF9090" # red
248
248
  ]
249
249
 
250
250
  taskreport status "" {
@@ -405,9 +405,9 @@ taskreport overview "" {
405
405
  # Macro to set the background color of a cell according to the alert
406
406
  # level of the task.
407
407
  macro AlertColor [
408
- cellcolor plan.alert = 0 "#00D000" # green
409
- cellcolor plan.alert = 1 "#D0D000" # yellow
410
- cellcolor plan.alert = 2 "#D00000" # red
408
+ cellcolor plan.alert = 0 "#90FF90" # green
409
+ cellcolor plan.alert = 1 "#FFFF90" # yellow
410
+ cellcolor plan.alert = 2 "#FF9090" # red
411
411
  ]
412
412
 
413
413
  taskreport status "" {
@@ -109,7 +109,7 @@ class AppConfig
109
109
  dirs = dataSearchDirs(baseDir)
110
110
  # Remove non-existing directories from the list again
111
111
  dirs.delete_if do |dir|
112
- !File.exist?(dir.untaint)
112
+ !File.exist?(dir)
113
113
  end
114
114
  dirs
115
115
  end
@@ -69,16 +69,16 @@ class TaskJuggler
69
69
  def initialize(maxCpuCores)
70
70
  @maxCpuCores = maxCpuCores
71
71
  # Jobs submitted by calling queue() are put in the @toRunQueue. The
72
- # pusher Thread will pick them up and fork them off into another
72
+ # launcher Thread will pick them up and fork them off into another
73
73
  # process.
74
- @toRunQueue = Queue.new
74
+ @toRunQueue = [ ]
75
75
  # A hash that maps the JobInfo objects of running jobs by their PID.
76
76
  @runningJobs = { }
77
77
  # A list of jobs that wait to complete their writing.
78
78
  @spoolingJobs = [ ]
79
79
  # The wait() method will then clean the @toDropQueue, executes the post
80
80
  # processing block and removes all JobInfo related objects.
81
- @toDropQueue = Queue.new
81
+ @toDropQueue = []
82
82
 
83
83
  # A semaphore to guard accesses to @runningJobs, @spoolingJobs and
84
84
  # following shared data structures.
@@ -106,28 +106,34 @@ class TaskJuggler
106
106
  # to identify the job upon completion. +block+ is a Ruby code block to be
107
107
  # executed in a separate process.
108
108
  def queue(tag = nil, &block)
109
- raise 'You cannot call queue() while wait() is running!' if @jobsOut > 0
110
-
111
- # If this is the first queued job for this run, we have to start the
112
- # helper threads.
113
- if @jobsIn == 0
114
- # The JobInfo objects in the @toRunQueue are processed by the pusher
115
- # thread. It forkes off processes to execute the code block associated
116
- # with the JobInfo.
117
- @pusher = Thread.new { pusher }
118
- # The popper thread waits for terminated childs and picks up the
119
- # results.
120
- @popper = Thread.new { popper }
121
- # The grabber thread collects $stdout and $stderr data from each child
122
- # process and stores them in the corresponding JobInfo.
123
- @grabber = Thread.new { grabber }
124
- end
125
109
 
126
110
  # Create a new JobInfo object for the job and push it to the @toRunQueue.
127
- job = JobInfo.new(@jobsIn, block, tag)
128
- # Increase job counter
129
- @lock.synchronize { @jobsIn += 1 }
130
- @toRunQueue.push(job)
111
+ @lock.synchronize do
112
+ raise 'You cannot call queue() while wait() is running!' if @jobsOut > 0
113
+
114
+ # If this is the first queued job for this run, we have to start the
115
+ # helper threads.
116
+ if @jobsIn == 0
117
+ # The JobInfo objects in the @toRunQueue are processed by the
118
+ # launcher thread. It forkes off processes to execute the code
119
+ # block associated with the JobInfo.
120
+ @launcher = Thread.new { launcher }
121
+ # The receiver thread waits for terminated child processes and picks
122
+ # up the results.
123
+ @receiver = Thread.new { receiver }
124
+ # The grabber thread collects $stdout and $stderr data from each
125
+ # child process and stores them in the corresponding JobInfo.
126
+ @grabber = Thread.new { grabber }
127
+ end
128
+
129
+ # To track a job through the queues, we use a JobInfo object to hold
130
+ # all data associated with a job.
131
+ job = JobInfo.new(@jobsIn, block, tag)
132
+ # Increase job counter
133
+ @jobsIn += 1
134
+ # Push the job to the toRunQueue.
135
+ @toRunQueue.push(job)
136
+ end
131
137
  end
132
138
 
133
139
  # Wait for all jobs to complete. The code block will get the JobInfo
@@ -138,29 +144,27 @@ class TaskJuggler
138
144
 
139
145
  # When we have received as many jobs in the @toDropQueue than we have
140
146
  # started then we're done.
141
- while !@lock.synchronize { @jobsIn == @jobsOut }
142
- if @toDropQueue.empty?
143
- sleep(@timeout)
144
- else
145
- # We have completed jobs.
146
- while !@toDropQueue.empty?
147
- # Pop a job from the @toDropQueue and call the block with it.
148
- job = @toDropQueue.pop
149
- # Remove the job related entries from the housekeeping tables.
150
- @lock.synchronize { @jobsOut += 1 }
151
-
147
+ while @lock.synchronize { @jobsOut < @jobsIn }
148
+ job = nil
149
+ @lock.synchronize do
150
+ if !@toDropQueue.empty? && (job = @toDropQueue.pop)
152
151
  # Call the post-processing block that was passed to wait() with
153
152
  # the JobInfo object as argument.
153
+ @jobsOut += 1
154
154
  yield(job)
155
155
  end
156
156
  end
157
+
158
+ unless job
159
+ sleep(@timeout)
160
+ end
157
161
  end
158
162
 
159
163
  # Signal threads to stop
160
164
  @terminate = true
161
165
  # Wait for treads to finish
162
- @pusher.join
163
- @popper.join
166
+ @launcher.join
167
+ @receiver.join
164
168
  @grabber.join
165
169
 
166
170
  # Reset some variables so we can reuse the object for further job runs.
@@ -175,25 +179,22 @@ class TaskJuggler
175
179
 
176
180
  # This function runs in a separate thread to pop JobInfo items from the
177
181
  # @toRunQueue and create child processes for them.
178
- def pusher
182
+ def launcher
179
183
  # Run until the terminate flag is set.
180
184
  until @terminate
181
- if @toRunQueue.empty? ||
182
- @lock.synchronize{ @runningJobs.length >= @maxCpuCores }
185
+ job = nil
186
+ unless @lock.synchronize { @runningJobs.length < @maxCpuCores &&
187
+ (job = @toRunQueue.pop) }
183
188
  # We have no jobs in the @toRunQueue or all CPU cores in use already.
184
189
  sleep(@timeout)
185
190
  else
186
191
  @lock.synchronize do
187
- # Get a new job from the @toRunQueue
188
- job = @toRunQueue.pop
189
-
190
192
  job.openPipes
191
- # Add the receiver end of the pipe to the @pipes Array.
193
+ # Add the receiver end of the pipe to the pipes Arrays.
192
194
  @pipes << job.stdoutP
195
+ @pipes << job.stderrP
193
196
  # Map the pipe end to this JobInfo object.
194
197
  @pipeToJob[job.stdoutP] = job
195
- # Same for $stderr.
196
- @pipes << job.stderrP
197
198
  @pipeToJob[job.stderrP] = job
198
199
 
199
200
  pid = fork do
@@ -224,15 +225,20 @@ class TaskJuggler
224
225
 
225
226
  # This function runs in a separate thread to wait for completed jobs. It
226
227
  # waits for the process completion and stores the result in the
227
- # corresponding JobInfo object.
228
- def popper
228
+ # corresponding JobInfo object. Aborted jobs are pushed to the
229
+ # @toDropQueue while completed jobs are pushed to the @spoolingJobs queue.
230
+ def receiver
229
231
  until @terminate
230
- if @runningJobs.empty?
231
- # No pending jobs, wait a bit.
232
- sleep(@timeout)
233
- else
232
+ pid = retVal = nil
233
+ begin
234
234
  # Wait for the next job to complete.
235
235
  pid, retVal = Process.wait2
236
+ rescue Errno::ECHILD
237
+ # No running jobs. Wait a bit.
238
+ sleep(@timeout)
239
+ end
240
+
241
+ if pid && retVal
236
242
  job = nil
237
243
  @lock.synchronize do
238
244
  # Get the JobInfo object that corresponds to the process ID. The
@@ -242,7 +248,7 @@ class TaskJuggler
242
248
  # Remove the job from the @runningJobs Hash.
243
249
  @runningJobs.delete(pid)
244
250
  # Save the return value.
245
- job.retVal = retVal.dup
251
+ job.retVal = retVal.exitstatus
246
252
  if retVal.signaled?
247
253
  cleanPipes(job)
248
254
  # Aborted jobs will probably not send an EOT. So we fastrack
@@ -269,22 +275,27 @@ class TaskJuggler
269
275
  res = nil
270
276
  begin
271
277
  @lock.synchronize do
272
- if (res = select(@pipes, nil, @pipes, @timeout))
278
+ if (res = IO.select(@pipes, nil, nil, @timeout))
273
279
  # We have output data from at least one child. Check which pipe
274
280
  # actually triggered the select.
275
281
  res[0].each do |pipe|
276
282
  # Find the corresponding JobInfo object.
277
283
  job = @pipeToJob[pipe]
278
- # Store the output.
284
+
285
+ # Store the standard output.
279
286
  if pipe == job.stdoutP
280
287
  # Look for the EOT character to signal the end of the text.
281
- if (c = pipe.getc) == ?\004
288
+ if pipe.closed? || (c = pipe.read_nonblock(1)) == ?\004
282
289
  job.stdoutEOT = true
283
290
  else
284
291
  job.stdout << c
285
292
  end
286
- else
287
- if (c = pipe.getc) == ?\004
293
+ end
294
+
295
+ # Store the error output.
296
+ if pipe == job.stderrP
297
+ # Look for the EOT character to signal the end of the text.
298
+ if pipe.closed? || (c = pipe.read_nonblock(1)) == ?\004
288
299
  job.stderrEOT = true
289
300
  else
290
301
  job.stderr << c
@@ -17,7 +17,7 @@ class TaskJuggler
17
17
  class FileRecord
18
18
 
19
19
  def initialize(fileName)
20
- @name = fileName.dup.untaint
20
+ @name = fileName.dup
21
21
  @mtime = File.mtime(@name)
22
22
  end
23
23
 
@@ -248,7 +248,6 @@ class TaskJuggler
248
248
 
249
249
  timeStamp = Time.new.strftime("%Y-%m-%d %H:%M:%S")
250
250
  begin
251
- @logFile.untaint
252
251
  File.open(@logFile, 'a') do |f|
253
252
  f.write("#{timeStamp} #{type} #{@appName}[#{Process.pid}]: " +
254
253
  "#{message}\n")
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = ResourceScenario.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2020
7
7
  # by Chris Schlaeger <cs@taskjuggler.org>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -322,6 +322,34 @@ class TaskJuggler
322
322
  end
323
323
  end
324
324
 
325
+ # A list of the tasks that the resource has been allocated to work on in
326
+ # the report time frame.
327
+ def query_duties(query)
328
+ list = []
329
+ iv = TimeInterval.new(query.start, query.end)
330
+ @duties.each do |task|
331
+ if task.hasResourceAllocated?(@scenarioIdx, iv, @property)
332
+ if query.listItem
333
+ rti = RichText.new(query.listItem, RTFHandlers.create(@project)).
334
+ generateIntermediateFormat
335
+ unless rti
336
+ error('bad_resource_ts_query',
337
+ "Syntax error in query statement for task attribute " +
338
+ "'resources'.")
339
+ end
340
+ q = query.dup
341
+ q.property = task
342
+ q.scopeProperty = @property
343
+ rti.setQuery(q)
344
+ list << "<nowiki>#{rti.to_s}</nowiki>"
345
+ else
346
+ list << "<nowiki>#{task.name} (#{task.id})</nowiki>"
347
+ end
348
+ end
349
+ end
350
+ query.assignList(list)
351
+ end
352
+
325
353
  # The effort allocated to the Resource in the specified interval. In case a
326
354
  # Task is given as scope property only the effort allocated to this Task is
327
355
  # taken into account.
@@ -48,7 +48,7 @@ class RuntimeConfig
48
48
  return false unless (p = @config)
49
49
  sections.each do |sec|
50
50
  p = p['_' + sec]
51
- unless p
51
+ unless p && p.is_a?(Hash)
52
52
  debug("Section #{section} not found in config file")
53
53
  return false
54
54
  end
@@ -166,11 +166,12 @@ class TaskJuggler
166
166
  inReplyTo = nil)
167
167
  case @emailDeliveryMethod
168
168
  when 'smtp'
169
- Mail.defaults do
170
- delivery_method :smtp, {
169
+ settings_dto = {
171
170
  :address => @smtpServer,
172
- :port => 25
173
- }
171
+ :port => 25,
172
+ }
173
+ Mail.defaults do
174
+ delivery_method :smtp, settings_dto
174
175
  end
175
176
  when 'sendmail'
176
177
  Mail.defaults do
@@ -35,9 +35,9 @@ class TaskJuggler
35
35
  @logFile = 'statussheets.log'
36
36
 
37
37
  # Regular expression to identify status sheets.
38
- @sheetHeader = /^[ ]*statussheet\s([a-z][a-z0-9_]*)\s[0-9\-:+]*\s-\s([0-9]*-[0-9]*-[0-9]*)/
38
+ @sheetHeader = /^[ ]*statussheet\s([a-zA-Z_][a-zA-Z0-9_]*)\s[0-9\-:+]*\s-\s([0-9]*-[0-9]*-[0-9]*)/
39
39
  # Regular expression to extract the sheet signature (time period).
40
- @signatureFilter = /^[ ]*statussheet\s[a-z][a-z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
40
+ @signatureFilter = /^[ ]*statussheet\s[a-zA-Z_][a-zA-Z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
41
41
  @emailSubject = "Status report from %s for %s"
42
42
  end
43
43
 
@@ -39,7 +39,7 @@ class TaskJuggler
39
39
  # The log file
40
40
  @logFile = 'statussheets.log'
41
41
 
42
- @signatureFilter = /^[ ]*statussheet\s[a-z][a-z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
42
+ @signatureFilter = /^[ ]*statussheet\s[a-zA-Z_][a-zA-Z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
43
43
  @introText = <<'EOT'
44
44
  Please find enclosed your weekly status report template. Please fill out the
45
45
  form and send it back to the sender of this email. You can either use the
@@ -1508,6 +1508,7 @@ class TaskJuggler
1508
1508
  end
1509
1509
  q = query.dup
1510
1510
  q.property = resource
1511
+ q.scopeProperty = @property
1511
1512
  rti.setQuery(q)
1512
1513
  list << "<nowiki>#{rti.to_s}</nowiki>"
1513
1514
  else
@@ -2179,8 +2180,12 @@ class TaskJuggler
2179
2180
  # been set already.
2180
2181
  if @scheduled && @effort == 0 && @length == 0 && @duration == 0 &&
2181
2182
  !@milestone
2182
- @start = @project.idxToDate(firstSlotIdx) unless @start
2183
- @end = @project.idxToDate(lastSlotIdx + 1) unless @end
2183
+ unless @start || !firstSlotIdx
2184
+ @start = @project.idxToDate(firstSlotIdx)
2185
+ end
2186
+ unless @end || !lastSlotIdx
2187
+ @end = @project.idxToDate(lastSlotIdx + 1)
2188
+ end
2184
2189
  end
2185
2190
  end
2186
2191
 
@@ -169,7 +169,7 @@ class TaskJuggler::TextParser
169
169
 
170
170
  def initialize(fileName, log, textScanner)
171
171
  super(log, textScanner)
172
- @fileName = fileName.dup.untaint
172
+ @fileName = fileName.dup
173
173
  data = (fileName == '.' ? $stdin : File.new(@fileName, 'r')).read
174
174
  begin
175
175
  @stream = StringIO.new(data.forceUTF8Encoding)
@@ -32,9 +32,9 @@ class TaskJuggler
32
32
  @logFile = 'timesheets.log'
33
33
 
34
34
  # Regular expression to identify time sheets.
35
- @sheetHeader = /^[ ]*timesheet\s([a-z][a-z0-9_]*)\s[0-9\-:+]*\s-\s([0-9]*-[0-9]*-[0-9]*)/
35
+ @sheetHeader = /^[ ]*timesheet\s([a-zA-Z_][a-zA-Z0-9_]*)\s[0-9\-:+]*\s-\s([0-9]*-[0-9]*-[0-9]*)/
36
36
  # Regular expression to extract the sheet signature (time period).
37
- @signatureFilter = /^[ ]*timesheet\s[a-z][a-z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
37
+ @signatureFilter = /^[ ]*timesheet\s[a-zA-Z_][a-zA-Z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
38
38
  @emailSubject = "Report from %s for %s"
39
39
  end
40
40
 
@@ -38,7 +38,7 @@ class TaskJuggler
38
38
  # The log file
39
39
  @logFile = 'timesheets.log'
40
40
 
41
- @signatureFilter = /^[ ]*timesheet\s[a-z][a-z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
41
+ @signatureFilter = /^[ ]*timesheet\s[a-zA-Z_][a-zA-Z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
42
42
  @introText = <<'EOT'
43
43
  Please find enclosed your weekly report template. Please fill out
44
44
  the form and send it back to the sender of this email. You can either
@@ -325,9 +325,10 @@ class TaskJuggler
325
325
  def totalGrossWorkingSlots
326
326
  project = @resource.project
327
327
  # Calculate the number of weeks in the report
328
- weeksToReport = (@interval.end - @interval.start) / (60 * 60 * 24 * 7)
328
+ weeksToReport = (@interval.end - @interval.start).to_f /
329
+ (60 * 60 * 24 * 7)
329
330
 
330
- daysToSlots(project.weeklyWorkingDays * weeksToReport)
331
+ daysToSlots((project.weeklyWorkingDays * weeksToReport).to_i)
331
332
  end
332
333
 
333
334
  # Compute the total number of actual working time slots of the
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TjpSyntaxRules.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2020
7
7
  # by Chris Schlaeger <cs@taskjuggler.org>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -673,7 +673,7 @@ EOT
673
673
  def rule_color
674
674
  pattern(%w( $STRING ), lambda {
675
675
  col = @val[0]
676
- unless /#[0-9A-Fa-f]{3}/ =~ col || /#[0-9A-Fa-f]{3}/ =~ col
676
+ unless /#[0-9A-Fa-f]{3}/ =~ col || /#[0-9A-Fa-f]{6}/ =~ col
677
677
  error('bad_color',
678
678
  "Color values must be specified as '#RGB' or '#RRGGBB' values",
679
679
  @sourceFileInfo[0])
@@ -3932,7 +3932,13 @@ EOT
3932
3932
  descr('The duration of a task')
3933
3933
 
3934
3934
  singlePattern('_duties')
3935
- descr('List of tasks that the resource is allocated to')
3935
+ descr(<<'EOT'
3936
+ List of tasks that the resource is allocated to
3937
+
3938
+ The list can be customized by the [[listitem.column|listitem]] and
3939
+ [[listtype.column|listtype]] attribute.
3940
+ EOT
3941
+ )
3936
3942
 
3937
3943
  singlePattern('_efficiency')
3938
3944
  descr('Measure for how efficient a resource can perform tasks')
@@ -52,7 +52,7 @@ class TaskJuggler
52
52
 
53
53
  # Write the XMLDocument to the specified file.
54
54
  def write(filename)
55
- f = filename == '.' ? $stdout : File.new(filename.untaint, 'w')
55
+ f = filename == '.' ? $stdout : File.new(filename, 'w')
56
56
  @elements.each do |element|
57
57
  f.puts element.to_s(0)
58
58
  end
@@ -37,7 +37,7 @@ class TaskJuggler
37
37
  @port = nil
38
38
  @webServer = false
39
39
  @webServerPort = 8080
40
- @webdPidFile = File.join(Dir.getwd, ".tj3webd-#{$$}.pid").untaint
40
+ @webdPidFile = File.join(Dir.getwd, ".tj3webd-#{$$}.pid")
41
41
  end
42
42
 
43
43
  def processArguments(argv)
@@ -92,7 +92,7 @@ EOT
92
92
  # Set some config variables if corresponding data was provided via the
93
93
  # command line.
94
94
  broker.port = @port if @port
95
- broker.uriFile = @uriFile.untaint
95
+ broker.uriFile = @uriFile
96
96
  broker.projectFiles = sortInputFiles(files) unless files.empty?
97
97
  broker.daemonize = @daemonize
98
98
  # Create log files for standard IO for each child process if the daemon
@@ -89,7 +89,7 @@ EOT
89
89
  # Set some config variables if corresponding data was provided via the
90
90
  # command line.
91
91
  webServer.port = @port if @port
92
- webServer.uriFile = @uriFile.untaint
92
+ webServer.uriFile = @uriFile
93
93
  webServer.webServerPort = @webServerPort if @webServerPort
94
94
  webServer.daemonize = @daemonize
95
95
  webServer.pidFile = @pidFile
@@ -137,9 +137,9 @@ class TaskJuggler
137
137
  # directory. The second one is the master project file (.tjp file).
138
138
  # Additionally a list of optional .tji files can be provided.
139
139
  def loadProject(args)
140
- dirAndFiles = args.dup.untaint
140
+ dirAndFiles = args.dup
141
141
  # The first argument is the working directory
142
- Dir.chdir(args.shift.untaint)
142
+ Dir.chdir(args.shift)
143
143
 
144
144
  # Save a time stamp of when the project file loading started.
145
145
  @modifiedCheck = TjTime.new