Skip to content

Commit 1df0ca8

Browse files
committed
Igniter installer
(install igniter: mix archive.install hex igniter_new) you can try mix igniter.new my_project --install exatomvm@github:petermm/exatomvm && cd my_project adds dependency and atomvm project config and the start function. early days in igniter world, but should be good to go. Signed-off-by: Peter M <[email protected]>
1 parent 49bb1d5 commit 1df0ca8

File tree

2 files changed

+216
-1
lines changed

2 files changed

+216
-1
lines changed

lib/mix/tasks/ExAtomVM.install.ex

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
defmodule Mix.Tasks.Exatomvm.Install do
2+
use Igniter.Mix.Task
3+
4+
@example "mix igniter.new my_project --install exatomvm@github:atomvm/exatomvm && cd my_project"
5+
6+
@shortdoc "Add and configure AtomVM for your project"
7+
@moduledoc """
8+
#{@shortdoc}
9+
10+
This task sets up your Elixir project to work with AtomVM, adding necessary dependencies
11+
and configuration for targeting embedded devices like ESP32, Raspberry Pi Pico, and STM32.
12+
13+
## Example
14+
15+
```bash
16+
#{@example}
17+
```
18+
19+
"""
20+
21+
@impl Igniter.Mix.Task
22+
def info(_argv, _composing_task) do
23+
%Igniter.Mix.Task.Info{
24+
# Groups allow for overlapping arguments for tasks by the same author
25+
# See the generators guide for more.
26+
group: :exatomvm,
27+
# dependencies to add
28+
adds_deps: [
29+
{:pythonx, "~> 0.4.0", runtime: false},
30+
{:req, "~> 0.5.0", runtime: false}
31+
],
32+
# dependencies to add and call their associated installers, if they exist
33+
installs: [],
34+
# An example invocation
35+
example: @example,
36+
# A list of environments that this should be installed in.
37+
only: nil,
38+
# a list of positional arguments, i.e `[:file]`
39+
positional: [],
40+
# Other tasks your task composes using `Igniter.compose_task`, passing in the CLI argv
41+
# This ensures your option schema includes options from nested tasks
42+
composes: [],
43+
# `OptionParser` schema
44+
schema: [],
45+
# Default values for the options in the `schema`
46+
defaults: [],
47+
# CLI aliases
48+
aliases: [],
49+
# A list of options in the schema that are required
50+
required: []
51+
}
52+
end
53+
54+
@impl Igniter.Mix.Task
55+
def igniter(igniter) do
56+
selected_instructions =
57+
Igniter.Util.IO.select(
58+
"Which device would you like to see setup instructions for?\n(Your project will be configured for all devices - this only affects the instructions shown):",
59+
["ESP32", "Pico", "STM32", "All"]
60+
)
61+
62+
IO.puts(selected_instructions)
63+
64+
options = [
65+
start: Igniter.Project.Module.module_name_prefix(igniter),
66+
esp32_flash_offset: Sourceror.parse_string!("0x250000"),
67+
stm32_flash_offset: Sourceror.parse_string!("0x8080000"),
68+
chip: "auto",
69+
port: "auto"
70+
]
71+
72+
Igniter.update_elixir_file(igniter, "mix.exs", fn zipper ->
73+
with {:ok, zipper} <- Igniter.Code.Function.move_to_def(zipper, :project, 0),
74+
{:ok, zipper} <-
75+
Igniter.Code.Keyword.put_in_keyword(
76+
zipper,
77+
[:atomvm],
78+
options
79+
) do
80+
{:ok, zipper}
81+
end
82+
end)
83+
|> Igniter.mkdir("avm_deps")
84+
|> Igniter.Project.Module.find_and_update_module!(
85+
Igniter.Project.Module.module_name_prefix(igniter),
86+
fn zipper ->
87+
case Igniter.Code.Function.move_to_def(zipper, :start, 0) do
88+
:error ->
89+
# start function not available, so let's create one
90+
zipper =
91+
Igniter.Code.Common.add_code(
92+
zipper,
93+
"""
94+
def start do
95+
IO.inspect("Hello AtomVM!")
96+
:ok
97+
end
98+
""",
99+
placement: :before
100+
)
101+
102+
{:ok, zipper}
103+
104+
_ ->
105+
{:ok, zipper}
106+
end
107+
end
108+
)
109+
|> Igniter.Project.Deps.set_dep_option(:exatomvm, :runtime, false)
110+
|> Igniter.Project.Deps.set_dep_option(:igniter, :runtime, false)
111+
|> output_instructions(selected_instructions)
112+
end
113+
114+
defp common_intro do
115+
"""
116+
🎉 Your AtomVM project is now ready!
117+
118+
Next, you need to install AtomVM itself on your target device.
119+
Important: Make sure to choose the Elixir-enabled build of AtomVM.
120+
"""
121+
end
122+
123+
defp output_instructions(igniter, selected_instructions)
124+
when selected_instructions == "ESP32" do
125+
igniter
126+
|> Igniter.add_notice("ESP32 Setup Instructions")
127+
|> Igniter.add_notice("""
128+
#{common_intro()}
129+
130+
## Installing AtomVM on ESP32
131+
132+
Choose one of these methods:
133+
134+
1. **Using Mix task (recommended):**
135+
mix atomvm.esp32.install
136+
137+
2. **Manual installation:**
138+
Follow the guide at: https://doc.atomvm.org/main/getting-started-guide.html#flashing-a-binary-image-to-esp32
139+
140+
3. **Web flasher (Chrome browser only):**
141+
Visit: https://petermm.github.io/atomvm_flasher
142+
143+
""")
144+
|> Igniter.add_notice("""
145+
## Flashing Your Project
146+
147+
Once AtomVM is installed on your device, flash your project with:
148+
149+
mix atomvm.esp32.flash
150+
151+
""")
152+
end
153+
154+
defp output_instructions(igniter, selected_instructions)
155+
when selected_instructions == "Pico" do
156+
igniter
157+
|> Igniter.add_notice("Raspberry Pi Pico Setup Instructions")
158+
|> Igniter.add_notice("""
159+
#{common_intro()}
160+
161+
## Installing AtomVM on Raspberry Pi Pico
162+
163+
Follow the installation guide at:
164+
https://doc.atomvm.org/main/getting-started-guide.html#flashing-a-binary-image-to-pico
165+
166+
""")
167+
|> Igniter.add_notice("""
168+
## Flashing Your Project
169+
170+
Once AtomVM is installed on your device, flash your project with:
171+
172+
mix atomvm.pico.flash
173+
174+
For more details, see: https://github.com/atomvm/exatomvm?tab=readme-ov-file#the-atomvmpicoflash-task
175+
""")
176+
end
177+
178+
defp output_instructions(igniter, selected_instructions)
179+
when selected_instructions == "STM32" do
180+
igniter
181+
|> Igniter.add_notice("STM32 Setup Instructions")
182+
|> Igniter.add_notice("""
183+
#{common_intro()}
184+
185+
## Building AtomVM for STM32
186+
187+
STM32 requires building AtomVM for your specific board:
188+
https://doc.atomvm.org/main/build-instructions.html#building-for-stm32
189+
190+
## Installing st-link
191+
192+
You'll need st-link installed for flashing:
193+
- Installation guide: https://github.com/stlink-org/stlink?tab=readme-ov-file#installation
194+
- Flashing guide: https://doc.atomvm.org/main/getting-started-guide.html#flashing-a-binary-image-to-stm32
195+
""")
196+
|> Igniter.add_notice("""
197+
## Flashing Your Project
198+
199+
Once AtomVM is built and installed on your device, flash your project with:
200+
201+
mix atomvm.stm32.flash
202+
203+
For more details, see: https://github.com/atomvm/exatomvm?tab=readme-ov-file#the-atomvmstm32flash-task
204+
""")
205+
end
206+
207+
defp output_instructions(igniter, selected_instructions)
208+
when selected_instructions == "All" do
209+
igniter
210+
|> output_instructions("ESP32")
211+
|> output_instructions("Pico")
212+
|> output_instructions("STM32")
213+
end
214+
end

mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ defmodule ExAtomVM.MixProject do
3535
{:uf2tool, "1.1.0", runtime: false},
3636
{:ex_doc, "~> 0.20", only: :dev, runtime: false},
3737
{:pythonx, "~> 0.4.0", runtime: false, optional: true},
38-
{:req, "~> 0.5.0", runtime: false, optional: true}
38+
{:req, "~> 0.5.0", runtime: false, optional: true},
39+
{:igniter, "~> 0.6", runtime: false, optional: true}
3940
]
4041
end
4142
end

0 commit comments

Comments
 (0)