Skip to content

Instantly share code, notes, and snippets.

@Foadsf
Created April 18, 2025 09:32
Show Gist options
  • Save Foadsf/7369884973712fc536e048d88eb0a133 to your computer and use it in GitHub Desktop.
Save Foadsf/7369884973712fc536e048d88eb0a133 to your computer and use it in GitHub Desktop.
TaskJuggler 3.8.1 Lessons Learned: Tips, Tricks, and Workarounds A comprehensive guide to using TaskJuggler 3.8.1 with modern Ruby versions, addressing common syntax issues, bugs, and report generation challenges.

TaskJuggler 3.8.1 Lessons Learned

Introduction

TaskJuggler is a powerful project management tool that uses a text-based syntax to define project plans, resources, and tasks. While the software is mature and feature-rich, its latest version (3.8.1 as of 2024) has some quirks and compatibility issues, especially with newer Ruby versions. This document shares practical lessons learned while working with TaskJuggler 3.8.1.

Basic Project Structure

TaskJuggler 3 has a specific file structure and syntax that differs significantly from version 2. Here's the basic structure of a TaskJuggler 3 project file:

project project_id "Project Name" "1.0" 2024-01-01 - 2024-12-31 {
  # Project attributes go here
  now 2024-01-01
  timeformat "%Y-%m-%d"
}

# Resources
resource res_id "Resource Name" {
  # Resource attributes
}

# Tasks
task task_id "Task Name" {
  # Task attributes
  start 2024-01-01
  duration 5d
}

# Reports
taskreport "report_name" {
  formats html
  columns name, start, end
}

Syntax Quirks and Common Mistakes

1. Report Syntax

TaskJuggler 3 uses a completely different syntax for reports than version 2:

Version 2 (incorrect for TJ3):

htmltaskreport "report.html" {
  columns name, start, end
}

Version 3 (correct):

taskreport "report_name" {
  formats html
  columns name, start, end
}

2. Task References and Dependencies

When referencing tasks in dependencies, pay attention to relative and absolute paths:

task project "Project" {
  task phase1 "Phase 1" {
    task task1 "Task 1" {
      start 2024-01-01
      duration 5d
    }
    task task2 "Task 2" {
      # Using ! for relative reference (to a sibling)
      depends !task1
      duration 3d
    }
  }
  
  task phase2 "Phase 2" {
    # Using ! for relative reference (to a sibling of parent)
    depends !phase1
    duration 4d
  }
}

Mistakes to avoid:

  • Missing the ! prefix for relative references
  • Using the wrong number of ! characters (each ! moves up one level)
  • Trying to use a simple ID without proper qualification

3. Report Location Specification

TaskJuggler 3 requires an output directory to be specified when running the command:

tj3 --output-dir output_directory project.tjp

The directory must exist before running the command.

Known Bugs and Workarounds

1. Chart Column Bug with Ruby 3.x

Problem: Including the chart column in task reports causes a fatal error when running with Ruby 3.x versions:

Fatal: undefined method '[]' for nil
C:/path/to/gems/taskjuggler-3.8.1/lib/taskjuggler/ResourceScenario.rb:499

Workaround: Remove the chart column from task reports:

# Instead of:
taskreport "report" {
  formats html
  columns name, start, end, chart  # Causes error
}

# Use:
taskreport "report" {
  formats html
  columns name, start, end, duration, effort, resources
}

2. Calendar View Issues in Resource Reports

Problem: Using calendar columns like weekly, monthly, etc. in resource reports can cause similar errors with Ruby 3.x.

Workaround: Use simpler columns without calendar views:

# Instead of:
resourcereport "resources" {
  formats html
  columns name, weekly  # May cause issues
}

# Use:
resourcereport "resources" {
  formats html
  columns name, start, end, effort
}

3. Deprecated Column Names

Problem: Some column names are deprecated but still used in documentation.

Solution: Use the newer column names:

  • hierarchindexbsi (Breakdown Structure Index)
  • indexno (Number)
taskreport "report" {
  formats html
  # Use bsi instead of hierarchindex
  columns bsi, name, start, end
}

Task Dependencies and Scheduling

1. Using Proper Dependency References

task t1 "Task 1" {
  start 2024-01-01
  duration 5d
}

