changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / emacs/lib/scrum.el

changeset 698: 96958d3eb5b0
parent: af486e0a40c9
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
1 ;;; scrum.el --- Scrum-like Planning and Roadmaps in Org -*- lexical-binding: t; -*-
2 
3 ;; Copyright (C) 2024 Richard Westhaver
4 
5 ;; Author: Richard Westhaver <richard.westhaver@gmail.com>
6 ;; Keywords: maint
7 
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
12 
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20 
21 ;;; Commentary:
22 
23 ;; The point of this package is to enable an Emacs-native scrum
24 ;; workflow. Many years ago I used to use the org-jira package and
25 ;; mirror an external scrum/agile system (Jira).
26 
27 ;; Mind you, I wouldn't dare take a shot at Jira. As far as Products
28 ;; go, when you need to work with hundreds of humans on software and
29 ;; are given a short list you must choose from, it's often the best of
30 ;; the worst.
31 
32 ;; The problem is however, that we don't need Products. What we need,
33 ;; is a plan. How we achieve that end should be via the best and most
34 ;; powerful tools possible.
35 
36 ;; In my opinion, Emacs Org Mode is the most powerful tool
37 ;; available. It is not quite the best tool for the job, but this
38 ;; isn't a problem because it is not a Product. We are given the
39 ;; opportunity to make it the best tool possible, in the only way
40 ;; possible - by doing it ourselves.
41 
42 ;; And yes, the aura of NIH syndrome may be strong here. Most of the
43 ;; time you need to work with lots of folks who don't have the need or
44 ;; patience to learn Org-mode. This package isn't for them. It's for
45 ;; small groups of like-minded Lispers :).
46 
47 ;;;; Refs
48 ;; scrum: https://www.scrum.org/resources/what-scrum-module
49 
50 ;; roadmap: https://compiler.company/plan/roadmap.html
51 
52 ;; tasks: https://compiler.company/plan/tasks
53 
54 ;;;; API
55 
56 ;; The API is still very much a WIP. Assume everything below to be
57 ;; theoretical.
58 
59 ;; - task dependencies
60 ;; - refer to org-depend.el for implementation details
61 ;; - org-trigger-hook and org-blocker-hook
62 ;; - org-todo-state-tags-triggers
63 
64 ;; - dynamic blocks
65 ;; - scrumboard
66 ;; - burndown
67 
68 ;;; Code:
69 (require 'ulang)
70 (require 'uml-mode)
71 
72 (defgroup scrum nil
73  "CC Scrum Framework.")
74 
75 (defvar scrum-properties '("SPRINT" "EPIC" "RELEASE" "TASKID" "PROJECT" "COMMIT" "GOAL"))
76 
77 (defvar scrum-tags '("demo" "mvp" "release" "major-release" "ua" "qa"))
78 
79 (defun org-dblock-write:scrumboard ()
80  "Generate a 'scrumboard'.")
81 
82 ;; TODO 2024-09-06: eplot
83 (defun org-dblock-write:burndown ()
84  "Generate a 'burndown' chart in the current buffer.")
85 
86 ;;; Projects
87 ;; defining 'project' machinery here because we don't have a better
88 ;; place to put it. These functions are intended to map projects
89 ;; from 'skel' and 'project.el' into our task-based org system.
90 
91 ;; Projects can contain many subprojects, which are identified by org
92 ;; headings with a 'PROJECT' todo keyword. Projects and sub-projects
93 ;; all have a 'VERSION' property assigned which can't be
94 ;; inherited. The 'PROJECT' property itself can be inherited.
95 
96 ;; project-info
97 (defcustom org-project-info-order '(details status tasks churn log files)
98  "Order in which sections of the 'project-info' dblock will appear."
99  :type 'list
100  :group 'scrum)
101 
102 (defun org-dblock-write:project-info (params)
103  "Generate a project-info section.
104 
105 The following keyword parameters can be passed to the info dynamic block:
106 
107 :location Set or override the project location which is inferred by
108  checking for a LOCATION property in the current tree, followed
109  by the value of the `project-current' function.
110 
111 :branch Set or override the project branch to display info for. Default
112  branch name is 'default'.
113 
114 :files When nil don't include the files table.
115 :churn When nil don't include the vc churn report.
116 :log when nil don't include the vc log.
117 :status when nil don't include vc status.
118 :details When nil don't include the project details section."
119  (let ((location (or (when-let ((param (plist-get params :location)))
120  (cl-coerce param 'string))
121  (org-entry-get (point) "LOCATION")
122  (when-let ((kw (org-collect-keywords '("LOCATION"))))
123  (cadar kw))
124  (project-root (project-current))))
125  (point (point))
126  (files (if-let ((val (plist-member params :files)))
127  (cadr val)
128  t))
129  (churn (if-let ((val (plist-member params :churn)))
130  (cadr val)
131  t))
132  (status (if-let ((val (plist-member params :log)))
133  (cadr val)
134  t))
135  (log (if-let ((val (plist-member params :status)))
136  (cadr val)
137  t))
138  (tasks (if-let ((val (plist-member params :tasks)))
139  (cadr val)
140  t))
141  (details (if-let ((val (plist-member params :details)))
142  (cadr val)
143  t)))
144  (message "Generating info for project: %s" location)
145  (let* ((project (project-current nil location))
146  (project-name (project-name project))
147  (project-root (project-root project)))
148  (dolist (i org-project-info-order)
149  (pcase i
150  ('details (when details
151  (message "building project details...")
152  (insert "#+CALL: project-details() :dir " project-root "\n")
153  (org-babel-execute-maybe)
154  (org-table-align)))
155  ('status (when status
156  (message "building project status...")
157  (insert "#+CALL: hg-status() :dir " project-root "\n")))
158  ('tasks (when tasks
159  (message "building project tasks...")
160  (insert "#+CALL: project-tasks() :dir " project-root "\n")))
161  ('churn (when churn
162  (message "building project vc churn...")
163  (insert "#+CALL: hg-churn() :dir " project-root "\n")))
164  ('log (when log
165  (message "building project vc log...")))
166  ('files (when files
167  (message "building project file table...")
168  (insert "#+CALL: project-files() :dir " project-root "\n")))))
169  (org-babel-execute-region point (point)))))
170 
171 (defun org-project-info ()
172  "Insert or update a project-info dblock."
173  (interactive)
174  (if (re-search-forward (rx bol "#+BEGIN:" (+ space) "project-info") nil t)
175  (progn
176  (if (fboundp 'org-fold-show-entry)
177  (org-fold-show-entry)
178  (with-no-warnings (org-show-entry)))
179  (beginning-of-line))
180  (org-create-dblock (list :name "project-info")))
181  (org-update-dblock))
182 
183 (provide 'scrum)
184 ;;; scrum.el ends here