#!/usr/bin/python3 import os # for checking if file exists import hashlib # for md5sum import sys # for reading cmd args import shutil # for removind directories recursively from subprocess import run # running external programs build_files_src = {} build_files_level = {} build_files_toBuild = {} # Taken from https://www.asciiart.eu/nature/deserts done_art = r""" . _ + . ______ . . ( /|\ . | \ . + . ||||| _ | | | | || . . ||||| | | _| | | | |_|| . /\ ||||| . | | | | | | . __||||_|||||____| |_|_____________\__________ . |||| ||||| /\ _____ _____ . . |||| ||||| |||| . . . ________ . \|`-'|||| |||| __________ . . \__ |||| |||| . . . __ ||||`-'||| . . __________ . . |||| ___/ ___________ . . _ ||||| . _ . _________ _ ___|||||__ _ \\--// . _ _ `---' .)=\oo|=(. _ . . . _ ^ . - . \.| """ def check_if_file(filename, build_file_name): """ Checks it the given file exists, else print error and exit """ if os.path.isfile(filename): return True else: print("In " + build_file_name + " : " + filename + " is not a file") exit(1) def getmd5(filename): """ Takes Path to a file and get it's md5sum """ with open(filename, 'rb') as file_to_check: data = file_to_check.read() md5_returned = hashlib.md5(data).hexdigest() return md5_returned def get_meta_file(filename): """ Takes src file name in build file and converts it to entry in .flow folder filename """ fname = "" for letter in filename: if letter == "." or letter == "\\" or letter == "/": pass else: fname += letter return fname def update_md5(filename): """ Takes the filename in .flow as var fname and updates it's md5sum value according to contents of var filename """ fname = get_meta_file(filename) with open(".flow/" + fname, "w") as f: f.write(getmd5(filename).strip()) def create_md5(filename): """ Takes the filename in .flow as var fname and updates it's md5sum value according to contents of var filename """ fname = get_meta_file(filename) with open(".flow/" + fname, "w") as f: f.write("new file") def getstoredmd5(filename): """ get value of file's md5 from .flow folder, else create entry. return the (md5, createdEntry)""" md5_returned = "" fname = get_meta_file(filename) if fname in os.listdir(".flow"): with open(".flow/" + fname, "r") as f: md5_returned = f.readline() else: print("INFO : md5sum entry not present for " + filename + " creating one.") create_md5(filename) return md5_returned def recieved_file(filename, level, rebuild): if build_files_toBuild.get(filename, False) == False: build_files_toBuild[filename] = rebuild if build_files_level.get(filename, -1) < level: build_files_level[filename] = level pass start, mid, end = "", "", "" with open(filename, "r") as f: x = f.read().split(";!run!;") start = x[0] y = x[1].split(";!end!;") mid = y[0] end = y[1] # start src_files = [] for line in start.split(): entry = line.strip() src_files.append(entry) build_files_src[filename] = src_files if rebuild: build_files_toBuild[filename] = True else: for line in start.split(): entry = line.strip() check_if_file(entry, filename) new_md5, old_md5 = "", "" new_md5 = getmd5(entry) old_md5 = getstoredmd5(entry) if old_md5 != new_md5: print(entry + " was modified") build_files_toBuild[filename] = True # mid if build_files_toBuild[filename]: with open(filename + ".temp", "w") as f: f.write(mid) # end for line in end.split(): entry = line.strip() check_if_file(entry, filename) recieved_file(entry, level + 1, build_files_toBuild[filename]) def remove_if_exists(filename): """ Check if the given filename exists, if yes then print filename and delete """ if os.path.isfile(filename): print("Deleting " + filename) os.remove(filename) def main(): with open("build.flow", "r") as main_build_file: if not os.path.exists(".flow"): os.makedirs(".flow") """ flow clean """ for i in sys.argv: if i == "clean": # delete the .flow folder if os.path.exists(".flow"): print("Deleting .flow directory") shutil.rmtree(".flow") # delete the mentioned files cleaning_started = False for line in main_build_file: entry = line.strip() if cleaning_started: remove_if_exists(entry) if entry == ";!remove!;": cleaning_started = True print("Cleaning done") exit(0) """ creating data for build process """ for line in main_build_file: entry = line.strip() if entry == ";!remove!;": break elif os.path.isfile(entry): recieved_file(entry, 0, False) else: print("ERROR : " + entry + " is neither a file or a directory") exit(1) print(build_files_level) print(build_files_src) print(build_files_toBuild) print() print("<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->") print() """ Build by using the data """ for f, x in list(build_files_toBuild.items()): if x == False: del build_files_level[f] del build_files_src[f] del build_files_toBuild[f] levels_list = [] for f,x in build_files_level.items(): levels_list.append((f,x)) n = len(levels_list) for i in range(n): for j in range(0, n-i-1): if levels_list[j][1] > levels_list[j+1][1]: levels_list[j], levels_list[j+1] = levels_list[j+1], levels_list[j] for item in levels_list: p = run([ "bash", item[0] + ".temp" ]) if p.returncode != 0: print(p) exit(p.returncode) for item in levels_list: build_file_name = item[0] for src_file in build_files_src[build_file_name]: update_md5(src_file) print(done_art) print("Build Completed Successfully") print() print("<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->") print() if __name__ == "__main__": main()