littlebitarestsructure

pull/231/head
connor rigby 2017-01-16 10:48:36 -08:00
parent f3bf5727c7
commit 481783e646
7 changed files with 12 additions and 288 deletions

1
VERSION 120000
View File

@ -0,0 +1 @@
apps/farmbot/VERSION

View File

@ -1,77 +0,0 @@
defmodule Mix.Tasks.Farmbot.Upload do
use Mix.Task
@shortdoc "Uploads a file to a url"
def run(args) do
ip_address = List.first(args)
|| "192.168.29.186" # I get to do this because i own it.
curl_args = [
"-T", "_images/rpi3/farmbot.fw",
"http://#{ip_address}:8988/firmware",
"-H", "Content-Type: application/x-firmware",
"-H", "X-Reboot: true"]
IO.puts("Starting upload...")
Mix.Tasks.Farmbot.Curl.run(curl_args)
end
end
defmodule Mix.Tasks.Farmbot.Curl do
use Mix.Task
@shortdoc "Uploads an image to a development target"
def run(args) do
args = args ++
[ "-#" ] # CURL OPTIONS
Port.open({:spawn_executable, "/usr/bin/curl"},
[{:args, args},
:stream,
:binary,
:exit_status,
:hide,
:use_stdio,
:stderr_to_stdout])
handle_output()()
end
def handle_output() do
receive do
info -> handle_info(info)
end
end
def handle_info({port, {:data, << <<35>>, _ :: size(568), " 100.0%">>}}) do # LAWLZ
IO.puts("\nDONE")
Port.close(port)
end
def handle_info({port, {:data, << "\r", <<35>>, _ :: size(568), " 100.0%">>}}) do # LAWLZ
IO.puts("\nDONE")
Port.close(port)
end
def handle_info({_port, {:data, << <<35>>, <<_ :: binary>> >>}}) do
IO.write("#")
handle_output()
end
def handle_info({_port, {:data, << "\n", <<35>>, <<_ :: binary>> >>}}) do
IO.write("#")
handle_output()
end
def handle_info({_port, {:data, << "\r", <<35>>, <<_ :: binary>> >>}}) do
IO.write("#")
handle_output()
end
def handle_info({_port, {:data, _data}}) do
# IO.puts(data)
handle_output()
end
def handle_info({_port, {:exit_status, 7}}) do
IO.puts("\nCOULD NOT CONNECT TO DEVICE!")
end
def handle_info({_port, {:exit_status, _status}}) do
IO.puts("\nDONE")
end
end

170
mix.exs
View File

