4 Commits
v1.10 ... v1.14

Author SHA1 Message Date
4c5f514fb4 Bash completion script, list-projects, list-contexts commands.
* list-projects lists all the projects in the repo.
* list-contexts lists all the context in the repo.
* Created a bash completion script to allow auto-complete for GTD.
2014-12-16 14:04:58 -06:00
a780d972f1 List actions now sorts its output alphabetically. 2014-12-16 11:16:49 -06:00
43f0930cf2 Updated the version number (forgot and pushed the tags). 2014-12-01 12:37:20 -06:00
f95dc91707 New rename-project command.
The `rename-project` command will rename a project and update all of the action
items associated with that project.

* Fills in some missing information in the online help.
* Fixes a bug in the finGtdRootDir function. It was not properly handling
  relative paths.
* Fixes a bug where the reconfigure command was referring to the wrong
  configuration file.
2014-12-01 12:05:55 -06:00
5 changed files with 184 additions and 11 deletions

View File

@ -1,8 +1,8 @@
#Wed, 19 Nov 2014 12:50:01 -0600
#Tue, 16 Dec 2014 11:59:49 -0600
lib.local=true
name=jdb-gtd
version=1.10
version=1.14
nailgun.classpath.dir=/home/jdbernard/programs/nailgun/classpath
executable.jar=true
main.class=com.jdblabs.gtd.cli.GTDCLI
build.number=1
build.number=5

View File

@ -0,0 +1,39 @@
_gtd()
{
local cur prev topOpts debugOpts logLevels
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
topOpts="help process done calendar list-copies new tickler list debug delegate rename-project list-projects list-contexts"
debugOpts="state loglevel"
logLevels="TRACE DEBUG INFO WARN ERROR"
case "${prev}" in
help)
COMPREPLY=( $(compgen -W "${topOpts}" -- ${cur}) )
return 0
;;
done|list-copies|delegate)
COMPREPLY=( $(compgen -f ${cur}) )
return 0
;;
ls|list)
COMPREPLY=( $(gtd list-projects) $(gtd list-contexts) )
return 0
;;
debug)
COMPREPLY=( $(compgen -W "${debugOpts}" -- ${cur}) )
return 0
;;
loglevel)
COMPREPLY=( $(compgen -W "${logLevels}" -- ${cur}) )
return 0
;;
*)
;;
esac
COMPREPLY=( $(compgen -W "${topOpts}" -- ${cur}) )
return 0
}
complete -F _gtd gtd

View File