task t2 "Task 2" {
  # Absolute reference
  depends t1
  duration 3d
}

task container "Container" {
  task c1 "Container Task 1" {
    duration 2d
  }
  task c2 "Container Task 2" {
    # Relative reference to sibling
    depends !c1
    duration 1d
  }
}

task t3 "Task 3" {
  # Reference to task inside container
  depends container.c2
  duration 2d
}

2. Scheduling Policies

TaskJuggler supports two scheduling policies:

  • asap (As Soon As Possible) - default
  • alap (As Late As Possible)
task t "Task" {
  start 2024-01-01
  duration 5d
  scheduling asap  # Default if not specified
}

task t2 "Task 2" {
  end 2024-01-10  # Implicitly sets to alap
  duration 3d
}

task t3 "Task 3" {
  start 2024-01-01
  end 2024-01-10  # Last statement wins
  duration 5d
  # Will be alap due to end statement being last
}

task t4 "Task 4" {
  start 2024-01-01
  end 2024-01-10
  duration 5d
  scheduling asap  # Explicitly overrides
}

Resource Allocation

1. Basic Resource Allocation

resource dev "Developer"

task t "Task" {
  effort 5d  # Task requires 5 person-days of effort
  allocate dev
}

2. Alternative Resources

resource dev1 "Developer 1"
resource dev2 "Developer 2"

task t "Task" {
  effort 10d
  allocate dev1 {
    alternative dev2  # Use dev2 if dev1 is not available
    persistent  # Once a resource is chosen, use it for the entire task
  }
}

3. Resource Limits

resource dev "Developer" {
  limits {
    dailymax 6h  # Max 6 hours per day
    weeklymax 30h  # Max 30 hours per week
  }
}

task t "Task" {
  effort 20d
  allocate dev {
    limits {
      dailymax 4h  # Overrides the resource's default limit for this task
    }
  }
}

Reporting Tips

1. Using Multiple Report Formats

taskreport "tasks" {
  formats html, csv
  columns name, start, end, duration, resources
}

2. Filtering Reports

# Show only tasks matching certain criteria
taskreport "critical_tasks" {
  formats html
  columns name, start, end
  hidetask ~isLeaf() | effort < 5d
}

# Show only certain resources
resourcereport "engineering_team" {
  formats html
  columns name, effort
  hideresource ~isChildOf(engineering)
}

3. Sorting Report Items

taskreport "sorted_tasks" {
  formats html
  columns name, start, end
  sorttasks tree, startup  # Sort by tree structure, then by start date
}

resourcereport "sorted_resources" {
  formats html
  columns name, effort
  sortresources nameup  # Sort alphabetically
}

4. Calendar Reports

Be cautious with calendar reports in TaskJuggler 3.8.1 when using Ruby 3.x. Calendar reports are bug-prone, but if needed:

htmltaskreport "report.html" {
  headline "Task Calendar"
  columns name, start, end, monthly
}

Compatibility Issues with Ruby 3.x

TaskJuggler 3.8.1 was developed with older Ruby versions in mind (2.x) and has several compatibility issues with Ruby 3.x:

  1. The caller API changes in Ruby 3.x cause bugs in ResourceScenario.rb
  2. Regular expression handling differences affect report generation
  3. NIL handling is stricter in Ruby 3.x, causing previously silent errors to fail

Workarounds:

  1. Consider using Ruby 2.7 if possible (last of the 2.x series)
  2. Avoid using features known to cause issues:
    • Gantt chart columns
    • Calendar views
    • Complex resource loading reports
  3. Use simpler report formats like CSV when encountering issues

Exporting to Other Formats

When TaskJuggler's built-in reports are problematic, consider:

  1. Exporting to CSV and using other tools for visualization:
taskreport "export" {
  formats csv
  columns name, start, end, duration, effort
}
  1. Creating simplified HTML reports and enhancing them with external JavaScript libraries:
taskreport "simple_report" {
  formats html
  columns name, start, end, duration
}

Conclusion

TaskJuggler 3.8.1 remains a powerful project management tool despite some compatibility issues with modern Ruby versions. By understanding its quirks and avoiding problematic features, you can still effectively use it for project planning and management.

For complex visualizations or when encountering persistent issues, consider exporting to CSV and using specialized visualization tools or spreadsheet software.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment