Skip to content

Commit 8c00f2c

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 8c00f2c

File tree

2 files changed

+224
-1
lines changed

2 files changed

+224
-1
lines changed

lib/mix/tasks/ExAtomVM.install.ex

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
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+
"""
59+
About to configure project for AtomVM!
60+
61+
Which device would you like to see setup instructions for?
62+
(Your project will be configured for all devices - this only affects the instructions shown):
63+
""",
64+
["ESP32", "Pico", "STM32", "All"],
65+
default: "All"
66+
)
67+
68+
IO.puts("\nGreat! now we will make the necessary changes to your project...\n")
69+
Process.sleep(2000)
70+
71+
options = [
72+
start: Igniter.Project.Module.module_name_prefix(igniter),
73+
esp32_flash_offset: Sourceror.parse_string!("0x250000"),
74+
stm32_flash_offset: Sourceror.parse_string!("0x8080000"),
75+
chip: "auto",
76+
port: "auto"
77+
]
78+
79+
Igniter.update_elixir_file(igniter, "mix.exs", fn zipper ->
80+
with {:ok, zipper} <- Igniter.Code.Function.move_to_def(zipper, :project, 0),
81+
{:ok, zipper} <-
82+
Igniter.Code.Keyword.put_in_keyword(
83+
zipper,
84+
[:atomvm],
85+
options
86+
) do
87+
{:ok, zipper}
88+
end
89+
end)
90+
|> Igniter.mkdir("avm_deps")
91+
|> Igniter.Project.Module.find_and_update_module!(
92+
Igniter.Project.Module.module_name_prefix(igniter),
93+
fn zipper ->
94+
case Igniter.Code.Function.move_to_def(zipper, :start, 0) do
95+
:error ->
96+
# start function not available, so let's create one
97+
zipper =
98+
Igniter.Code.Common.add_code(
99+
zipper,
100+
"""
101+
def start do
102+
IO.inspect("Hello AtomVM!")
103+
:ok
104+
end
105+
""",
106+
placement: :before
107+
)
108+
109+
{:ok, zipper}
110+
111+
_ ->
112+
{:ok, zipper}
113+
end
114+
end
115+
)
116+
|> Igniter.Project.Deps.set_dep_option(:exatomvm, :runtime, false)
117+
|> Igniter.Project.Deps.set_dep_option(:igniter, :runtime, false)
118+
|> output_instructions(selected_instructions)
119+
end
120+
121+
defp common_intro do
122+
"""
123+
🎉 Your AtomVM project is now ready!
124+
125+
Next, you need to install AtomVM itself on your device.
126+
127+
"""
128+
end
129+
130+
defp output_instructions(igniter, selected_instructions)
131+
when selected_instructions == "ESP32" do
132+
igniter
133+
|> Igniter.add_notice("ESP32 Setup Instructions")
134+
|> Igniter.add_notice("""
135+
#{common_intro()}
136+
137+
## Installing AtomVM on ESP32
138+
139+
Choose one of these methods:
140+
141+
1. **Using Mix task (recommended):**
142+
mix atomvm.esp32.install
143+
144+
2. **Manual installation:**
145+
Follow the guide at: https://doc.atomvm.org/main/getting-started-guide.html#flashing-a-binary-image-to-esp32
146+
147+
3. **Web flasher (Chrome browser only):**
148+
(Choose the Elixir-enabled build of AtomVM.)
149+
Visit: https://petermm.github.io/atomvm_flasher
150+
151+
""")
152+
|> Igniter.add_notice("""
153+
## Flashing Your Project
154+
155+
Once AtomVM is installed on your device, flash your project with:
156+
157+
mix atomvm.esp32.flash
158+
159+
""")
160+
end
161+
162+
defp output_instructions(igniter, selected_instructions)
163+
when selected_instructions == "Pico" do
164+
igniter
165+
|> Igniter.add_notice("Raspberry Pi Pico Setup Instructions")
166+
|> Igniter.add_notice("""
167+
#{common_intro()}
168+
169+
## Installing AtomVM on Raspberry Pi Pico
170+
171+
Follow the installation guide at:
172+
https://doc.atomvm.org/main/getting-started-guide.html#flashing-a-binary-image-to-pico
173+
174+
""")
175+
|> Igniter.add_notice("""
176+
## Flashing Your Project
177+
178+
Once AtomVM is installed on your device, flash your project with:
179+
180+
mix atomvm.pico.flash
181+
182+
For more details, see: https://github.com/atomvm/exatomvm?tab=readme-ov-file#the-atomvmpicoflash-task
183+
""")
184+
end
185+
186+
defp output_instructions(igniter, selected_instructions)
187+
when selected_instructions == "STM32" do
188+
igniter
189+
|> Igniter.add_notice("STM32 Setup Instructions")
190+
|> Igniter.add_notice("""
191+
#{common_intro()}
192+
193+
## Building AtomVM for STM32
194+
195+
STM32 requires building AtomVM for your specific board:
196+
https://doc.atomvm.org/main/build-instructions.html#building-for-stm32
197+
198+
## Installing st-link
199+
200+
You'll need st-link installed for flashing:
201+
- Installation guide: https://github.com/stlink-org/stlink?tab=readme-ov-file#installation
202+
- Flashing guide: https://doc.atomvm.org/main/getting-started-guide.html#flashing-a-binary-image-to-stm32
203+
""")
204+
|> Igniter.add_notice("""
205+
## Flashing Your Project
206+
207+
Once AtomVM is built and installed on your device, flash your project with:
208+
209+
mix atomvm.stm32.flash
210+
211+
For more details, see: https://github.com/atomvm/exatomvm?tab=readme-ov-file#the-atomvmstm32flash-task
212+
""")
213+
end
214+
215+
defp output_instructions(igniter, selected_instructions)
216+
when selected_instructions == "All" do
217+
igniter
218+
|> output_instructions("ESP32")
219+
|> output_instructions("Pico")
220+
|> output_instructions("STM32")
221+
end
222+
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)