@ -19,6 +19,7 @@ package com.jdblabs.gtd
* calendar to "schedule" items, but only to represent items which must be
* done by or on that day.
* * `details`: more information related to this item.
* * `project`: the name of the project with which this item is associated.
* @org gtd.jdb-labs.com/Item
*/
public class Item {

View File

@ -104,7 +104,7 @@ public class Util {
def gtdDirs = [:]
/// Start by considering the current directory as a candidate.
File currentDir = givenDir
File currentDir = givenDir.canonicalFile
while (currentDir != null) {
/// We recognize the GTD root directory when it contains all of the
/// GTD top-level directories.

View File

@ -17,13 +17,18 @@ import com.jdblabs.gtd.Item
import com.jdblabs.gtd.PropertyHelp
import com.jdbernard.util.LightOptionParser
import com.martiansoftware.nailgun.NGContext
import java.io.FileFilter
import java.nio.file.Files
import java.nio.file.Path
import java.security.MessageDigest
import groovy.io.FileType
import org.joda.time.DateMidnight
import org.joda.time.DateTime
import org.slf4j.Logger as SFL4JLogger
import org.slf4j.LoggerFactory
import static com.jdblabs.gtd.Util.*
import static java.nio.file.StandardCopyOption.*
/**
* Command-line helper for working with this implementation of the Getting
@ -31,7 +36,7 @@ import static com.jdblabs.gtd.Util.*
* @org gtd.jdb-labs.com/cli/GTDCLI */
public class GTDCLI {
public static final String VERSION = "1.9"
public static final String VERSION = "1.14"
private static String EOL = System.getProperty("line.separator")
/// We have a persistent instance when we are in the context of a Nailgun
@ -107,7 +112,7 @@ public class GTDCLI {
/// read afresh the configuration file.
nailgunInst = null
nailgunInst = new GTDCLI(new File(
System.getProperty("user.home"), ".gritterrc"))
System.getProperty("user.home"), ".gtdclirc"))
nailgunInst.run(args) } }
@ -240,9 +245,12 @@ public class GTDCLI {
case ~/list-copies/: listCopies(parsedArgs); break
case ~/new/: newAction(parsedArgs); break
case ~/tickler/: tickler(parsedArgs); break
case ~/list-contexts/: listContexts(parsedArgs); break;
case ~/list-projects/: listProjects(parsedArgs); break;
case ~/ls|list/: ls(parsedArgs); break;
case ~/debug/: debug(parsedArgs); break;
case ~/delegate/: delegateAction(parsedArgs); break;
case ~/rp|rename-project/: renameProject(parsedArgs); break;
default:
log.error "Unrecognized command: ${command}"
break } } }
@ -621,7 +629,7 @@ public class GTDCLI {
def printItems = { dir ->
if (!dir.exists() || !dir.isDirectory()) return
println "-- ${getRelativePath(gtdDirs.root, dir)} --"
dir.eachFile { file ->
dir.listFiles().sort { it.name }.each { file ->
if (!file.exists() || !file.isFile() || file.isHidden() ||
file.name.startsWith('.'))
return
@ -646,6 +654,29 @@ public class GTDCLI {
printItems(new File(gtdDirs.waiting, target))
printItems(new File(gtdDirs.projects, target)) } }
/** #### `listProjects`
* Implement the `list-projects` command to list all the known projects
* for this repository. For detailed information see the
* [online help][help-list-projects] by running `gtd help list-projects`.
*
* [help-list-projects]: jlp://gtd.jdb-labs.com/cli/GTDCLI/help/list-projects
*/
protected void listProjects(LinkedList args) {
gtdDirs.projects.eachFile(FileType.DIRECTORIES) { println it.name } }
/** #### `listContexts`
* Implement the `list-contexts` command to list all the known contexts
* for this repository. For detailed information see the
* [online help][help-list-contexts] by running `gtd help list-contexts`.
*
* [help-list-contexts]: jlp://gtd.jdb-labs.com/cli/GTDCLI/help/list-contexts
*/
protected void listContexts(LinkedList args) {
def ctxNames = []
gtdDirs["next-actions"].eachFile(FileType.DIRECTORIES) { ctxNames << it.name }
gtdDirs.waiting.eachFile(FileType.DIRECTORIES) { ctxNames << it.name }
ctxNames.unique().each { println it } }
/** #### `debug`
* Print out debug information. Currently this prints out the internal
* state of the CLI. I may add other subcommands if the need arises. */
@ -787,6 +818,56 @@ public class GTDCLI {
/// Delete the original file.
oldFile.delete() } }
/** #### `rename-project`
* Implement the `rename-project` command. This will rename the project
* directory in TODO as well as change the project reference in any of the
* items from the `next-actions` contexts.
*
* `gtd help rename-project`.
*
* [help-rename-project]: jlp://gtd.jdb-labs.com/cli/GTDCLI/help/rename-project
*/
protected void renameProject(LinkedList args) {
def projectName = args.poll()
def newName = args.poll()
if (!projectName || !newName) {
log.error "The 'gtd rename-project' command requires two " +
"parameters: <existing-project-name> and a <new-name>."
return }
def projectDir = new File(gtdDirs.projects, projectName)
if (!projectDir.exists() || !projectDir.isDirectory()) {
log.error "There is no directory named '$projectName' in the " +
"'projects' directory."
return }
def newDir = new File(gtdDirs.projects, newName)
if (newDir.exists()) {
log.error "There is already a project named '$newName'."
return }
// Perform the rename of the directory itself.
try { Files.move(projectDir.toPath(), newDir.toPath(), REPLACE_EXISTING) }
catch (Exception e) {
log.error "Unable to rename the project: ${e.localizedMessage}."
return }
// Update all of the items associated with this project.
def projectFiles = newDir.
listFiles({ File f ->
f.exists() && !f.isHidden() &&
f.isFile() && !f.name.startsWith('.') } as FileFilter)
def allProjectItems = projectFiles.collectMany { f ->
findAllCopies(f, gtdDirs.root).collect { new Item(it) } }
allProjectItems.each {
it.project = newName
it.save() }
println "Project renamed. ${allProjectItems.size()} items updated." }
private void print(String msg) { log.info(msg) }
private void println(String line) { log.info(line + EOL) }
@ -809,20 +890,41 @@ options are:
top-level commands:
help <command> Print detailed help about a command.
process Process inbox items systematically.
done <action-file> Mark an action as done. This will automatically
take care of duplicates of the action in project
or next-actions sub-folders.
calendar Show the tasks with specific days assigned to
them, sorted by date.
list-copies <action-file> Given an action item, list all the other places
there the same item is filed (cross-reference
with a project folder, for example).
new Interactively create a new action item in the
current folder.
tickler Search the tickler file for items that need to be
delivered and move them to the *next-actions*
folder."""
folder.
list, ls [<context> ...] List all the tasks for a given set of contexts
projects.
debug n
delegate Move an item from a next-action context or a
project folder to a waiting context and attach
the name of the party now responsible for the
item.
rename-project, rp <existing-project> <new-name>
Rename a project directory and update any task
items that reference it."""
} else {
def command = args.poll()
@ -926,15 +1028,17 @@ file for any items that should become active (based on their <tickle> property)
and moves them out of the tickler file and into the next-actions file."""
break
/// Online help for the `ls`/`list-context` command.
/// Online help for the `ls`/`list` command.
/// @org gtd.jdb-labs.com/cli/GTDCLI/help/ls
case ~/ls|list-context/: println """\
usage gtd ls [<context> ...]
case ~/ls|list/: println """\
usage gtd list [<context> ...]
or gtd ls [<context> ...]
This command lists all the tasks for a given context or project. The purpose is
to list in one place items that are sitting in the next-actions folder or the
waiting folder for a specific context or list items for a given project. If no
context or project is named, all contexts are listed."""
break
/// Online help for the `delegate` command.
/// @org gtd.jdb-labs.com/cli/GTDCLI/help/delegate
@ -944,6 +1048,35 @@ usage gtd delegate [<action-file> ...]
This command moves an action item from a next-action context or project folder
to the delegate folder. It allows the user to attach the name of the newly
responsible party and optionally rename the item."""
break
/// Online help for the `list-projects` command.
/// @org gtd.jdb-labs.com/cli/GTDCLI/hemp/list-projects
case ~/list-projects/: println """\
usage gtd list-projects
This command lists all of the project folders defined in this repository (all
the folders in the /projects folder."""
break
/// Online help for the `list-contexts` command.
/// @org gtd.jdb-labs.com/cli/GTDCLI/hemp/list-contexts
case ~/list-contexts/: println """\
usage gtd list-contexts
This command lists all of the context folders defined in this repository (all
the folders in the /next-actions and /waiting folders."""
break
/// Online help for the `rename-project` command.
/// @org gtd.jdb-labs.com/cli/GTDCLI/help/rename-project
case ~/delegate/: println """\
usage gtd rename-project <existing-project> <new-name>
or gtd rp <existing-project> <new-name>
This command renames a project directory and updates any items that reference
the project."""
break
}
}