2016-07-01 3 views
4

Мне нужно загрузить, изменить и написать код в файле mix.exs. Я хочу иметь возможность загрузить файл, написать зависимости и записать файл.Программный код Elixir:

Я начинаю с:

defmodule Elixir_2ndTest.Mixfile do 
    use Mix.Project 

    def project do 
    [app: :elixir_2nd_test, 
    version: "0.0.1", 
    elixir: "~> 1.2", 
    build_embedded: Mix.env == :prod, 
    start_permanent: Mix.env == :prod, 
    description: description(), 
    deps: deps] 
    end 

    def application do 
    [applications: [:logger]] 
    end 

    defp deps do 
    [] 
    end 
end 

И мне нужно, чтобы в конечном итоге с (единственное отличие заключается в DEPS удовольствия):

defmodule Elixir_2ndTest.Mixfile do 
    use Mix.Project 

    def project do 
    [app: :elixir_2nd_test, 
    version: "0.0.1", 
    elixir: "~> 1.2", 
    build_embedded: Mix.env == :prod, 
    start_permanent: Mix.env == :prod, 
    description: description(), 
    deps: deps] 
    end 

    def application do 
    [applications: [:logger]] 
    end 

    defp deps do 
    [{:httpoison, "~> 0.8.3"}] 
    end 
end 

Зависимости происходят из другой системы сборки (I не может использовать hex напрямую из общедоступного Интернета, поэтому я использую его в режиме OFFLINE и отбрасываю зависимости в .hex/

Я знаю, какие зависимости и какие версии необходимо вставлять в функции deps (в этом случае httpoison 0.8.3).

Если мое понимание правильное, это должно быть возможно, загрузив файл, указав, изменив, выполнив незаметность.

Это то, что у меня до этого момента:

{:ok, body} = File.read("mix.exs") 
{:ok, ast} = Code.string_to_quoted(body) 

Любого указатель на том, как я могу изменить AST и записать его обратно будет оценен.

+0

Я немного заглянул в это в надежде добавить что-то вроде 'mix install', похожего на' npm install', вам в основном придется разбирать и lex-файл. У меня не было возможности вникать в это.Если вы это сделаете, это будет здорово, но его определенно нетривиально, так как deps может быть функцией или несколькими функциями или списком в функции проекта. – TattdCodeMonkey

+0

Я знаю, что такое депо. Мне просто нужно бросить их туда. Все, что там, будет заменено. – Mircea

ответ

1

Это не будет выглядеть точно так же, но вы можете использовать Macro.to_string, чтобы преобразовать ast обратно в код эликсира.

Я играл с помощью своей библиотеки PhStTransform, чтобы изменить аш и преобразовать его обратно в код. Вот очень простой пример из тестовой библиотеки PhStTransform.

test "transform quote do output" do 
    data = quote do: Enum.map(1..3, fn(x) -> x*x end) 
    data_transform = quote do: Enum.map(1..3, fn(y) -> y*y end) 
    replace_x = fn(a, _d) -> 
    case a do 
     :x -> :y 
     atom -> atom 
    end 
    end 
    potion = %{ Atom => replace_x } 
    assert PhStTransform.transform(data, potion) == data_transform 
end 

Что это значит, все ссылки на: x в ast на: y. Вам нужно быть немного умнее писать микстуру для PhStTransform, но я думаю, что это должно быть возможно. PhStTransform находится в шестнадцатеричном режиме.

https://hex.pm/packages/phst_transform

1

Я не эксперт Elixir, но я знаю о преобразовании исходного кода; см. мою биографию.

Если у вас есть доступ к AST как структура данных, вы всегда можете написать процедурный код, чтобы перелезть через него и взломать туда, где вы хотите что-то другое. Я предполагаю, что если Elixir предоставит вам AST, он предоставит вам процедуры доступа/модификации для работы с ним. Это компилятор 101.

Это, как правило, не очень хороший код для написания или поддержки. И этого может быть недостаточно: вам часто нужно больше, чем просто АСТ, чтобы провести серьезный анализ и трансформацию. См. Мое эссе по адресу Life After Parsing l. Подумайте об этом как о компиляторе 102.

Одним из первых камней преткновения является регенерирующий текст из АСТ. Вот моя SO-дискуссия о том, как отпечатать AST, и почему это сложнее, чем выглядит: https://stackoverflow.com/a/5834775/120163

(Похоже, что Fred the Magic Wonder Dog не думала, что предлагаемого Эликсира достаточно, и изобретает собственные расширения сделайте это проще.).

+0

да. вроде как это должно работать, и интересно, есть ли что-то, что можно сделать для Эликсира. – Mircea

+0

Elixir AST - это структура данных Elixir, поэтому ее очень легко преобразовать. Существует не так много инструментов, которые еще нацелены на управление АСТ, но для этого не требуется специальный синтаксический анализ/etc ... –

+0

Я считаю, что разбор/производство АСТ - это самая легкая * часть. После этого все становится сложнее. Вопрос в том, хотите ли вы изобретать все механизмы, необходимые для трансформаций, или вы хотите использовать фонды, где это встроено, и вы можете работать над своей проблемой? –

Смежные вопросы