@ -1,8 +1,11 @@
defmodule FarmbotOs.Mixfile do
use Mix.Project
@version Path.join(__DIR__, "VERSION") |> File.read! |> String.strip
def project do
[apps_path: "apps",
version: @version,
target: target(Mix.env),
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
@ -11,164 +14,13 @@ defmodule FarmbotOs.Mixfile do
# Dependencies listed here are available only for this project
# and cannot be accessed from applications inside the apps folder
defp deps, do: [{:httpotion, "~> 3.0.0"}]
defp deps, do: []
defp target(:prod), do: System.get_env("NERVES_TARGET") || "rpi3"
defp target(_), do: System.get_env("NERVES_TARGET") || "development"
end
defmodule Mix.Tasks.Farmbot do
def env_info do
IO.puts "[ NERVES_TARGET ]: #{Mix.Project.config[:target]}"
System.put_env("NERVES_TARGET", "#{Mix.Project.config[:target]}")
if System.get_env("NERVES_SYSTEM") do
IO.puts "[ NERVES_SYSTEM ]: #{System.get_env("NERVES_SYSTEM")}"
end
IO.puts "[ ENVIRONMENT ]: #{Mix.env}"
IO.puts "[ GIT HASH ]: #{git_revision}"
end
defp git_revision do
# git log --pretty=format:'%h' -n 1
{res, 0} = System.cmd("git", ["log", "--pretty=format:%h", "-n 1"])
res |> String.trim
end
defmodule System do
def run(_) do
Mix.Tasks.Farmbot.env_info
port = Port.open({:spawn, "bash ./scripts/clone_system.sh"},
[:stream,
:binary,
:exit_status,
:hide,
:use_stdio,
:stderr_to_stdout])
handle_port(port)
end
def handle_port(port) do
receive do
{^port, {:data, data}} -> IO.puts data; handle_port(port)
{^port, {:exit_status, 0}} -> IO.puts "Environment built!"
{^port, {:exit_status, _}} -> IO.puts "Error setting up environment"
stuff -> IO.puts "unexpected stuff: #{inspect stuff}"
end
end
end
defmodule Firmware do
use Mix.Task
@shortdoc "Builds firmware."
def run(args) do
Mix.Tasks.Farmbot.env_info
:ok = case handle_args(args) do
true -> do_run(args)
_ -> :ok
end
if Enum.find_value(args, fn(arg) -> arg == "--upload" end) do
if Elixir.System.get_env("BOT_IP_ADDR") == nil do
Elixir.System.put_env("BOT_IP_ADDR", "192.168.24.1")
end
ip = Elixir.System.get_env("BOT_IP_ADDR")
port = Port.open({:spawn, "bash ./scripts/upload.sh"},
[:stream,
:binary,
:exit_status,
:hide,
:use_stdio,
:stderr_to_stdout])
handle_port(port, "Uploaded!", "Failed to upload!")
end
end
def check_system_dir do
{:ok, dirs} = File.ls "./apps/"
Enum.find(dirs, fn(dir) ->
String.contains?(dir, "NERVES_SYSTEM")
end)
end
def do_run(_args) do
maybe_system_dir = check_system_dir
if maybe_system_dir && Elixir.System.get_env("NERVES_SYSTEM") == nil do
IO.puts "detected a system build: #{maybe_system_dir}, set the NERVES_SYSTEM env var to use it."
end
if !File.exists?("./deps") do
fetch_deps
end
port = Port.open({:spawn, "bash ./scripts/build.sh"},
[:stream,
:binary,
:exit_status,
:hide,
:use_stdio,
:stderr_to_stdout])
handle_port(port, "Built firmware!", "Error building firmware!")
end
def handle_port(port, success, err) do
receive do
{^port, {:data, data}} -> IO.puts data; handle_port(port, success, err)
{^port, {:exit_status, 0}} -> IO.puts success; :ok
{^port, {:exit_status, _}} -> IO.puts err; :error
stuff -> IO.puts "unexpected stuff: #{inspect stuff}"; :error
end
end
defp fetch_deps do
IO.puts "Fetching dependencies."
Mix.Tasks.Deps.Get.run([])
true
end
def handle_args(args) do
Enum.all?(args, fn(arg) ->
do_thing(arg)
end)
end
# Because reasons.
def do_thing("-h"), do: do_thing("--help")
def do_thing("--help") do
IO.puts help_text
false
end
def do_thing("--clean") do
IO.puts "cleaning environment!"
File.rm_rf("deps")
File.rm_rf("_build")
File.rm_rf("_images")
end
def do_thing("--nobuild"), do: false
def do_thing("--upload"), do: true
def do_thing("--burn"), do: true
def do_thing("--deps"), do: fetch_deps
def do_thing(other) do
IO.puts "bad argument: #{other}"
IO.puts help_text
false
end
defp help_text, do:
"""
Builds a farmbot firmware image.
Can be configured by various env vars.
* NERVES_TARGET (default: rpi3) - can be "rpi3", "qemu-arm" right now. More support coming soon.
* NERVES_SYSTEM (optional) - can be used to not use the default system for your NERVES_TARGET
* BOT_IP_ADDR (optional) - the ip address of a running farmbot. This is used in the upload task.
Can also be configured by several command line switches.
* --clean - will clean the environment before building again. (this can take a while)
* --upload - If the build succeeds, upload firmware to IP_ADDRESS
* --deps - force fetch dependencies.
* --nobuild - don't actually build the firmware.
* --burn - burn the image to an sdcard
* --help - display this message.
"""
end
def target(:prod) do
blah = System.get_env("NERVES_TARGET") || "rpi3"
System.put_env("NERVES_TARGET", blah)
blah
end
def target(_), do: "development"
end

View File

@ -1,33 +0,0 @@
#!/bin/bash
# yes. This is in fact a bash script that gets called
# from a mix task, that then in a wild chain of events, executes more mix tasks.
# don'nt you worry about a thing.
CWD=$PWD # this should be from the root of the project
OS_DIR=$CWD/apps/farmbot
CONFIGURATOR_DIR=$CWD/apps/farmbot_configurator
cd $CONFIGURATOR_DIR
if [ ! -d "node_modules" ]; then
echo "need to get configurator deps!"
npm install
if [ $? != 0 ]; then
echo "error building bundle"
exit $?
fi
fi
npm run build
if [ $? != 0 ]; then
echo "error building bundle"
exit $?
fi
cd $OS_DIR
if [ ! -d "deps" ]; then
echo "need to get os deps!"
mix deps.get
fi
mix firmware
exit $?

View File

@ -1,5 +0,0 @@
#!/bin/bash
CWD=$PWD # this should be from the root of the project
OS_DIR=$CWD/apps/farmbot
cd $OS_DIR
mix firmware.burn

View File

@ -1,10 +0,0 @@
#!/bin/bash
# sets up the environment for building the linux part of Farmbot.
CWD=$PWD # this should be from the root of the project
APPS_DIR=$CWD/apps
TARGET_DIR=$APPS_DIR/nerves_system_$NERVES_TARGET
BR_DIR=$CWD/deps/nerves_system_br
$BR_DIR/create-build.sh $TARGET_DIR/nerves_defconfig $APPS_DIR/NERVES_SYSTEM_$NERVES_TARGET
exit 0

View File

@ -1,4 +0,0 @@
#!/bin/bash
echo "uploading to ${BOT_IP_ADDR}"
/usr/bin/curl -T apps/farmbot/_images/rpi3/farmbot.fw http://${BOT_IP_ADDR}:8988/firmware \
-H "Content-Type: application/x-firmware" -H "X-Reboot: true" -#