11defmodule Mix.Tasks.Membrane.Demo do
22 @ shortdoc "Generate Membrane demos and examples"
33 @ moduledoc """
4- Generate Membrane demos and examples
5-
6- $ mix membrane.demo [-a] [-l] demos ...
4+ Generate Membrane demos and examples. Requires `git` installed.
75
6+ $ mix membrane.demo [-a] [-l] [-d <repo_dir>] <demos> ...
87
8+ ## Options
9+ * `-l, --list` - List all demos available and their brief descriptions.
10+ * `-a, --all` - Pull the repository with all demos.
11+ * `-d, --directory` - Directory where the demos should be placed in.
912 """
13+ use Mix.Task
14+
15+ @ switches [
16+ list: :boolean ,
17+ all: :boolean ,
18+ directory: :string
19+ ]
20+
21+ @ aliases [
22+ l: :list ,
23+ a: :all ,
24+ d: :directory
25+ ]
26+
27+ @ demos_potential_locations [ "." , "livebooks" ]
1028
1129 @ demos_readme_url "https://raw.githubusercontent.com/membraneframework/membrane_demo/refs/heads/master/README.md"
12- use Mix.Task
30+ @ demos_clone_url "https://github.com/membraneframework/membrane_demo.git"
1331
1432 @ impl true
1533 def run ( [ ] ) do
1634 Mix.Tasks.Help . run ( [ "membrane.demo" ] )
1735 end
1836
1937 def run ( argv ) do
20- { :ok , _ } = Application . ensure_all_started ( :req )
38+ { opts , demos_names } = OptionParser . parse! ( argv , aliases: @ aliases , switches: @ switches )
39+
40+ if opts [ :list ] do
41+ list_available_demos ( )
42+ end
43+
44+ repo_dir = Path . join ( Path . expand ( opts [ :directory ] || "." ) , "membrane_demo" )
45+
46+ cond do
47+ opts [ :all ] -> copy_all_demos ( repo_dir )
48+ demos_names != [ ] -> copy_specific_demos ( repo_dir , demos_names )
49+ true -> :ok
50+ end
51+ end
52+
53+ defp list_available_demos ( ) do
54+ { :ok , _apps } = Application . ensure_all_started ( :req )
2155 response = Req . get! ( @ demos_readme_url )
2256
2357 demos_info =
@@ -43,7 +77,39 @@ defmodule Mix.Tasks.Membrane.Demo do
4377 dots_line = String . duplicate ( "." , max_name_length - String . length ( name ) + 3 )
4478 Mix . shell ( ) . info ( " | #{ name } #{ dots_line } | #{ description } " )
4579 end )
80+ end
81+
82+ defp copy_all_demos ( repo_dir ) do
83+ System . cmd ( "git" , [ "clone" , "-q" , "--depth" , "1" , @ demos_clone_url , repo_dir ] )
84+ end
85+
86+ defp copy_specific_demos ( repo_dir , demos_names ) do
87+ System . cmd ( "git" , [ "clone" , "-q" , "--depth" , "1" , "-n" , @ demos_clone_url , repo_dir ] )
88+
89+ File . cd! ( repo_dir )
90+
91+ Enum . each ( demos_names , fn demo_name ->
92+ if copy_demo ( demo_name ) == :error do
93+ Mix . shell ( ) . error (
94+ "No demo named #{ demo_name } , run this task with -l to list all available demos"
95+ )
96+ end
97+ end )
98+
99+ File . rm_rf! ( repo_dir )
100+ end
46101
47- # |> Enum.each(&Mix.shell().info("#{&1["package"]} - #{&1["description"]}"))
102+ defp copy_demo ( demo_name ) do
103+ Enum . reduce_while ( @ demos_potential_locations , :error , fn demo_dir , _status ->
104+ demo_path = Path . join ( demo_dir , demo_name )
105+
106+ System . cmd ( "git" , [ "sparse-checkout" , "set" , demo_path ] )
107+ System . cmd ( "git" , [ "checkout" ] )
108+
109+ case File . cp_r ( demo_path , Path . join ( ".." , Path . basename ( demo_path ) ) ) do
110+ { :ok , _files } -> { :halt , :ok }
111+ { :error , :enoent , _dir } -> { :cont , :error }
112+ end
113+ end )
48114 end
49115end
0 commit comments