Module makefile.make

Source code
from functools import reduce
class Task:
    """A class to keep track of the task's command and dependencies"""
    def __init__(self, dependencies, command):
        """Base for Task class
        
        Arguments:
            dependecies {list[str]} -- list of tasks names that the task depends on
            
            command {str} -- the command associated with the task
        """
        self.dependencies = dependencies
        self.command = command
    def get_dependencies(self):
        """Getter for dependencies"""
        return self.dependencies
    def get_command(self):
        """Getter for command"""
        return self.command
class Make:
    """A class to maintain apps and their depndencies"""
    def __init__(self):
        """Base for Make class
        
        tasks {dict} -- a dict of tasks that is maintained by the class
        """
        self.tasks = {}
    def add_task(self, name, dependencies, command):
        """Adds a new task

        Arguments:
            name {str} -- A descriptive name of the task

            dependencies {list[str]} -- The names of the tasks that it depends on
            command {str} -- The command to be executed to run the task
        """
        self.tasks[name] = Task(dependencies, command)
    def run_task(self, task_name):
        """Prints the commands to run the given task or reports that a cycle occued
        
        Arguments:
            task_name {str} -- the task to be executed
        """
        self.vis = {""}
        self.commands = []
        self.parent = {}
        result = self.traverse_depends(task_name)
        if result != None:
            self.print_cycle(result)
        else:
            print(reduce(lambda x, y: x + y + '\n', self.commands, ""))
    def traverse_depends(self, task_name):
        """Execute all the dependencies of the given task before it
        
        Arguments:
            task_name {str} -- the name of the task

        Returns:
            one of:
                
                None -- If the depencies are traversed correctly

                str  -- If a cycle is detected, a task in the cycle is returned.
        """
        ds = self.tasks[task_name].get_dependencies()
        com = self.tasks[task_name].get_command()
        self.vis.add(task_name)
        for d in ds:
            self.parent[d] = task_name
            if d in self.vis:
                return d
            else:
                x = self.traverse_depends(d)
                if x != None:
                    return x
        self.commands.append(com)

    def print_cycle(self, node):
        """Print the cycle in which the node is in

        node {str} -- the name of a task in the cycle
        """
        print("The tasks:")
        current = self.parent[node]
        print(node)
        while current != node:
            print(current)
            current = self.parent[current]
        print("forms a cycle")
    def print_out_to_string(self, task):
        import sys
        from io import StringIO
        result = StringIO()
        sys.stdout = result
        self.run_task(task)
        sys.stdout = sys.__stdout__
        return result.getvalue()
if __name__ == "__main__":
    b = Make()
    b.add_task("publish", ["build-release"], "print publish")
    b.add_task("build-release", ["nim-installed"], "print exec command to build release mode")
    b.add_task("nim-installed", ["curl-installed"], "print curl LINK | bash")
    b.add_task("curl-installed", ["apt-installed"], "apt-get install curl")
    b.add_task("apt-installed", [], "code to install apt...")
    b.run_task("publish")
    print(b.print_out_to_string("publish"))

Classes

class Make

A class to maintain apps and their depndencies

Base for Make class

tasks {dict} – a dict of tasks that is maintained by the class

Source code
class Make:
    """A class to maintain apps and their depndencies"""
    def __init__(self):
        """Base for Make class
        
        tasks {dict} -- a dict of tasks that is maintained by the class
        """
        self.tasks = {}
    def add_task(self, name, dependencies, command):
        """Adds a new task

        Arguments:
            name {str} -- A descriptive name of the task

            dependencies {list[str]} -- The names of the tasks that it depends on
            command {str} -- The command to be executed to run the task
        """
        self.tasks[name] = Task(dependencies, command)
    def run_task(self, task_name):
        """Prints the commands to run the given task or reports that a cycle occued
        
        Arguments:
            task_name {str} -- the task to be executed
        """
        self.vis = {""}
        self.commands = []
        self.parent = {}
        result = self.traverse_depends(task_name)
        if result != None:
            self.print_cycle(result)
        else:
            print(reduce(lambda x, y: x + y + '\n', self.commands, ""))
    def traverse_depends(self, task_name):
        """Execute all the dependencies of the given task before it
        
        Arguments:
            task_name {str} -- the name of the task

        Returns:
            one of:
                
                None -- If the depencies are traversed correctly

                str  -- If a cycle is detected, a task in the cycle is returned.
        """
        ds = self.tasks[task_name].get_dependencies()
        com = self.tasks[task_name].get_command()
        self.vis.add(task_name)
        for d in ds:
            self.parent[d] = task_name
            if d in self.vis:
                return d
            else:
                x = self.traverse_depends(d)
                if x != None:
                    return x
        self.commands.append(com)

    def print_cycle(self, node):
        """Print the cycle in which the node is in

        node {str} -- the name of a task in the cycle
        """
        print("The tasks:")
        current = self.parent[node]
        print(node)
        while current != node:
            print(current)
            current = self.parent[current]
        print("forms a cycle")
    def print_out_to_string(self, task):
        import sys
        from io import StringIO
        result = StringIO()
        sys.stdout = result
        self.run_task(task)
        sys.stdout = sys.__stdout__
        return result.getvalue()

