Compare commits

...

21 Commits

Author SHA1 Message Date
Ben Harris fa8fa53e48 fix #3
don't error out if the command -v is in ~/bin
2022-06-03 14:50:32 -04:00
Ben Harris 61f6f2ccd2 check empty command first 2020-06-11 16:01:01 -04:00
Ben Harris 619bc12e6e switch to sh 2020-06-11 15:54:04 -04:00
Ben Harris 17470a610b fix description saving 2020-06-10 22:31:12 -04:00
Ben Harris 8c8cd4c86d add missing bracket 2020-06-10 22:22:52 -04:00
Ben Harris e92ace542d big tidy up and shellcheck fixes 2020-06-10 22:21:08 -04:00
Ben Harris f94ce2dfe3 fix existing file condition 2020-06-10 21:24:09 -04:00
Ben Harris a137bff6c0 Merge pull request 'wraps stat for bsd support' (#2) from tomasino/tilde-launcher:master into master 2020-06-10 21:22:37 -04:00
Tilde Black Admin 67bf3b918d mail addresses use variables for host portability 2020-06-10 21:22:37 -04:00
Tilde Black Admin 3b1057a434 test if files exist in bin dir when using list 2020-06-10 21:22:37 -04:00
Tilde Black Admin f8dd46482b corrects gnu version of stat 2020-06-10 21:22:37 -04:00
Tilde Black Admin 4fe8a4f229 wraps stat for bsd support 2020-06-10 21:22:37 -04:00
Ben Harris 4b7fb0c7df Merge pull request 'hashbang uses env for portability' (#1) from tomasino/tilde-launcher:master into master 2020-06-10 20:35:29 -04:00
James Tomasino 8899cf985c hashbang uses env for portability 2020-06-11 00:31:54 +00:00
Ben Harris 4c3fe64acd add makefile and manpage 2018-09-05 21:20:34 -04:00
Ben Harris cdef21ce0d update README 2018-07-18 15:20:56 -04:00
Ben Harris d3395a42b9 merge bash-tilde to master 2018-06-12 15:57:26 -04:00
Ben Harris 47185a2df4 check for file, not executable for arg not found 2018-06-12 15:48:32 -04:00
Ben Harris e7080f8209 fix username of submitter on approval 2018-06-12 01:00:23 -04:00
Ben Harris b169e80b42 add submission and approval flows 2018-06-12 00:43:59 -04:00
Ben Harris 4cd90345af advise user to add /tilde/bin to PATH instead of aliases 2018-06-08 18:42:13 -04:00
5 changed files with 366 additions and 93 deletions

22
Makefile Normal file
View File

@ -0,0 +1,22 @@
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man
install:
@echo Installing the executable to $(BINDIR)
@mkdir -p $(BINDIR)
@cp -f tilde $(BINDIR)/tilde
@chmod 755 $(BINDIR)/tilde
@echo Installing the manual page to $(MANDIR)/man1
@mkdir -p $(MANDIR)/man1
@cp -f tilde.1 $(MANDIR)/man1/tilde.1
@chmod 644 $(MANDIR)/man1/tilde.1
uninstall:
@echo Removing the executable from $(BINDIR)
@rm -f $(BINDIR)/tilde
@echo Removing the manual page from $(MANDIR)/man1
@rm -f $(BINDIR)/man1/tilde.1
.PHONY: install uninstall

View File

@ -1,34 +1,19 @@
# `tilde` - A tilde-launcher proposal in Python
# `tilde` - user script tilde-launcher
This is my proposal for the tilde town program launcher. Here are the features that make it compliant with the specs:
```
wrapper for user-submitted scripts
supports user submission and admin approval
- It has a help menu that, while not meeting the format of the specs, gives an example usage string and description.
- It implements the contrib system beautifully (IMO)
usage: tilde [help|list|submit|about|<script_name>]
Here are the things I have left to make before this proposal can be considered a true answer to the specs:
tilde list - show a list of approved userscripts
tilde submit - start the submission flow for your own script
tilde about <script_name> - get the description for script_name
tilde <script_name> - run script_name with all remaining args are passed to the script
```
- [ ] Implement submit process
- [ ] Implement other commands shown in help example (see below)
- [ ] Polish some rough logic
approved scripts are placed in /tilde/bin and listed with `tilde list`
## Top-level commands
submissions use sendmail to notify an admin.
- [x] help - complete
- [x] contrib - complete
- [x] chat - complete
- [ ] mail - just need to write this one
- [ ] submit - See Questions below
## Questions
### `tilde submit`
- How should this be accomplished?
- Is this supposed to be only for ben or for an admin in general to help?
- If the answer to the previous question is the latter, how should this be accomplished?
## Requirements
In `/tilde/special`, put:
- `list` - see list program in this directory
admins can use `sudo tilde approve` and `sudo tilde revoke <script_name>`.

4
list
View File

@ -1,4 +0,0 @@
#!/bin/bash
cd /tilde/bin
ls | tr '\t' '\n'

359
tilde
View File

@ -1,74 +1,311 @@
#!/usr/bin/python2
import argparse,sys,os,subprocess
#!/bin/sh
# ---------------------------------------------------------------------------
# tilde - manage user-submitted scripts and apps
class TildeContrib(object):
def __init__(self,progdir):
self.progdir=progdir
pass
# Copyright 2018, Ben Harris <ben@tilde.team>
def __getattr__(self,k):
if k in ("list"):
return object.__getattr__(self,k)
return lambda x: os.system("/tilde/bin/{} {}".format(k," ".join(x)))
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
def list(self, x, inc=True):
cs = filter(None,subprocess.check_output(['/tilde/special/list']).split("\n"))
f = " ".join(x) if len(x)>0 else ""
ret = []
for c in cs:
if f in c:
ret.append(c)
if inc:
ret.extend(["list"])
return ret
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License at <http://www.gnu.org/licenses/> for
# more details.
class TildeLauncher:
# Usage: tilde [-h|--help]
COMMANDS = ["help","contrib"]
# ---------------------------------------------------------------------------
USAGE = dict(help="\n Displays this menu",contrib=" <program>\n Your gateway to programs made by teammates,\n for teammates!")
PROGNAME=${0##*/}
VERSION="0.1.0"
user=$(whoami)
hostname=$(hostname -f)
def __init__(self,prog_dir):
self.progdir = prog_dir
self.tc = TildeContrib(prog_dir)
# check coreutils and wrap stat for portability
if stat -c"%U" /dev/null >/dev/null 2>/dev/null ; then
# GNU environment
stat_func () {
stat -c '%U' "$1"
}
else
# BSD environment
stat_func () {
stat -f %Su "$1"
}
fi
def base(self):
print """ Welcome to tilde.team :) this program is your gateway to team-specific
commands and features. Run tilde help to see the sort of things you can do."""
isroot() {
[ "$(id -u)" = "0" ]
}
def help(self,argv):
commands_to_display = []
if len(argv)==0:
commands_to_display = self.COMMANDS
else:
commands_to_display = [i for i in argv if i in self.COMMANDS]
for cmd in commands_to_display:
print "tilde {}{}".format(cmd,self.USAGE[cmd])
error_exit() {
printf "%s\n" "${1:-"unknown Error"}" >&2
exit 1
}
def contrib(self,argv):
if not argv:
argv = ["list"] # default to listing
if argv[0]=="list":
print "Commands:"
for c in self.tc.list(argv[1:]):
print " tilde contrib "+c
# elif argv[0]=="bootstrap":
# for c in self.tc.list([],False):
# print("alias {0}=\"tilde contrib {0}\"".format(c))
else:
getattr(self.tc,argv[0])(argv[1:])
signal_exit() { # Handle trapped signals
case $1 in
INT)
error_exit "program interrupted by user"
;;
TERM)
printf "\n%s: program terminated" "$PROGNAME" >&2
exit
;;
*)
error_exit "$PROGNAME: terminating on unknown signal"
;;
esac
}
# def chat(self,argv):
# os.system("/tilde/special/chat")
prompt_confirm() {
while true; do
printf "%s [y/n]: " "${1:-continue?}"
read -r REPLY
case $REPLY in
[yY]) printf "\n" ; return 0 ;;
[nN]) printf "\n" ; return 1 ;;
*) printf " \033[31m %s \n\033[0m" "invalid input" ;;
esac
done
}
if __name__=="__main__":
tl = TildeLauncher("/tilde/bin")
argv = sys.argv[1:]
if len(argv)==0:
tl.base()
else:
if not hasattr(tl,argv[0]):
print " Unknown command %s!"
tl.help([])
help_message() {
printf "%s version %s\n" "$PROGNAME" "$VERSION"
printf "wrapper for user-submitted scripts\n"
printf "supports submission and admin approval\n"
usage
}
usage() {
printf "\nusage: %s [help|list|submit|about|script_name]\n\n" "$PROGNAME"
printf " list - show a list of approved userscripts\n"
printf " submit - start the submission flow for your own script\n"
if isroot; then
printf " approve - enter the approval queue\n"
printf " revoke <script_name> - send a script back to the author and remove from /tilde/bin\n"
fi
printf " about <script_name> - get the description for script_name\n"
printf " <script_name> - run script_name with all remaining args are passed to the script\n"
case ":$PATH:" in
*:/tilde/bin:*)
;;
*)
printf "\nadd /tilde/bin to your PATH to use approved scripts without this wrapper\n"
printf "if you're using bash, run the following to add it quickly\n"
printf " echo 'export PATH=\$PATH:/tilde/bin' >> ~/.bashrc && source ~/.bashrc\n"
;;
esac
}
verify_script_name() {
if [ -z "$1" ]; then
error_exit "please enter a script name"
fi
if command -v "$1"; then
if [ "$(command -v "$1")" != "/home/$user/bin/$1" ]; then
error_exit "$1 already exists. rename your script and try again."
fi
fi
if [ -x "/tilde/bin/$1" ]; then
error_exit "$1 is already taken. rename your script and try again."
fi
case $1 in
about|description|list|ls|submit|about|help|apropos|submit|approve)
error_exit "$1 is a subcommand of tilde. rename your script and try again."
;;
*)
return
;;
esac
}
submission_checklist() {
cat <<- _EOF_
requirements for submitting a user script or program:
- placed in your ~/bin
- executable
- responds to help or --help
- no name collisions with existing scripts or $PROGNAME subcommands
_EOF_
}
mail_body() {
cat <<- _EOF_
Subject: tilde script submission from ${user}
From: ${user}@${hostname}
To: root@${hostname}
tilde script submission from ${user}
script name: $1
description:
-----------------------------------------------------------------------
$2
-----------------------------------------------------------------------
you'll find the script and description in: /tilde/pending-submissions/$user/$1
run this to see the approval queue:
sudo tilde approve
_EOF_
}
# Trap signals
trap "signal_exit TERM" TERM HUP
trap "signal_exit INT" INT
# Parse command-line
case $1 in
-h | --help | help)
help_message; exit
;;
-v | --version)
printf "%s" "$VERSION"
;;
-* | --*)
usage
error_exit "Unknown option $1"
;;
list | ls)
printf "available scripts:\n\n"
for scr in /tilde/bin/*; do
if [ -f "$scr" ]; then
script_name=$(basename "$scr")
target=$(readlink -f "$scr")
printf "%s by %s\n" "$script_name" "$(stat_func "$target")"
cat "/tilde/descriptions/$script_name"
printf "\n"
fi
done
;;
about | apropos | description)
if [ -f "/tilde/descriptions/$2" ]; then
cat "/tilde/descriptions/$2"
else
printf "%s not found. try %s list to see available user scripts.\n" "$2" "$PROGNAME"
fi
;;
submit)
printf "hello, %s! so it's time to submit your script?\n" "$user"
submission_checklist
prompt_confirm "are you ready to continue?" || exit
printf "enter the name of your script: "
read -r script_name
verify_script_name "$script_name"
if [ -x "$HOME/bin/$script_name" ]; then
printf "cool, found your script\n"
if [ -x "/tilde/pending-submissions/$user/$script_name/$script_name" ]; then
error_exit "you've already submitted $script_name"
fi
else
error_exit "$script_name not found in ~/bin"
fi
printf "enter a description of your script: \n"
read -r description
printf "\nyour script, along with your description will be sent to the admins for approval\n"
prompt_confirm "ready to submit?" || exit
# submit now
mkdir -p "/tilde/pending-submissions/$user/$script_name"
ln -s "$HOME/bin/$script_name" "/tilde/pending-submissions/$user/$script_name/$script_name"
printf "%s\n" "$description" > "/tilde/pending-submissions/$user/$script_name/description.txt"
mail_body "$script_name" "$description" | sendmail root
printf "script submitted. thanks! :)\n"
;;
approve)
if ! isroot; then
error_exit "re-run this as root to access the approval queue"
fi
printf "welcome to the approval queue\n\n"
for user in /tilde/pending-submissions/*; do
for scr in $user/*; do
user=$(basename "$user")
script_name=$(basename "$scr")
[ -f "$scr/approved" ] && continue
script="$scr/$script_name"
if [ -f "$script" ]; then
printf "%s by %s\n" "$script_name" "$user"
cat "$scr/description.txt"
prompt_confirm "approve?" || continue
ln -s "$(readlink -f "$script")" "/tilde/bin/$script_name"
cp "$scr/description.txt" "/tilde/descriptions/$script_name"
touch "$scr/approved"
chmod 664 /tilde/descriptions/*
printf "your submission of %s has been approved and is now available at /tilde/bin/%s" "$script_name" "$script_name" \
| sendmail "$user"
fi
done
done
printf "~~done for now~~\n"
;;
revoke)
isroot || \
error_exit "re-run this as sudo to access the revoke menu"
[ -f "/tilde/bin/$2" ] || \
error_exit "$2 isn't an approved script"
prompt_confirm "revoke $2?"
printf "please provide a reason: "
read -r reason
original_script=$(readlink -f "/tilde/bin/$2")
author=$(stat_func "$original_script")
rm "/tilde/bin/$2"
rm "/tilde/descriptions/$2"
rm -rf "/tilde/pending-submissions/$author/$2"
printf "your script %s has been returned because: %s\nfeel free to resubmit\n" "$2" "$reason" \
| sendmail "$author"
printf "%s revoked and returned to author" "$2"
;;
*)
if [ -z "$1" ]; then
help_message
exit
elif [ -x "/tilde/bin/$1" ]; then
prog="/tilde/bin/$1"
shift
exec "$prog" "$@"
else
printf "%s not found. check %s list to see what's available\n\n" "$1" "$PROGNAME"
help_message
exit
fi
;;
esac
getattr(tl,argv[0])(argv[1:])

33
tilde.1 Normal file
View File

@ -0,0 +1,33 @@
.TH tilde 1 "5 September 2018" "v0.0.2"
.SH NAME
tilde \- user script wrapper and submission tool
.SH SYNOPSIS
.B tilde [options] (scriptname)
.P
.SH DESRIPTION
.B tilde
is a wrapper around user-submitted scripts.
any accepted script in /tilde/bin can be run with
the wrapper feature.
users can submit any script in their ~/bin directory
which will be mailed to admins for review.
.SH USAGE
.TP
.B tilde list
List all available scripts in /tilde/bin
.TP
.B tilde [scriptname]
Run scriptname.
.TP
.B tilde submit
Submit a script from your ~/bin directory
.TP
.B tilde about [scriptname]
Get the submitter's description for a script.
.SH DEPENDENCIES
None.
.SH BUGS
None known. Please submit to https://tildegit.org/team/tilde-launcher/issues
.SH AUTHOR
Ben Harris <ben (at) tilde (dot) team>