parent
0b5c7ce740
commit
5301062b0c
@ -0,0 +1,8 @@
|
||||
*Compile
|
||||
#do
|
||||
gcc -o tasks tasks.c
|
||||
|
||||
*Test
|
||||
#do
|
||||
./tasks test.tsk
|
||||
|
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
import pickle
|
||||
from subprocess import run
|
||||
|
||||
tasks = []
|
||||
|
||||
class Task:
|
||||
name = ""
|
||||
ifchange = []
|
||||
commands = []
|
||||
|
||||
def show(self):
|
||||
print(self.name)
|
||||
print(self.ifchange)
|
||||
print(self.commands)
|
||||
|
||||
|
||||
dragon_ascii = """
|
||||
,,
|
||||
`""*$b..
|
||||
""*$o.
|
||||
"$$o.
|
||||
"*$$o.
|
||||
"$$$o.
|
||||
"$$$$bo... ..o:
|
||||
"$$$$$$$$booocS$$$ .. ,.
|
||||
". "*$$$$SP V$o..o$$. .$$$b
|
||||
"$$o. .$$$$$o. ...A$$$$$$$$$$$$$$b
|
||||
""bo. "*$$$$$$$$$$$$$$$$$$$$P*$$$$$$$$:
|
||||
"$$. V$$$$$$$$$P"**""*"' VP * "l
|
||||
"$$$o.4$$$$$$$$X
|
||||
"*$$$$$$$$$$$$$AoA$o..oooooo.. .b
|
||||
.X$$$$$$$$$$$P"" ""*oo,, ,$P
|
||||
$$P""V$$$$$$$: . ""*****"
|
||||
.*" A$$$$$$$$o.4; .
|
||||
.oP"" "$$$$$$b. .$;
|
||||
A$$$$$$$$$$P
|
||||
" "$$$$$P"
|
||||
$$P*"
|
||||
mls .$"
|
||||
"
|
||||
"""
|
||||
|
||||
|
||||
help_message = """
|
||||
tasks :
|
||||
A simple way to define tasks and execute them.
|
||||
|
||||
Usage: tasks file
|
||||
"""
|
||||
def print_help():
|
||||
""" print help and usage """
|
||||
print(dragon_ascii)
|
||||
print(help_message)
|
||||
|
||||
def check_if_file(in_file, check_file):
|
||||
""" Checks it the given file exists, else print error and exit """
|
||||
if os.path.isfile(check_file):
|
||||
return True
|
||||
else:
|
||||
print("In " + in_file + " : " + check_file + " is not a file")
|
||||
exit(1)
|
||||
|
||||
def getsha1(filename):
|
||||
""" Return the sha1 value of the given filename """
|
||||
with open(filename, 'rb') as file_to_check:
|
||||
data = file_to_check.read()
|
||||
sha1_returned = hashlib.sha1(data).hexdigest()
|
||||
return sha1_returned
|
||||
|
||||
def do_tasks(tasks_file):
|
||||
""" Do the tasks stored in tasks list """
|
||||
stored_entries = {}
|
||||
if os.path.isfile("." + tasks_file + ".bin"):
|
||||
stored_entries = pickle.load(open("." + tasks_file + ".bin", 'rb'))
|
||||
|
||||
for task in tasks:
|
||||
redo_task = False
|
||||
|
||||
""" If change check """
|
||||
for f in task.ifchange:
|
||||
if stored_entries.get(f, "") != getsha1(f):
|
||||
stored_entries[f] = getsha1(f)
|
||||
redo_task = True
|
||||
|
||||
""" Update the stored_entries for this tasks file """
|
||||
pickle.dump(stored_entries, open("." + tasks_file + ".bin", 'wb'))
|
||||
|
||||
if len(task.ifchange) < 1:
|
||||
redo_task = True
|
||||
|
||||
if redo_task == False:
|
||||
continue
|
||||
|
||||
""" Run Commands of the Task """
|
||||
for c in task.commands:
|
||||
print("+ " + c)
|
||||
p = run(c.split())
|
||||
if p.returncode != 0:
|
||||
print(p)
|
||||
print("Task Failed : " + task.name , file=sys.stderr )
|
||||
exit(p.returncode)
|
||||
|
||||
def get_tasks(filename):
|
||||
""" Take a tasks file and convert it to Task structures, stored in a global tasks list """
|
||||
number_of_tasks = 0
|
||||
# Possible sections : comment, ifchange, commands
|
||||
current_section = ""
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
for line in f.readlines():
|
||||
l = line.strip()
|
||||
|
||||
if len(l) > 0 and l[0] == '*':
|
||||
number_of_tasks += 1
|
||||
tasks.append(Task())
|
||||
tasks[number_of_tasks - 1].name = l[1:].strip()
|
||||
tasks[number_of_tasks - 1].ifchange = []
|
||||
tasks[number_of_tasks - 1].commands = []
|
||||
current_section = "comment"
|
||||
continue
|
||||
elif l == "#ifchange":
|
||||
current_section = "ifchange"
|
||||
continue
|
||||
elif l == "#do":
|
||||
current_section = "commands"
|
||||
continue
|
||||
|
||||
if current_section == "ifchange":
|
||||
for entry in l.split():
|
||||
check_if_file(filename, entry)
|
||||
tasks[number_of_tasks - 1].ifchange.append(entry)
|
||||
elif current_section == "commands" and len(l) > 0:
|
||||
tasks[number_of_tasks - 1].commands.append(l)
|
||||
|
||||
def main():
|
||||
tasks_file = "main.tasks"
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
if os.path.isfile(sys.argv[1]):
|
||||
tasks_file = sys.argv[1]
|
||||
else:
|
||||
print_help()
|
||||
exit(1)
|
||||
|
||||
get_tasks(tasks_file)
|
||||
print("<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->")
|
||||
for task in tasks:
|
||||
print("For task named " + task.name)
|
||||
task.show()
|
||||
print("<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->")
|
||||
do_tasks(tasks_file)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
pass
|
@ -0,0 +1,255 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_TASKS 5
|
||||
|
||||
typedef enum {false, true} bool;
|
||||
|
||||
typedef struct TASKS_str_linked_list{
|
||||
char *data;
|
||||
struct TASKS_str_linked_list *next;
|
||||
} TASKS_str_linked_list;
|
||||
|
||||
void TASKS_sll_print(TASKS_str_linked_list *list){
|
||||
printf("[ ");
|
||||
while(list != NULL){
|
||||
printf(" %s ,", list->data);
|
||||
list = list->next;
|
||||
}
|
||||
printf(" ]\n");
|
||||
}
|
||||
|
||||
//* Takes pointer to linked list head *//
|
||||
void TASKS_sll_add(TASKS_str_linked_list **list, char *s){
|
||||
TASKS_str_linked_list *node = (TASKS_str_linked_list *) malloc(sizeof(TASKS_str_linked_list));
|
||||
node->data = s;
|
||||
node->next = *list;
|
||||
*list = node;
|
||||
}
|
||||
|
||||
// The length values will also count \0
|
||||
typedef struct TASKS_task{
|
||||
char name[100];
|
||||
TASKS_str_linked_list *ifchange;
|
||||
TASKS_str_linked_list *commands;
|
||||
} TASKS_task;
|
||||
|
||||
|
||||
TASKS_task TASKS_new_task(char *name){
|
||||
TASKS_task r;
|
||||
strcpy(r.name, name);
|
||||
r.ifchange = NULL;
|
||||
r.commands = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
void TASKS_delete_task(TASKS_task task){
|
||||
// TODO : HERE
|
||||
// This will need to create functions to free TASKS_str_linked_list
|
||||
// For a task ifchange list and commands list needs to be freed
|
||||
// For freeing list, we need to free both strings and the nodes
|
||||
}
|
||||
|
||||
// We currently keeping a global list of tasks.
|
||||
int number_of_tasks = 0;
|
||||
TASKS_task tasks[MAX_TASKS];
|
||||
|
||||
//* Returns the substring from index x to y (both inclusive) *//
|
||||
//* The returned string needs to be freed by the caller of the function *//
|
||||
//* Adds the \0 at end *//
|
||||
char *TASKS_substr(const char *s, int x, int y){
|
||||
assert(y >= x);
|
||||
char *r = (char *) malloc(sizeof(char) * (y - x + 2));
|
||||
|
||||
int j = 0;
|
||||
for(int i = x; i <= y; i++){
|
||||
r[j++] = s[i];
|
||||
}
|
||||
|
||||
r[j] = '\0';
|
||||
return r;
|
||||
}
|
||||
|
||||
//* Checks if file exists by trying to open it *//
|
||||
bool TASKS_file_exists(char *filename){
|
||||
FILE *f = fopen(filename, "r");
|
||||
if(errno == ENOENT)
|
||||
return false;
|
||||
else{
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//* Remove white space before and after a line *//
|
||||
//* This function works straight on the pointer, so keep a copy if you need orignal line. *//
|
||||
void TASKS_strip_line(char *line){
|
||||
int len = 0;
|
||||
while(line[len] != '\0') len += 1;
|
||||
|
||||
int start = 0;
|
||||
int end = len;
|
||||
|
||||
for(int i = 0; i < len; i ++){
|
||||
if(line[i] != '\n' && line[i] != '\t' && line[i] != ' ')
|
||||
break;
|
||||
start += 1;
|
||||
}
|
||||
|
||||
for(int i = (len-1); i >= 0; i--){
|
||||
if(line[i] != '\n' && line[i] != '\t' && line[i] != ' ')
|
||||
break;
|
||||
end = i;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for(int i = start; i <= end; i++)
|
||||
line[j++] = line[i];
|
||||
line[end - start] = '\0';
|
||||
}
|
||||
|
||||
//* Returns true if there are more lines to read, else returns false. *//
|
||||
bool TASKS_get_line(FILE *f, char *line, int *current_line_capacity){
|
||||
if(*current_line_capacity > 1)
|
||||
line[0] = '\0';
|
||||
|
||||
char c;
|
||||
int i = 0;
|
||||
while(true){
|
||||
c = fgetc(f);
|
||||
|
||||
if(c == EOF)
|
||||
return false;
|
||||
|
||||
if(c == '\n'){
|
||||
line[i] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
if(i > *current_line_capacity){
|
||||
*current_line_capacity *= 2;
|
||||
int x = *current_line_capacity;
|
||||
line = (char *) realloc(line, sizeof(char) * x);
|
||||
}
|
||||
|
||||
line[i++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void TASKS_get_tasks(char *filename){
|
||||
char current_section[10] = "comment";
|
||||
int current_line_capacity = 100;
|
||||
char *current_line = (char *) malloc(sizeof(char) * current_line_capacity);
|
||||
assert(current_line != NULL);
|
||||
|
||||
FILE *f = fopen(filename, "r");
|
||||
assert(f != NULL);
|
||||
|
||||
bool semicolon = true;
|
||||
while(TASKS_get_line(f, current_line, ¤t_line_capacity)){
|
||||
TASKS_strip_line(current_line);
|
||||
|
||||
if(current_line[0] == '\0') continue;
|
||||
|
||||
//* Uncomment to print the file read by program line by line *//
|
||||
//printf("%s\n", current_line);
|
||||
|
||||
// This length includes the \0
|
||||
int current_line_len = 0;
|
||||
while(current_line[current_line_len++] != '\0');
|
||||
|
||||
// Setting current section
|
||||
if(current_line[0] != '\0' && current_line[0] == '*'){
|
||||
number_of_tasks += 1;
|
||||
if(number_of_tasks > MAX_TASKS){
|
||||
printf("MAX_TASKS exceeded, increase the number of max tasks in the source file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tasks[number_of_tasks - 1] = TASKS_new_task(TASKS_substr(current_line,1,current_line_len - 1));
|
||||
strcpy(current_section, "comment");
|
||||
continue;
|
||||
}else if(strcmp(current_line, "#ifchange") == 0){
|
||||
strcpy(current_section, "ifchange");
|
||||
continue;
|
||||
}else if(strcmp(current_line, "#do") == 0){
|
||||
strcpy(current_section, "commands");
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse file based on current section
|
||||
if(strcmp(current_section, "ifchange") == 0){
|
||||
// TODO : ADD '\ ' to support files with spaces
|
||||
// We use x and y to get substrings from x-y
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
while(current_line[y++] != '\0'){
|
||||
if(current_line[y] == '\n' || current_line[y] == '\t' || current_line[y] == ' '){
|
||||
char *to_add = TASKS_substr(current_line, x, y);
|
||||
TASKS_strip_line(to_add);
|
||||
TASKS_sll_add(&tasks[number_of_tasks - 1].ifchange, to_add);
|
||||
x = y;
|
||||
while(current_line[++y] == '\n' || current_line[y] == '\t' || current_line[y] == ' ');
|
||||
}
|
||||
}
|
||||
char *to_add = TASKS_substr(current_line, x, y);
|
||||
TASKS_strip_line(to_add);
|
||||
if(to_add[0] == '\0') continue;
|
||||
else TASKS_sll_add(&tasks[number_of_tasks - 1].ifchange, to_add);
|
||||
|
||||
}else if(strcmp(current_section, "commands") == 0){
|
||||
TASKS_sll_add(&tasks[number_of_tasks - 1].commands, TASKS_substr(current_line, 0, current_line_len - 2));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(current_line);
|
||||
}
|
||||
|
||||
void TASKS_do_all_tasks(){
|
||||
for(int i = 0; i < number_of_tasks; i++){
|
||||
printf("[*] EXECUTING TASK : %s\n", tasks[i].name);
|
||||
TASKS_str_linked_list *cll = tasks[i].commands;
|
||||
while(cll != NULL){
|
||||
char *cmd = cll->data;
|
||||
printf("+ %s\n", cmd);
|
||||
system(cmd);
|
||||
cll = cll->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
char *tasks_file = "main.tsk";
|
||||
|
||||
if(argc > 1){
|
||||
if(TASKS_file_exists(argv[1]))
|
||||
tasks_file = argv[1];
|
||||
else{
|
||||
/* Print Help Here */
|
||||
printf("File does not exist");
|
||||
exit(ENOENT);
|
||||
}
|
||||
}
|
||||
|
||||
assert(TASKS_file_exists(tasks_file));
|
||||
|
||||
printf("Working on tasks file : %s\n", tasks_file);
|
||||
TASKS_get_tasks(tasks_file);
|
||||
|
||||
for(int i = 0; i < number_of_tasks; i++){
|
||||
printf("\n<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->\n\n");
|
||||
printf("For task named : %s\n", tasks[i].name);
|
||||
printf("ifchange : "); TASKS_sll_print(tasks[i].ifchange);
|
||||
printf("Commands : "); TASKS_sll_print(tasks[i].commands);
|
||||
}
|
||||
printf("\n<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->\n\n");
|
||||
|
||||
//* From here we just need to execute all tasks *//
|
||||
TASKS_do_all_tasks();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue