예제 #1
0
def get_project_metrics():
    STANDALONE_MODE = getenv("STANDALONE_MODE")
    owner = request.json['owner']
    repo = request.json['repo']
    project_name = owner + "/" + repo
    print(functions.log_time(), "Analyse request for:", project_name)
    if project_name is None:
        print(functions.log_time(), "Project name not set.")
        return jsonify({"error": "an error occurred"}), 500
    status = ""
    last_status = ""

    if STANDALONE_MODE == "True":
        # Standalone mode
        functions.post_status_update(project_name, "in_progress", "Fetching project data.")
        project = functions.get_project_internal(project_name)
        if project.is_empty():
            return jsonify({"error": "standalone mode, project cannot be parsed and is not in the database"}), 503
        result = functions.compute_metrics(project_name, project)
        return jsonify(result), 200
    else:
        while status != "error" and status != "ast_parsed":
            status = functions.get_parsing_status(project_name)
            if status != last_status:
                functions.post_status_update(project_name, status, "Processing project.")
            last_status = status
            time.sleep(5)
        if status == "error":
            return jsonify({"error": "an error occurred attempting to parse this project"}), 500
        if status == "ast_parsed":
            functions.post_status_update(project_name, "in_progress", "Fetching project data.")
            project = functions.get_project_internal(project_name)
            result = functions.compute_metrics(project_name, project)
            return jsonify(result), 200
 def __init__(self):
     # TODO Check if graph exists
     network.Network.__init__(self)
     records = self.__fetch_data()
     self.neo4j_to_network_artifact(records)
     print(functions.log_time(), "Fetched data and built graph.")
     self.__page_rank = self.compute_pagerank()
     print(functions.log_time(), "Calculated pagerank.")
예제 #3
0
 def get_project_node(self):
     for node in self.graph.nodes(data=True):
         if node[1]['type'] == "Project":
             project_node = node
             return project_node
     print(functions.log_time(), "Project node not found.")
     return
    def __fetch_dependent_data(self, project_name):
        print(functions.log_time(), "Fetching dependents.")
        # Dependent projects
        query = ("MATCH p = (parent:Project{id:$projectName})"
                 "-[:Contains*0..1]->(child:Artifact)"
                 "<-[:Depends*0..1]-(dep:Artifact)" + self.query_end)

        with self.db_driver.session() as session:
            result = session.run(query,
                                 parameters={"projectName": project_name})
            return result.records()
예제 #5
0
 def __fetch_data(self, project_name):
     print(functions.log_time(), "Fetching data for", project_name)
     query = ("MATCH p = (parent:Project{id:$projectName})"
              "-[ra:Contains]->(child:Package)"
              "-[rb:Contains]->(class:ClassOrInterface)"
              "-[rc:Contains]->(method:Method)"
              "-[rd:Calls*0..1]->(depMethod:Method) " + self.query_end)
     with self.db_driver.session() as session:
         result = session.run(query,
                              parameters={"projectName": project_name})
         return result.records()
 def __fetch_data(self):
     print(functions.log_time(), "Fetching artifacts")
     query = (
         "MATCH p=(:Artifact)"
         "UNWIND nodes(p) as allnodes WITH COLLECT(ID(allnodes)) AS ALLID "
         "MATCH (a)-[r2]-(b) "
         "WHERE ID(a) IN ALLID AND ID(b) IN ALLID "
         "WITH DISTINCT r2 "
         "RETURN id(startNode(r2)), type(r2), id(endNode(r2))")
     with self.db_driver.session() as session:
         result = session.run(query)
         return result.records()
예제 #7
0
    status = ""
    last_status = ""

    if STANDALONE_MODE == "True":
        # Standalone mode
        functions.post_status_update(project_name, "in_progress", "Fetching project data.")
        project = functions.get_project_internal(project_name)
        if project.is_empty():
            return jsonify({"error": "standalone mode, project cannot be parsed and is not in the database"}), 503
        result = functions.compute_metrics(project_name, project)
        return jsonify(result), 200
    else:
        while status != "error" and status != "ast_parsed":
            status = functions.get_parsing_status(project_name)
            if status != last_status:
                functions.post_status_update(project_name, status, "Processing project.")
            last_status = status
            time.sleep(5)
        if status == "error":
            return jsonify({"error": "an error occurred attempting to parse this project"}), 500
        if status == "ast_parsed":
            functions.post_status_update(project_name, "in_progress", "Fetching project data.")
            project = functions.get_project_internal(project_name)
            result = functions.compute_metrics(project_name, project)
            return jsonify(result), 200


