ref: 28dcffa50db033003ea5549e1616d49e3420256d
parent: 6e7bc9b9dc67f5556f2c0c2ed2742e5b1c1ef710
author: Michael Misch <michaelmisch1985@gmail.com>
date: Mon Sep 2 13:46:47 PDT 2024
Rename everything to be just tasks
--- /dev/null
+++ b/.task/0
@@ -1,0 +1,7 @@
+# Initial release
+
+[ ] Commands working from any child directory
+[ ] Showcase plumbing integration
+ - /usr/glenda/src/hlfw.ca/extra/task/1
+ - /usr/glenda/src/hlfw.ca/extra/task/2
+
--- /dev/null
+++ b/.task/1
@@ -1,0 +1,5 @@
+# Clean systems integration
+
+[ ] Plumbing files fore // TODO, /* TODO ... */, # TODO etc. pro/task with trailing text as synopsis
+[ ] Set up wm with /tmp/wm.pro
+[ ] Menu building
--- /dev/null
+++ b/.task/2
@@ -1,0 +1,5 @@
+# Task manager that can handle queries `walk/fs`
+
+[ ] Parse all task files
+[ ] Build graph out of any linkages
+[ ] Write out results based on requests (tags, strings, etc)
--- a/README.md
+++ b/README.md
@@ -1,11 +1,3 @@
-## Config
-
-The config file in `.pro/config` is created by `pro/init`. `srvfile` and `stubs` are used by `pro/ns`, described below
-
- [project "projectname"]
- srvfile=/srv/foo
- stubs=docs,resources
-
## Task files
# A synopsis of the task
@@ -18,17 +10,15 @@
## Commands
-`pro/init` is use to create a new barebones project, with no tasks or namespace files. The project will be created with the basename of current directory, or `name` if given.
+`task/init` is use to create a new barebones project, with no tasks or namespace files. The project will be created with the basename of current directory, or `name` if given.
-`pro/ns` sets up a namespace based on the contents on `.pro/ns`, (see namespace(6)). This namespace is then posted to /srv/$name, based on the srvfile config setting. Any stubs in the config will be set up using `aux/stub -d $name` prior to starting the namespace
-
(See [this post](https://hlfw.ca/blog/2024-08-24-more-setup.html) for inspiration, and further integration.)
- `pro/task` is used to manage or add a task to the graph, usage is similar to git/commit - the hold editor will be used by default, ctrl+d is used to signal completion. `-c $tag` is used to change an existing task. Passing `-e` will use your default editor instead of hold mode. Any args afterwards will be passed along as the `synopsis` for the task
+ `task/add` is used to manage or add a task to the graph, usage is similar to git/commit - the hold editor will be used by default, ctrl+d is used to signal completion. `-c $tag` is used to change an existing task. Passing `-e` will use your default editor instead of hold mode. Any args afterwards will be passed along as the `synopsis` for the task
-`pro/rm` removes a given completed task. With `-f`, all matching tags are removed. With `-a`, all completed tags are checked for removal.
+`task/rm` removes a given completed task. With `-f`, all matching tags are removed. With `-a`, all completed tags are checked for removal.
-`pro/walk` shows the status of tasks in the graph. It prints a list of tasks prefixed with the status character. The -c flag disables printing the status characters. The -p flag will only search within the given project. The -q option suppresses all output. The -f option filters tasks by status, and only matching items are printed. By default, the filters are DNS.
+`task/walk` shows the status of tasks in the graph. It prints a list of tasks prefixed with the status character. The -c flag disables printing the status characters. The -p flag will only search within the given project. The -q option suppresses all output. The -f option filters tasks by status, and only matching items are printed. By default, the filters are DNS.
The task status characters are as follows:
@@ -40,17 +30,17 @@
*Blocked tasks have a child task that requires completing before they can be completed
-`pro/show` prints a formatted task to stdout, when passed -r it will print the raw task file
+`task/show` prints a formatted task to stdout, when passed -r it will print the raw task file
## TODO
- make commands work from any child directory
-- `pro/walk` implementation
+- `task/walk` implementation
- multi-project awareness for all utils. A task should be able to reference another project via a tag, such as `projectname/tag`
- Showcase plumbing integration
-- potential git integration (completed new task, git/commit could parse the .pro/tasks, add the synopsis of the completed ones and/or a formatted task lists, and then finally pro/rm the task after committing)
+- potential git integration (completed new task, git/commit could parse the .task/ directory, add the synopsis of the completed ones and/or a formatted task lists, and then finally task/rm the task after committing)
## Multi-project Thoughts
-A `pro/fs` could be spun up, given a set of paths that your projects live somewhere within, by default the user $home, and could walk the paths looking for .pro directories.
+A `task/fs` could be spun up, given a set of paths that your projects live somewhere within, by default the user $home, and could walk the paths looking for .task directories.
- This would allow utilities to query the fs for valid tags and completion states outside of the current project.
--- /dev/null
+++ b/add
@@ -1,0 +1,82 @@
+#!/bin/rc -e
+rfork ne
+
+fn editmsg{
+ if(! test -s $msgfile.tmp){
+ >$msgfile.tmp {
+ echo '#' $synopsis
+ echo ''
+ }
+ edit=1
+ }
+
+ if(! ~ $#edit 0){
+ if(~ $#editor 0){
+ # store current, run editor, then write change to final
+ cp $msgfile.tmp $msgfile
+ editor=hold
+ }
+ $editor $mw
+sgfile.tmp
+ }
+ if(! test -s $msgfile.tmp){
+ echo 'nothing to add' >[1=2]
+ exit 'message'
+ }
+ ## TODO: Check if we have hold as editor, otherwise just cp here
+ cat $msgfile.tmp >> $msgfile
+}
+
+fn gettag{
+ # Fetch he last numerical tag in the dir
+ tag=`{ls .task/*[0-9] | tail -1 | sed 's#.task/##'}
+ if(! ~ $#change 0)
+ tag=$change
+ if not
+ tag=`{echo $tag^+1 | bc}
+}
+
+fn finish{
+ cp $msgfile .task/$tag
+ # TODO: . common.rc to set $project, as it's useful for our outputs
+ #echo '$project:$tag'
+}
+
+fn sigexit{
+ if(! ~ $#msgfile 0)
+ rm -f $msgfile
+ if(! ~ $#msgfile.tmp 0)
+ rm -f $msgfile.tmp
+}
+
+flagfmt='c:change change, e:edit'; args='[msg ...]'
+eval `''{aux/getflags $*} || exec aux/usage
+
+msgfile=/tmp/task.$pid
+
+# Bit o messy initialization, but that's ok.
+if(! ~ $#* 0)
+ synopsis=`{echo $*}
+if(! ~ $#change 0){
+ edit=1
+ if(test -s .task/$change){
+ if(! ~ $#synopsis 0){
+ echo '#' $synopsis > $msgfile.tmp
+ tail +2 .task/$change >> $msgfile.tmp
+ }
+ if not
+ cat .task/$change > $msgfile.tmp
+ }
+ if not {
+ echo 'no task found for ' $change >[1=2]
+ exit 'missing'
+ }
+}
+
+@{
+ flag e +
+ gettag
+ editmsg
+ finish
+} || echo 'could not write task:' $status >[1=2]
+exit ''
--- a/conf.c
+++ /dev/null
@@ -1,135 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ctype.h>
-#include <bio.h>
-
-#include "pro.h"
-
-static char*
-strip(char *s)
-{
- char *e;
-
- while(isspace(*s))
- s++;
- e = s + strlen(s);
- while(e > s && isspace(*--e))
- *e = 0;
- return s;
-}
-
-static char*
-wd2sfile(void)
-{
- char pathname[512];
- char *pr;
-
- if(getwd(pathname, sizeof(pathname)) == 0)
- return "/srv/work";
- if((pr = utfrrune(pathname, '/')))
- return strcat("/srv", pr);
- return "/srv/work";
-}
-
-static char**
-fromCSV(char *s, int *nfields)
-{
- char **fields;
- int i, cap, nf;
- char *token;
-
- cap = 1;
- nf = 0;
-
- fields = malloc(sizeof(char*));
- if(!fields)
- return nil;
-
- token = strtok(s, ",");
- while(token){
- if(nf >= cap){
- cap *= 2;
- char **tmp = realloc(fields, cap * sizeof(char*));
- if(!tmp)
- goto Fail;
- fields = tmp;
- }
-
- fields[nf] = strdup(token);
- if(!fields[nf])
- goto Fail;
- nf++;
- token = strtok(nil, ",");
- }
- *nfields = nf;
- return fields;
-Fail:
- for(i = 0; i < nf; i++)
- free(fields[i]);
- free(fields);
- werrstr("failed to parse csv");
- return nil;
-}
-
-void
-freeconf(Proconf *conf)
-{
- int i;
- if(!conf)
- return;
-
- if(conf->stubs){
- for(i = 0; i < conf->nstub; i++)
- free(conf->stubs[i]);
- free(conf->stubs);
- }
- free(conf);
-
-}
-
-Proconf*
-pconf(void)
-{
- Proconf *conf;
- Biobuf *f;
- char *ln, *p;
-
- if((f = Bopen(".pro/config", OREAD)) == nil)
- return nil;
-
- conf = malloc(sizeof(Proconf));
- conf->nstub = 0;
- conf->stubs = nil;
- while((ln = Brdstr(f, '\n', 1)) != nil){
- p = strip(ln);
- if(strncmp(p, "name", 4) == 0){
-print("Into Sfile\n");
- p = strip(p + 4);
- if(*p == '='){
- p = strip(p + 1);
- conf->sfile = strcat("/srv/", p);
- }
-print("Out of Sfile\n");
- }
- if(strncmp(p, "stubs", 5) == 0){
-print("Stubby\n");
- p = strip(p + 5);
- if(*p == '='){
- p = strip(p + 1);
- conf->stubs = fromCSV(p, &conf->nstub);
- if(!conf->stubs){
- Bterm(f);
- freeconf(conf);
- free(ln);
- return nil;
- }
- }
-print("Out of stubby\n");
- }
- free(ln);
- }
- Bterm(f);
- if(!conf->sfile)
- conf->sfile = wd2sfile();
- return conf;
-}
--- a/example/.pro/config
+++ /dev/null
@@ -1,3 +1,0 @@
-[project "pro"]
- name=ns.pro
- stubs=docs,bars
--- a/example/.pro/ns
+++ /dev/null
@@ -1,3 +1,0 @@
-mount /srv/plumb /mnt/plumb
-
-. /usr/glenda/lib/doc.namespace.9c
--- a/example/.pro/task/0
+++ /dev/null
@@ -1,7 +1,0 @@
-# Synopsis here for first task
-
-[ ] Item 1
-[ ] Item 2
-[x] Item 3
-
- - /path/to/example/1
--- a/example/.pro/task/1
+++ /dev/null
@@ -1,6 +1,0 @@
-# Second task
-
-[ ] Item 1
-[ ] Item 2
-[ ] Third thing
-
--- a/init
+++ /dev/null
@@ -1,20 +1,0 @@
-#!/bin/rc -e
-rfork ne
-
-dir=$1
-if(~ $#dir 0)
- dir=.
-if(test -e $dir/.pro){
- echo $0: $dir/.pro already exists >[1=2]
- exit 'exists'
-}
-
-name=`{basename `{cleanname -d `{pwd} $dir}}
-mkdir -p $dir/.pro/task
-
-touch $dir/.pro/ns
->$dir/.pro/config {
- echo '[project '$name']'
- echo ' srvname='$name
- echo ' stubs='
-}
--- a/mkfile
+++ b/mkfile
@@ -1,27 +1,16 @@
</$objtype/mkfile
-BIN=/$objtype/bin/pro
-TARG=\
- ns\
+BIN=/$objtype/bin/task
RC=\
- init\
- task\
+ add\
rm\
show\
walk\
-OFILES=\
- conf.$O\
-
-HFILES=proj.h
-
</sys/src/cmd/mkmany
install:V:
- mkdir -p $BIN
- for (i in $TARG)
- mk $MKFLAGS $i.install
for (i in $RC)
mk $MKFLAGS $i.rcinstall
--- a/ns.c
+++ /dev/null
@@ -1,69 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-
-#include "pro.h"
-
-static void
-usage(char *argv0)
-{
- fprint(2, "usage: %s\n", argv0);
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- Proconf *conf;
- int i, fd, pipefd[2];
-
- if(argc != 1)
- usage(argv[0]);
- conf = pconf();
- if(conf == nil){
- fprint(2, "can't parse: %r\n");
- exits("config");
- }
- for(i = 0; i < conf->nstub; i++){
- print(conf->stubs[i]);
- if(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFNAMEG) == 0){
- execl("/bin/aux/stub", "aux/stub", "-d", conf->stubs[i]);
- fprint(2, "can't exec aux/stub: %r\n");
- }
- }
- if(addns(getuser(), ".pro/ns") < 0){
- fprint(2, "can't addns: %r\n");
- exits("addns");
- }
- if(pipe(pipefd) < 0){
- fprint(2, "can't pipe: %r\n");
- exits("pipe");
- }
- if(access(conf->sfile, 0) == 0)
- remove(conf->sfile);
- fd = create(conf->sfile, OWRITE|ORCLOSE, 0600);
- if(fd < 0){
- fprint(2, "can't create %s: %r\n", conf->sfile);
- exits("create");
- }
-
- fprint(fd, "%d", pipefd[1]);
- close(pipefd[1]);
- freeconf(conf);
- switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFREND)){
- case -1:
- fprint(2, "can't rfork: %r\n");
- exits("rfork");
- case 0:
- dup(pipefd[0], 0);
- dup(pipefd[0], 1);
- close(pipefd[0]);
-
- execl("/bin/exportfs", "exportfs", "-r", ".");
- fprint(2, "can't exec exportfs: %r\n");
- exits("exec");
- default:
- break;
- }
- exits(0);
-}
--- a/pro.h
+++ /dev/null
@@ -1,10 +1,0 @@
-typedef struct Proconf Proconf;
-struct Proconf
-{
- char *sfile;
- char **stubs;
- int nstub;
-};
-
-void freeconf(Proconf*);
-Proconf *pconf(void);
--- a/rm
+++ b/rm
@@ -8,18 +8,18 @@
fn checkstate {
if(! ~ $#all 0){
if(! ~ $#force 0)
- rmlist=`{ls .pro/task}
+ rmlist=`{ls .task}
if not {
# TODO: This will need to be filtered to just our project after
- #rmlist=`{pro/walk -c -fC -p $project}
- rmlist=`{pro/walk -c -fC}
+ #rmlist=`{task/walk -c -fC -p $project}
+ rmlist=`{task/walk -c -fC}
}
}
if not {
if(! ~ $#force 0)
- rmlist=`{ls .pro/task/$tag}
+ rmlist=`{ls .task/$tag}
if not
- rmlist=`{pro/walk -q fC $tag && ls .pro/task/$tag}
+ rmlist=`{task/walk -q fC $tag && ls .task/$tag}
}
}
--- a/show
+++ b/show
@@ -3,8 +3,8 @@
fn gettags {
for(a in $pathlist)
- if(test -s .pro/task/$a)
- showlist=($showlist .pro/task/$a)
+ if(test -s .task/$a)
+ showlist=($showlist .task/$a)
}
fn pretty {
--- a/task
+++ /dev/null
@@ -1,81 +1,0 @@
-#!/bin/rc -e
-rfork ne
-
-fn editmsg{
- if(! test -s $msgfile.tmp){
- >$msgfile.tmp {
- echo '#' $synopsis
- echo ''
- }
- edit=1
- }
-
- if(! ~ $#edit 0){
- if(~ $#editor 0){
- # store current, run editor, then write change to final
- cp $msgfile.tmp $msgfile
- editor=hold
- }
- $editor $msgfile.tmp
- }
- if(! test -s $msgfile.tmp){
- echo 'nothing to add' >[1=2]
- exit 'message'
- }
- ## TODO: Check if we have hold as editor, otherwise just cp here
- cat $msgfile.tmp >> $msgfile
-}
-
-fn gettag{
- # Fetch he last numerical tag in the dir
- tag=`{ls .pro/task/*[0-9] | tail -1 | sed 's#.pro/task/##'}
- if(! ~ $#change 0)
- tag=$change
- if not
- tag=`{echo $tag^+1 | bc}
-}
-
-fn finish{
- cp $msgfile .pro/task/$tag
- # TODO: . common.rc to set $project, as it's useful for our outputs
- #echo '$project:$tag'
-}
-
-fn sigexit{
- if(! ~ $#msgfile 0)
- rm -f $msgfile
- if(! ~ $#msgfile.tmp 0)
- rm -f $msgfile.tmp
-}
-
-flagfmt='c:change change, e:edit'; args='[msg ...]'
-eval `''{aux/getflags $*} || exec aux/usage
-
-msgfile=/tmp/pro-msg.$pid
-
-# Bit o messy initialization, but that's ok.
-if(! ~ $#* 0)
- synopsis=`{echo $*}
-if(! ~ $#change 0){
- edit=1
- if(test -s .pro/task/$change){
- if(! ~ $#synopsis 0){
- echo '#' $synopsis > $msgfile.tmp
- tail +2 .pro/task/$change >> $msgfile.tmp
- }
- if not
- cat .pro/task/$change > $msgfile.tmp
- }
- if not {
- echo 'no task found for ' $change >[1=2]
- exit 'missing'
- }
-}
-
-@{
- flag e +
- gettag
- editmsg
- finish
-} || echo 'could not write task:' $status >[1=2]
-exit ''