Skip to content
This repository has been archived by the owner on Jun 17, 2022. It is now read-only.

Commit

Permalink
feat: knock off multiple TODOs
Browse files Browse the repository at this point in the history
- rename requireConfig to useConfig
- more printing of relative paths for paths relative to
  GLUE_WD
- fix broken links in docs
- ensure use{Config,Action} works with folders
  • Loading branch information
hyperupcall committed May 16, 2021
1 parent c4bac3d commit c69e18c
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 44 deletions.
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,8 @@ For concrete examples see [glue-example](https://github.com/eankeen/glue-example

See [details.md](./docs/details.md)

- Fix broken links in docs
- Other todos scattered throughout
- On warnings in which there is something about with two files, print the two files adjacently vertical
TODOS

- autocomplete
- greadlink readlink -f check
- TODO: autocomplete
- make requireConfig work with folders
- rename requireConfig to useConfig
- search for requireActions in 'actions'?
- cd to GLUE_WD?
- list dependencies in regular file instead of having requireCOnfig annotatinos
- log paths show relative paths
- list dependencies in regular file instead of having requireConfig annotatinos?
6 changes: 2 additions & 4 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ Certain directories have an intrinsic meaning and should be used as such. All di

### `commands`

The location Glue looks to execute a particular task. Glue also scans this directory to find `requireAction()` annotations
The location Glue looks to execute a particular task. Glue also scans this directory to find `useAction()` annotations

### `actions`

The location a script in 'commands' looks to source to perform a more fine-grained action (ex. run `eslint`). Glue also scans this directorie to find `requireConfig()` annotations
The location a script in 'commands' looks to source to perform a more fine-grained action (ex. run `eslint`). Glue also scans this directorie to find `useConfig()` annotations

### `configs`

Expand All @@ -51,5 +51,3 @@ Any persistent state that your scripts may emit. Use of this directory is _highl
# Miscellaneous

- Most script-writing-gotchia's are due to the fact that the script file can reside in either `commands/auto/script.sh` or `commands/script.sh`

- Note that for example, when `commands/auto/script.sh` runs, `GLUE_ACTIONS_DIR` may be different on first pass. This is due to the eval of `GLUE_ACTIONS_BOOTSTRAP`. So, only use these variables in functions
16 changes: 7 additions & 9 deletions docs/details.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

For every project you want to use Glue with, a `.glue` directory is used to contain everything related to Glue: configuration, scripts, and script output.

There are two types of scripts: 'command' and 'action'. 'command' scripts can simply be though of the execution of a particular task relating to a programming language. For example: `Build Go library` or `Deploy Node server`. Each 'command' script calls out to an 'action' script that does the actual command. For example `go build .` or `ansible-playbook playbook.yml`. Two categories of scripts exist to increase composability of 'actions' across languages (or even possibly domains!). Lastly, 'command' and 'action' scripts are contains in the `.glue/commands` and `.glue/actions` directories, respectively
There are two types of scripts: 'command' and 'action'. 'command' scripts can simply be though of the execution of a particular task relating to a programming language. For example: `Build Go library` or `Deploy Node server`. Each 'command' script calls out to an 'action' script that does the actual command. For example a script containaing `go build .` or `ansible-playbook playbook.yml`. Two categories of scripts exist to increase composability of 'actions' across languages (or even possibly domains!). Lastly, 'command' and 'action' scripts are contained in the `.glue/commands` and `.glue/actions` directories, respectively

The following explain the different parts of Glue, in no particular order

Expand All @@ -18,13 +18,13 @@ It's important to understand the execution flow of Glue when using the `cmd` sub

1. When first invoking Glue, it looks for an `actions.bootstrap.*` and a `commands.bootstraps.*` file in the Glue store, setting their contents to `$GLUE_ACTIONS_BOOTSTRAP` and `$GLUE_COMMANDS_BOOTSTRAP`, respectively

2. If a task is specified through the `cmd` subcommand, it looks for that task in the `.glue/commands`, then `.glue/commands/auto` directories of your project. If none are found, it displays an error. See [Finding Scripts](## Finding Scripts) for more details
2. If a task is specified through the `cmd` subcommand, it looks for that task in the `.glue/commands`, then `.glue/commands/auto` directories of your project. If none are found, it displays an error. See [Scripts](#scripts) for more details

3. Assuming the task is found, the file is executed, and the `$GLUE_ACTIONS_BOOTSTRAP`, `$GLUE_COMMANDS_BOOTSTRAP`, and `$GLUE_IS_AUTO` variables are passed into the environment. The rest of the execution is now dependent on the user's Glue store

## About Scripts
## Scripts

Glue's process of finding and executing scripts makes script-writing easy to extend, modify, and compose. This functionality is only for scripts in the `commands (not `actions`) directory.
Glue's process of finding and executing scripts makes script-writing easy to extend, modify, and compose. This functionality is only for scripts in the `commands` (not `actions`) directory.

A meta task is a combination of a Project Type, a Task, and a When. Not all components need to be present and not all compositional variations are valid

Expand All @@ -40,7 +40,7 @@ glue cmd NodeJS_Server.build-before

From this meta task, Glue searches for a script (ex. NodeJS_Server.build-before.sh`) in `.glue/commands/auto`. However, if one by the same name is found in `.glue/commands`, it uses that one instead

As you can see, script names are nearly identical to the meta task. The following lists all variations and their semantics
As you can see, script names are nearly identical to the meta task. The following code blocks lists all variations and their semantics

```sh
# Only task
Expand All @@ -58,12 +58,10 @@ glue cmd NodeJS_Server-before
# Invalid because it doesn't make sense

# And projectType, task, when
glue cmd NodeJS_Server-before
glue cmd NodeJS_Server-only
glue cmd NodeJS_Server.ci-before
glue cmd NodeJS_Server.ci-only
```

To know which scripts are executed in which order, see [Finding Scripts](##finding-scripts)

### Project Type

```sh
Expand Down
4 changes: 4 additions & 0 deletions glue.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ main() {
shift
doSync "$@"
;;
list)
sync
doList "$@"
;;
cmd)
shift
doCmd "$@"
Expand Down
58 changes: 43 additions & 15 deletions lib/do.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ doSync() {
# ACTIONS, CONFIGS
# <directoryToSearchAnnotations:annotationName:directoryToSearchForFile>
local arg
for arg in 'commands:requireAction:actions' 'actions:requireConfig:configs'; do
for arg in 'commands:useAction:actions' 'actions:useConfig:configs'; do
local searchDir="${arg%%:*}"
local annotationName="${arg#*:}"; annotationName="${annotationName%:*}"
local fileDir="${arg##*:}"
Expand All @@ -52,23 +52,47 @@ doSync() {

# 'file' is a relative path
for file in "${files[@]}"; do
if [ -f "$GLUE_STORE/$fileDir/$file" ]; then
if [ -e "$GLUE_STORE/$fileDir/$file" ]; then
case "$file" in
*/*)
# If file contains a directory path in it
mkdir -p "$GLUE_WD/.glue/$fileDir/auto/${file%/*}"
cp "$GLUE_STORE/$fileDir/$file" "$GLUE_WD/.glue/$fileDir/auto/${file%/*}"
;;
*)
cp "$GLUE_STORE/$fileDir/$file" "$GLUE_WD/.glue/$fileDir/auto/"
cp -r "$GLUE_STORE/$fileDir/$file" "$GLUE_WD/.glue/$fileDir/auto/"
esac
else
log.warn "Corresponding file for annotation'$annotationName()' not found in directory '$GLUE_STORE/$fileDir'. Skipping'"
log.warn "Corresponding file for annotation '$annotationName($file)' not found in directory '$GLUE_STORE/$fileDir'. Skipping'"
fi
done
done
}

doList() {
local -A tasks=()

shopt -s dotglob
shopt -s nullglob

local filePath
for filePath in "$GLUE_WD"/.glue/commands/* "$GLUE_WD"/.glue/commands/auto/*; do
local file="${filePath##*/}"
local task="${file%%.*}"

# Do not include files without a projectType
if [ "$file" = "$task" ]; then
continue
fi

tasks+=(["$task"]='')
done

for task in "${!tasks[@]}"; do
echo "$task"
done
}

doCmd() {
[[ -z $1 ]] && die 'No meta task passed'

Expand All @@ -85,6 +109,7 @@ doCmd() {
cat "$actionsBootstrapFile"
)" || die "Could not get contents of '$actionsBootstrapFile'"

# -------------------- Parse Meta task ------------------- #
get.task "$1"
local task="$REPLY"

Expand All @@ -94,20 +119,18 @@ doCmd() {
get.when "$1"
local when="$REPLY"

# --------------------- Sanity check --------------------- #
if [ -z "$task" ]; then
die "Specifying a 'task is required"
fi

if [[ -v DEBUG ]]; then
echo "task: $task"
echo "projectType: $projectType"
echo "when: $when"
fi

if [ -z "$task" ]; then
die "Specifying a 'task is required"
fi

local commandDir="$GLUE_WD/.glue/commands"
local hasRan=no

# specify projectTypes
# calculate 'projectType's to run
local -a projectTypes=()
if [ -n "$projectType" ]; then
projectTypes=("$projectType" "")
Expand All @@ -119,7 +142,7 @@ doCmd() {
projectTypes=("${GLUE_USING[@]}" "")
fi

# specify whens
# calculate 'when's to run
local -a whens=()
if [ -n "$when" ]; then
# a blank 'when' represents a file like 'build-go.sh' compared to 'build-go-before.sh'
Expand All @@ -133,6 +156,9 @@ doCmd() {
whens=("-before" "" "-after")
fi

# run and execute files in order
local commandDir="$GLUE_WD/.glue/commands"
local hasRan=no
for projectType in "${projectTypes[@]}"; do
for when in "${whens[@]}"; do
helper.get_executable_file "$commandDir/${projectType}.${task}${when}"
Expand All @@ -153,7 +179,9 @@ doCmd() {
done

if [[ $hasRan == no ]]; then
printf -v msg "%s\n -> %s\n -> %s\nExiting" "Task '$task' did not match any files in the following directories" ".glue/commands/auto" ".glue/commands"
log.error "$msg"
log.error "Task '$task' did match any files"
echo " -> Is the task contained in '.glue/commands/auto' or '.glue/commands'" >&2
echo " -> Was a task like 'build', 'ci', etc. actually specified?" >&2
exit 1
fi
}
4 changes: 3 additions & 1 deletion lib/helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ helper.get_executable_file() {
firstFileMatch=
for aFileMatch in "$file".*?; do
if [[ $hasRanFile = yes ]]; then
log.warn "Both '$aFileMatch' and '$firstFileMatch' should not exist"
log.warn "Two files match the same pattern"
echo " -> '$aFileMatch" >&2
echo " -> '$firstFileMatch'" >&2
break
fi

Expand Down
21 changes: 18 additions & 3 deletions lib/util/log.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,29 @@ die() {
exit 1
}

# Print info
log.info() {
printf "\033[0;34m%s\033[0m\n" "Info: $*"
if [[ -v NO_COLOR || $TERM = dumb ]]; then
printf "%s\n" "Info: $*"
else
printf "\033[0;34m%s\033[0m\n" "Info: $*"
fi
}

# Print warning
log.warn() {
printf "\033[1;33m%s\033[0m\n" "Warn: $*" >&2
if [[ -v NO_COLOR || $TERM = dumb ]]; then
printf "%s\n" "Warn: $*"
else
printf "\033[1;33m%s\033[0m\n" "Warn: $*" >&2
fi
}

# Print error
log.error() {
printf "\033[0;31m%s\033[0m\n" "Error: $*" >&2
if [[ -v NO_COLOR || $TERM = dumb ]]; then
printf "%s\n" "Error: $*"
else
printf "\033[0;31m%s\033[0m\n" "Error: $*" >&2
fi
}
3 changes: 1 addition & 2 deletions lib/util/util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ util.show_help() {
}

util.show_version() {
# TODO
cat <<-EOF
VERSION
0.3
EOF
}

0 comments on commit c69e18c

Please sign in to comment.