if __name__ == '__main__':
    print(functions.log_time(), "Starting software network analysis!")
    app.run(host='0.0.0.0', debug=True)
    def get_artifacts(self):
        project_node = self.get_project_node()
        if project_node is None:
            print(functions.log_time(), "Error: project node not found")
            return
        project_artifacts = nx.ego_graph(self.graph,
                                         project_node[0],
                                         center=False)
        # Graph of all artifacts, without the project node (all relations should be "Depends")
        graph_of_artifacts_only = nx.ego_graph(self.graph,
                                               project_node[0],
                                               center=False,
                                               undirected=True,
                                               radius=100)
        reversed_graph = graph_of_artifacts_only.reverse()
        direct_dependencies = {}
        transitive_dependencies = {}
        dependents = {}
        project_artifact_details = {}

        # Search through direct dependencies and dependents
        for project_artifact in project_artifacts:
            project_artifact_details[project_artifact] = self.graph.nodes[
                project_artifact]
            project_artifact_details[project_artifact][
                "internal_id"] = project_artifact
            if self.graph.nodes[project_artifact]["type"] == "Artifact":
                # Outgoing nodes from artifact (dependencies)
                artifact_dependencies = nx.ego_graph(self.graph,
                                                     project_artifact,
                                                     center=False,
                                                     radius=1)
                # Direct dependencies
                for artifact_dependency in artifact_dependencies:
                    if self.graph.nodes[artifact_dependency]["type"] == "Artifact" \
                            and artifact_dependency not in direct_dependencies \
                            and artifact_dependency not in project_artifacts:
                        direct_dependencies[
                            artifact_dependency] = self.graph.nodes[
                                artifact_dependency]
                        direct_dependencies[artifact_dependency][
                            "internal_id"] = artifact_dependency

                # Incoming nodes into artifact (dependents)
                artifact_dependents = nx.ego_graph(reversed_graph,
                                                   project_artifact)
                for artifact_dependent in artifact_dependents:
                    if self.graph.nodes[artifact_dependent]["type"] == "Artifact" \
                            and artifact_dependent not in dependents:
                        dependents[artifact_dependent] = self.graph.nodes[
                            artifact_dependent]
                        dependents[artifact_dependent][
                            "internal_id"] = artifact_dependent

        # Search all nodes for nodes not direct dependency or project artifact
        for artifact in graph_of_artifacts_only:
            if self.graph.nodes[artifact]["type"] == "Artifact" and artifact not in direct_dependencies \
                    and artifact not in project_artifact_details and artifact not in dependents:
                transitive_dependencies[artifact] = self.graph.nodes[artifact]
                transitive_dependencies[artifact]["internal_id"] = artifact

        return {
            "Artifact": project_artifact_details,
            "DirectDependency": direct_dependencies,
            "TransitiveDependency": transitive_dependencies,
            "Dependent": dependents,
        }
import functions

app = Flask(__name__)
"""Flask URL -> endpoints"""
CORS(app)


# Routes
@app.route('/artifacts/pageranks', methods=['GET'])
def get_pagerank():
    artifacts = artifacts_network.ArtifactsNetwork()
    artifacts_pagerank = artifacts.compute_pagerank()
    if artifacts is not None:
        return jsonify(artifacts_pagerank), 200
    return 500


@app.route('/artifacts/<string:owner>/<string:repo>', methods=['GET'])
def get_project_artifacts(owner, repo):
    project_name = owner + "/" + repo
    artifact_deps = dependency_network.DependencyNetwork(project_name)
    if artifact_deps.is_empty():
        return jsonify(""), 404
    artifacts = artifact_deps.get_artifacts()
    return jsonify(artifacts), 200


if __name__ == '__main__':
    print(functions.log_time(), "Starting dependency network analysis!")
    app.run(host='0.0.0.0', debug=True)
예제 #10
0
    def compute_metrics(self, project_name, project_node):
        node_metrics = {}  # {a:{comp_a:x, comp_b:y}}
        project_child_nodes = nx.ego_graph(self.graph, project_node[0])
        reversed_graph = self.graph.reverse()  # For nWeakComp
        project_network_comp = 0
        project_procedure_comp = 0
        for project_child_node in project_child_nodes:  # For each package
            package_network_comp = 0
            if self.graph.nodes[project_child_node]["type"] != "Package":
                continue
            print(functions.log_time(), "Analysing metrics for package:",
                  self.graph.nodes[project_child_node]["id"])
            functions.post_status_update(
                project_name, "in_progress", "Analysing metrics for package:" +
                self.graph.nodes[project_child_node]["id"] + ".")
            package_child_nodes = nx.ego_graph(self.graph, project_child_node)
            for package_child_node in package_child_nodes:  # For each class
                if self.graph.nodes[package_child_node][
                        "type"] != "ClassOrInterface":
                    continue
                print(functions.log_time(), "Analysing metrics for class:",
                      self.graph.nodes[package_child_node]["id"])
                functions.post_status_update(
                    project_name, "in_progress",
                    "Analysing metrics for class:" +
                    self.graph.nodes[package_child_node]["id"] + ".")
                class_network_comp = 0
                class_child_nodes = nx.ego_graph(self.graph,
                                                 package_child_node)
                for class_child_node in class_child_nodes:  # For each method
                    if self.graph.nodes[class_child_node]["type"] == "Method":
                        node_metrics[class_child_node] = {}
                        method_network_comp = self.get_network_comp(
                            class_child_node, reversed_graph)
                        procedure_comp = self.procedure_complexity(
                            self.graph.in_degree(class_child_node),
                            self.graph.out_degree(class_child_node))
                        node_metrics[class_child_node][
                            "network_comp"] = method_network_comp
                        node_metrics[class_child_node][
                            "procedure_comp"] = procedure_comp
                        project_procedure_comp += procedure_comp
                        class_network_comp += method_network_comp
                node_metrics[package_child_node] = {}
                node_metrics[package_child_node][
                    "network_comp"] = class_network_comp
                package_network_comp += class_network_comp

            node_metrics[project_child_node] = {}
            node_metrics[project_child_node][
                "network_comp"] = package_network_comp
            project_network_comp += package_network_comp

        node_metrics[project_node[0]] = {}
        node_metrics[project_node[0]]["code_churn"] = round(
            functions.compute_avg_code_change(project_name), 8)
        node_metrics[project_node[0]]["network_comp"] = project_network_comp
        node_metrics[
            project_node[0]]["procedure_comp"] = project_procedure_comp

        functions.post_status_update(project_name, "in_progress",
                                     "Project analysed.")
        print(functions.log_time(), "Internal metrics analysed.")

        return node_metrics