-
Notifications
You must be signed in to change notification settings - Fork 0
/
cm.sh
executable file
·216 lines (192 loc) · 5.66 KB
/
cm.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# Initialization
PROJECT_FILE=${HOME}/.cm/_CURRENT_PROJECT
_PROJECT=''
CM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
## If command-manager main directory doesn't exist create new empty one
if [ ! -d "${HOME}/.cm" ]; then
mkdir -p ${HOME}/.cm
echo "command-manager: folder initialized"
fi
## Set current project name
if test -f "$PROJECT_FILE"; then
_PROJECT=$(cat $PROJECT_FILE)
else
touch $PROJECT_FILE
fi
# Load all commands from all projects
echo -n '' > /tmp/.cm-source-file
for PROJECT in $(find $HOME/.cm/ -maxdepth 1 -type d -print | tail -n +2 | rev | cut -d'/' -f1 | rev)
do
cat ~/.cm/$PROJECT/aliases | sed "s#^#alias ${PROJECT}.#g" >> /tmp/.cm-source-file
done
source /tmp/.cm-source-file
rm /tmp/.cm-source-file
# Main function
function _cm() {
if [ "$#" -eq 0 ]; then
_cm_help
else
case $1 in
help) _cm_help;;
version) echo '{{VERSION}}';;
init) _cm_init "$@";;
rm-project) _cm_rm-project "$@";;
set|current) _cm_set "$@";;
add) _cm_add "$@";;
remove) _cm_remove;;
load) _cm_load;;
list) _cm_list;;
list-projects|projects) _cm_projects;;
edit) _cm_edit;;
*) _cm_help;;
esac
fi
}
alias cm='_cm 2>&1'
# Autocomplete
function _cm__autocomplete() {
COMMANDS=$(grep --color=never -E "^[[:space:]]+[[:alpha:]|-]+).+;;" $CM_DIR/cm.sh | cut -d')' -f1 | awk '{$1=$1};1' | sed 's/|/\n/g' | tr '\r\n' ' ')
complete -W "$COMMANDS" cm
}
# Print command-manager information
function _cm__info() {
echo "cm: $@"
}
# Load all project sub-commands
function _cm_load() {
cat ${HOME}/.cm/${_PROJECT}/aliases | sed "s#^#alias ${_PROJECT}.#g"
}
function _cm_help() {
cat <<EOF
usage: cm [command]
help
Prints this help page
version
Prints version
init <project-name>
Create project as an umbrella name for all sub-commands.
This can be changed in any given time.
set <project-name>
If you have more then one project then with this command
you can switch beetween them. Without project-name this
will show current project.
set|current
Same as set without parameters. Show current project name.
add <sub-command>
Add new sub-command
remove <sub-command>
Remove existing sub-command
list
List all sub-commands for the currently set project.
list-projects|projects
List all projects
edit
Edit your sub-commands. Default open in vi, if you want to change this
then `export EDITOR=nano`. To make it permanent add this to the end of
your ~/.bashrc
Report bugs to: https://github.com/sobi3ch/project-manager/issues
EOF
}
function _cm_init() {
if [ -z "$2" ]
then
_cm__info "Project name is missing"
_cm__info "usage: cm init <project-name>"
return
fi
local PROJECT=$2
if [ ! -d "${HOME}/.cm/${PROJECT}" ]; then
mkdir -p ${HOME}/.cm/${PROJECT}
touch ${HOME}/.cm/${PROJECT}/aliases
_cm_set $PROJECT
_cm__info "Project *${PROJECT}* created"
else
_cm__info "Project *${PROJECT}* already exist"
fi
}
function _cm_rm-project() {
local CURRENT_PROJECT=$(cat $HOME/.cm/_CURRENT_PROJECT)
if [[ $# -gt 1 ]]
then
local PROJECT=$2
if [ "$PROJECT" == "$CURRENT_PROJECT" ]
then
echo "error: Cannot delete the project '$PROJECT' which you are currently on."
else
_cm_projects | grep $PROJECT > /dev/null
if [[ $? -gt 0 ]]
then
echo "error: There is no project '$PROJECT'."
else
read -p "Are you sure you want to permanently delete project '$PROJECT'? [y/N]: " opt
if [ "$opt" == "y" ]
then
rm -rf ${HOME}/.cm/${PROJECT} && \
echo "'$PROJECT' deleted."
fi
fi
fi
else
echo 'To few parameters'
fi
}
## Set the current project
function _cm_set() {
local CURRENT_PROJECT=$(cat $HOME/.cm/_CURRENT_PROJECT)
if [[ $# -eq 1 && ! -z "$CURRENT_PROJECT" ]]
then
_cm__info $CURRENT_PROJECT
else
PROJECT=$1
if [ ! -d "${HOME}/.cm/${PROJECT}" ]; then
echo "Missing project: ${PROJECT}"
elif [ "$PROJECT" == "$CURRENT_PROJECT" ]; then
echo "Already on '${PROJECT}'"
else
echo $PROJECT > $HOME/.cm/_CURRENT_PROJECT
_cm__info "Project set to: ${PROJECT}"
_PROJECT=$(cat ${HOME}/.cm/_CURRENT_PROJECT)
fi
fi
}
function _cm_add() {
echo "Type your alias like: ll='ls -la'"
read -p '> ' ALIAS
local NAME=$(echo "${ALIAS}" | cut -d'=' -f1)
cat ~/.cm/${_PROJECT}/aliases | grep ^${NAME}= > /dev/null
local EXIT=$?
if [ $EXIT -ne 0 ]; then
echo "${ALIAS}" >> ${HOME}/.cm/${_PROJECT}/aliases && \
_cm_reload_project_commands $_PROJECT.$NAME && \
echo "Alias created: ${_PROJECT}.${NAME}"
else
echo "This sub-command already exist"
fi
}
function _cm_reload_project_commands() {
echo "Setting out: $1"
cat ${HOME}/.cm/${_PROJECT}/aliases | sed "s#^#alias $_PROJECT.#g" >> /tmp/.cm-source-file
source /tmp/.cm-source-file
rm /tmp/.cm-source-file
}
function _cm_remove() {
echo 'Removing existing command'
}
function _cm_list() {
grep -Eo "^[a-zA-Z0-9]+=" ${HOME}/.cm/${_PROJECT}/aliases | sed 's#=$##' | sed "s#^#${_PROJECT}.#"
}
function _cm_projects() {
LIST=$(for P in $(find $HOME/.cm/ -maxdepth 1 -type d -print | tail -n+2); do
basename $P
done)
# TODO check if not empty
local CURRENT_PROJECT=$(cat $HOME/.cm/_CURRENT_PROJECT)
echo "$LIST" | sed "s#$CURRENT_PROJECT#$CURRENT_PROJECT*#"
}
# Edit with default editor aliases file
function _cm_edit() {
"${EDITOR:-vi}" ${HOME}/.cm/${_PROJECT}/aliases
cat ${HOME}/.cm/${_PROJECT}/aliases | sed "s#^#alias ${_PROJECT}.#g" > /tmp/.cm-source-file
source /tmp/.cm-source-file
}
_cm__autocomplete