Methods

def add_task(self, name, dependencies, command)

Adds a new task

Arguments

name {str} – A descriptive name of the task

dependencies {list[str]} – The names of the tasks that it depends on command {str} – The command to be executed to run the task

Source code
def add_task(self, name, dependencies, command):
    """Adds a new task

    Arguments:
        name {str} -- A descriptive name of the task

        dependencies {list[str]} -- The names of the tasks that it depends on
        command {str} -- The command to be executed to run the task
    """
    self.tasks[name] = Task(dependencies, command)
def print_cycle(self, node)

Print the cycle in which the node is in

node {str} – the name of a task in the cycle

Source code
def print_cycle(self, node):
    """Print the cycle in which the node is in

    node {str} -- the name of a task in the cycle
    """
    print("The tasks:")
    current = self.parent[node]
    print(node)
    while current != node:
        print(current)
        current = self.parent[current]
    print("forms a cycle")
def print_out_to_string(self, task)
Source code
def print_out_to_string(self, task):
    import sys
    from io import StringIO
    result = StringIO()
    sys.stdout = result
    self.run_task(task)
    sys.stdout = sys.__stdout__
    return result.getvalue()
def run_task(self, task_name)

Prints the commands to run the given task or reports that a cycle occued

Arguments

task_name {str} – the task to be executed

Source code
def run_task(self, task_name):
    """Prints the commands to run the given task or reports that a cycle occued
    
    Arguments:
        task_name {str} -- the task to be executed
    """
    self.vis = {""}
    self.commands = []
    self.parent = {}
    result = self.traverse_depends(task_name)
    if result != None:
        self.print_cycle(result)
    else:
        print(reduce(lambda x, y: x + y + '\n', self.commands, ""))
def traverse_depends(self, task_name)

Execute all the dependencies of the given task before it

Arguments

task_name {str} – the name of the task

Returns

one of:

None – If the depencies are traversed correctly

str – If a cycle is detected, a task in the cycle is returned.

Source code
def traverse_depends(self, task_name):
    """Execute all the dependencies of the given task before it
    
    Arguments:
        task_name {str} -- the name of the task

    Returns:
        one of:
            
            None -- If the depencies are traversed correctly

            str  -- If a cycle is detected, a task in the cycle is returned.
    """
    ds = self.tasks[task_name].get_dependencies()
    com = self.tasks[task_name].get_command()
    self.vis.add(task_name)
    for d in ds:
        self.parent[d] = task_name
        if d in self.vis:
            return d
        else:
            x = self.traverse_depends(d)
            if x != None:
                return x
    self.commands.append(com)
class Task (dependencies, command)

A class to keep track of the task's command and dependencies

Base for Task class

Arguments

dependecies {list[str]} – list of tasks names that the task depends on

command {str} – the command associated with the task

Source code
class Task:
    """A class to keep track of the task's command and dependencies"""
    def __init__(self, dependencies, command):
        """Base for Task class
        
        Arguments:
            dependecies {list[str]} -- list of tasks names that the task depends on
            
            command {str} -- the command associated with the task
        """
        self.dependencies = dependencies
        self.command = command
    def get_dependencies(self):
        """Getter for dependencies"""
        return self.dependencies
    def get_command(self):
        """Getter for command"""
        return self.command

Methods

def get_command(self)

Getter for command

Source code
def get_command(self):
    """Getter for command"""
    return self.command
def get_dependencies(self)

Getter for dependencies

Source code
def get_dependencies(self):
    """Getter for dependencies"""
    return self.dependencies