# Copyright (C) 2020 by the Georgia Tech Research Institute (GTRI) # This software may be modified and distributed under the terms of # the BSD 3-Clause license. See the LICENSE file for details. defmodule Mix.Tasks.Lei.BulkAnalyze do use Mix.Task @shortdoc "Run LowEndInsight and analyze a list of git repositories" @moduledoc ~S""" This is used to run a LowEndInsight scan against a repository, by cloning it locally, then looking into it. Pass in the repo URL as a parameter to the task. Skipping validation is possible: ➜ lowendinsight git:(develop) ✗ mix lei.bulk_analyze test/fixtures/npm.short.csv invalid file contents ➜ lowendinsight git:(develop) ✗ mix lei.bulk_analyze test/fixtures/npm.short.csv no_validation 11:45:39.773 [error] Not a Git repo URL, is a subdirectory 11:45:40.102 [info] Cloned -> 3: git+https://github.com/SuzuNohara/zzzROOTPreloader.git 11:45:40.134 [info] Cloned -> 7: git+https://github.com/zenghongyang/test.git 11:45:40.177 [info] Cloned -> 5: git+https://github.com/chameleonbr/zzzz-test-module.git #Usage ``` cat url_list | mix lei.bulk_analyze | jq ``` This will return a big report (prettied by jq), depending on your list quantity. ``` { "state": "complete", "report": { "uuid": "2916881c-67d7-11ea-be2b-88e9fe666193", "repos": [ { "header": { "uuid": "25b55c30-67d6-11ea-9764-88e9fe666193", "start_time": "2020-03-16T22:32:45.324687Z", "source_client": "mix task", "library_version": "", "end_time": "2020-03-16T22:33:24.152148Z", "duration": 39 }, "data": { "risk": "high", "results": { "top10_contributors": [ { ... ``` """ def run(args) do file = List.first(args) case File.exists?(file) do false -> Mix.shell().info("\ninvalid file provided") true -> urls = File.read!(file) |> String.split("\n", trim: true) ## Hacking in a simple handler to bypass validation for the bulk analyzer for a specific ## use case where we need to process invalid URLs listed in a repos pointer to the source ## code. if Enum.at(args, 1) == "no_validation" do {:ok, report} = AnalyzerModule.analyze(urls, "mix task", DateTime.utc_now(), %{types: false}) Poison.encode!(report) |> Mix.shell().info() else case Helpers.validate_urls(urls) do :ok -> {:ok, report} = AnalyzerModule.analyze(urls, "mix task", DateTime.utc_now(), %{types: false}) Poison.encode!(report) |> Mix.shell().info() {:error, _} -> Mix.shell().info("\ninvalid file contents") end end end end end