@@ -26,43 +26,47 @@ defmodule GitFoil.Helpers.FileEncryption do
2626 def add_files_with_progress ( files , total , opts \\ [ ] ) do
2727 repository = Keyword . get ( opts , :repository )
2828 terminal = Keyword . get ( opts , :terminal , Terminal )
29+ { password_env , cleanup_password_env } = build_password_env ( opts )
2930
3031 show_progress? = total > 0
3132
3233 if show_progress? do
3334 IO . write ( " " )
3435 end
3536
36- files
37- |> Enum . with_index ( 1 )
38- |> Enum . reduce_while ( :ok , fn { file , index } , _acc ->
39- if show_progress? do
40- progress_bar = terminal . progress_bar ( index , total )
41- IO . write ( "\r \e [K #{ progress_bar } #{ index } /#{ total } files" )
42- end
43-
44- # Add the file (triggers clean filter for encryption)
45- result = if repository do
46- # Use injected repository adapter (for testing)
47- repository . add_file ( file )
48- else
49- # Direct git call
50- case System . cmd ( "git" , [ "add" , file ] , stderr_to_stdout: true ) do
51- { _ , 0 } -> :ok
52- { error , _ } -> { :error , String . trim ( error ) }
37+ result =
38+ files
39+ |> Enum . with_index ( 1 )
40+ |> Enum . reduce_while ( :ok , fn { file , index } , _acc ->
41+ if show_progress? do
42+ progress_bar = terminal . progress_bar ( index , total )
43+ IO . write ( "\r \e [K #{ progress_bar } #{ index } /#{ total } files" )
5344 end
54- end
5545
56- case result do
57- :ok ->
58- { :cont , :ok }
46+ # Add the file (triggers clean filter for encryption)
47+ result =
48+ if repository do
49+ repository . add_file ( file )
50+ else
51+ case System . cmd ( "git" , [ "add" , file ] , env: password_env , stderr_to_stdout: true ) do
52+ { _ , 0 } -> :ok
53+ { error , _ } -> { :error , String . trim ( error ) }
54+ end
55+ end
56+
57+ case result do
58+ :ok ->
59+ { :cont , :ok }
60+
61+ { :error , reason } ->
62+ IO . write ( "\n " )
63+ { :halt , { :error , "Failed to encrypt #{ file } : #{ reason } " } }
64+ end
65+ end )
5966
60- { :error , reason } ->
61- IO . write ( "\n " )
62- { :halt , { :error , "Failed to encrypt #{ file } : #{ reason } " } }
63- end
64- end )
65- |> case do
67+ cleanup_password_env . ( )
68+
69+ case result do
6670 :ok ->
6771 if show_progress? do
6872 IO . write ( "\n " )
@@ -80,4 +84,42 @@ defmodule GitFoil.Helpers.FileEncryption do
8084 error
8185 end
8286 end
87+
88+ defp build_password_env ( opts ) do
89+ case Keyword . get ( opts , :password_value ) do
90+ password when is_binary ( password ) ->
91+ path = Path . join ( System . tmp_dir! ( ) , "gitfoil-pass-" <> random_suffix ( ) )
92+
93+ File . write! ( path , password <> "\n " <> password <> "\n " )
94+
95+ case File . chmod ( path , 0o600 ) do
96+ :ok -> :ok
97+ { :error , _ } -> :ok
98+ end
99+
100+ previous = System . get_env ( "GIT_FOIL_TTY" )
101+ System . put_env ( "GIT_FOIL_TTY" , path )
102+
103+ env = [ { "GIT_FOIL_TTY" , path } ]
104+
105+ cleanup = fn ->
106+ case previous do
107+ nil -> System . delete_env ( "GIT_FOIL_TTY" )
108+ value -> System . put_env ( "GIT_FOIL_TTY" , value )
109+ end
110+
111+ File . rm_rf ( path )
112+ end
113+ { env , cleanup }
114+
115+ _ ->
116+ { [ ] , fn -> :ok end }
117+ end
118+ end
119+
120+ defp random_suffix do
121+ 12
122+ |> :crypto . strong_rand_bytes ( )
123+ |> Base . url_encode64 ( padding: false )
124+ end
83125end
0 commit comments