mix_project.ex 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import Snyk.MixProject.Common
  2. defmodule Snyk.MixProject.Mix.Project do
  3. def load_mix_project(""), do: error("Please provide a valid path for the project")
  4. def load_mix_project(path) do
  5. manifest = load_manifest(path)
  6. apps = get_apps(manifest[:apps_path], path)
  7. lock_file_name = get_lock_file_name(manifest[:lockfile])
  8. lock_file_path = Path.join(path, lock_file_name)
  9. lock_file = read_file(lock_file_path)
  10. parent_umbrella_manifest = case Path.dirname(lock_file_path) do
  11. ^path -> nil
  12. parent_path -> load_manifest(parent_path, "parent_app")
  13. end
  14. %{
  15. manifest: manifest,
  16. lock: lock_file,
  17. apps: apps,
  18. parent_umbrella_manifest: parent_umbrella_manifest
  19. }
  20. end
  21. defp read_file(path) do
  22. Path.expand(path)
  23. |> Code.eval_file()
  24. end
  25. defp get_lock_file_name(nil), do: get_lock_file_name("")
  26. defp get_lock_file_name(""), do: "mix.lock"
  27. defp get_lock_file_name(filename), do: filename
  28. defp load_manifest(path), do: load_manifest(path, "root_app")
  29. defp load_manifest(path, app) do
  30. Mix.Project.in_project(
  31. String.to_atom(app),
  32. path,
  33. fn module ->
  34. module.project ++ [module_name: inspect(module)]
  35. end
  36. )
  37. end
  38. defp get_apps(nil, _), do: nil
  39. defp get_apps(apps_path, path) do
  40. Path.join([path, apps_path, "/*/mix.exs"])
  41. |> Path.absname
  42. |> Path.wildcard
  43. |> Enum.map(fn path -> Path.dirname(path) end)
  44. |> Enum.reduce(
  45. %{},
  46. fn full_project_path, acc ->
  47. relative_project_path = Path.relative_to(full_project_path, path)
  48. Map.put(acc, relative_project_path, load_manifest(full_project_path, relative_project_path))
  49. end
  50. )
  51. end
  52. end