Hi, I want to get some value from a module which is AST, and why I want to do this you can see this post Getting basic information of an elixir project from GitHub.
for example I have something like this:
code = """
defmodule MishkaDeveloperTools.MixProject do
use Mix.Project
@version "0.0.7"
def project do
[
app: :mishka_developer_tools,
version: @version,
elixir: "~> 1.13",
name: "Mishka developer tools",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps(),
description: description(),
package: package(),
homepage_url: "https://github.com/mishka-group",
source_url: "https://github.com/mishka-group/mishka_developer_tools",
]
end
end
"""
for example, I want to get the values of version
and elixir
and app
, so I used Macro.postwalk
and I do not know it is the right way to do this:
{:ok, ast} = Code.string_to_quoted(code)
ast
|> Macro.postwalk(fn
......
end)
When I print this, I can see something like this:
{:defmodule, [line: 1],
[
{:__aliases__, [line: 1], [:MishkaDeveloperTools, :MixProject]},
[
do: {:__block__, [],
[
{:use, [line: 2], [{:__aliases__, [line: 2], [:Mix, :Project]}]},
{:@, [line: 3], [{:version, [line: 3], ["0.0.7"]}]},
{:def, [line: 5],
[
{:project, [line: 5], nil},
[
do: [
app: :mishka_developer_tools,
version: {:@, [line: 8], [{:version, [line: 8], nil}]},
elixir: "~> 1.13",
name: "Mishka developer tools",
elixirc_paths: {:elixirc_paths, [line: 11],
[
{{:., [line: 11], [{:__aliases__, [line: 11], [:Mix]}, :env]},
[line: 11], []}
]},
start_permanent: {:==, [line: 12],
[
{{:., [line: 12], [{:__aliases__, [line: 12], [:Mix]}, :env]},
[line: 12], []},
:prod
]},
deps: {:deps, [line: 13], []},
description: {:description, [line: 14], []},
package: {:package, [line: 15], []},
homepage_url: "https://github.com/mishka-group",
source_url: "https://github.com/mishka-group/mishka_developer_tools"
]
]
]}
]}
]
]}
After that, I tried to get project
function like this:
Macro.postwalk(ast, fn
{:defmodule, _line ,[_aliases,[do: {:__block__, _, [
{:use, [line: 2], [{:__aliases__, [line: 2], [:Mix, :Project]}]},
{:@, [line: 3], [{:version, [line: 3], ["0.0.7"]}]},
{:def, [line: 5], block}
]}]]} -> IO.inspect block
v -> v
end)
It is hard code and I do not know what is my user mix.exs
file is? So I tried to delete some lanes like:
{:use, [line: 2], [{:__aliases__, [line: 2], [:Mix, :Project]}]},
{:@, [line: 3], [{:version, [line: 3], ["0.0.7"]}]},
but the pattern is not matched, and always the v
pattern is run
Macro.postwalk(ast, fn
{:defmodule, _line ,[_aliases,[do: {:__block__, _, [{:def, [line: 5], block}]}]]} -> IO.inspect block
v -> v
end)
I think I don’t have enough understanding about the AST, how can I do it and get another lane in my source because if I have something like this: version: @version,
I need to back and get @version "0.0.7"
for example
Thank you in advance