shahryarjb

shahryarjb

Getting basic information of a elixir project from GitHub

Hi, Please consider you have a project in GitHub and before running and getting it with mix deps task you want to get some basic information like what is the version and name of this library from mix.exs file.

So regex is not a good way because some people put version as global variable like @version, hence I need to run whole the mix.exs and get the version and name from it.

What is your suggesting to get mix.exs as string from GitHub and compile it? For example, and get the name and version from it or another information before installing it.


I do not know Code.eval_string(code) is useful for me and safe? All the examples in the document is about a function or operation, but not about a full module:

{:module, MishkaDeveloperTools.MixProject,
 <<70, 79, 82, 49, 0, 0, 11, 156, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 1, 5,
   0, 0, 0, 25, 38, 69, 108, 105, 120, 105, 114, 46, 77, 105, 115, 104, 107, 97,
   68, 101, 118, 101, 108, 111, 112, 101, 114, ...>>, {:package, 0}}

After evaluating the module, I do not know how to get version for example:

MishkaDeveloperTools.MixProject.project()

Thank you in advance

Most Liked Responses

hst337

hst337

Code.eval_string is not safe. I’d suggest Code.string_to_quoted

hst337

hst337

You can just travese AST with functions provided in macro. You should look for field version in project funcion. If it contains, @version, than look for @version attirbute. If it contains something else, than there’s no safe way to fetch a version without executing code defined in this module

LostKobrakai

LostKobrakai

The AST of a keyword list is not a keyword list by itself, so you cannot use Keyword to access things. AST is an abstraction of written code, and not of the data represented by that code. You’ll need more manual approaches for filtering out the information you need.

A rather naive appraoch to getting to the information you seek would be like this:

{_ast, acc} =
  Macro.postwalk(ast, %{version: nil, attributes: %{}}, fn
    {:@, _, [{name, _, value}]} = ast, acc when is_atom(name) and not is_nil(value) ->
      {ast, put_in(acc.attributes[name], value)}

    {:version, {:@, _, [{name, _, nil}]}} = ast, acc ->
      {ast, Map.put(acc, :version, {:attribute, name})}

    {:version, value} = ast, acc ->
      {ast, Map.put(acc, :version, value)}

    ast, acc ->
      {ast, acc}
  end)

acc
# %{attributes: %{version: ["0.0.7"]}, version: {:attribute, :version}}

However you’d want to be more cautious as currently any later keyword list with a :version key would overwrite the returned result.

What you’re doing here is very brittle, as you’re trying to interpret code without running it, which can easily break by someone not sticking to conventions closely.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; somethi...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New

We're in Beta

About us Mission Statement