Skip to content

Conversation

@cbecker
Copy link

@cbecker cbecker commented Jan 3, 2026

Allows to specify where to save temporary files to. See #144 for more details

Copy link
Member

@achempion achempion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for submitting the PR. I can merge it after these changes

  • use :tmp_dir option name
  • have a test case covering both TMPDIR and :tmp_dir options (search for test "recv_timeout" do in the codebase for a setup example)
  • update documentation for the new option

@cbecker
Copy link
Author

cbecker commented Jan 15, 2026

Thanks. I improved the tests in local_test.ex, and did the other items.

I am not sure what you mean with testing for both cases for tests in store_test.ex, where the recv_timeout tests are, because those tests don't use the temp storage, so nothing fails if, for example, the test storage is set to a path that cannot be written. Do you mean to change a different suite of tests?

Copy link
Member

@achempion achempion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update, here are couple of things that I noticed

  • the testing approach is too complicated
  • documentation can live inside the defmodule Waffle.Definition.Storage module instead of readme

I am not sure what you mean with testing for both cases for tests in store_test.ex

I linked an abstract example that tests a configuration option.

@cbecker cbecker force-pushed the cb/add-temp-dir-config branch from ec8a055 to d31781f Compare January 16, 2026 08:56
@cbecker
Copy link
Author

cbecker commented Jan 16, 2026

Thanks.

  • Ideally, docs belong to Waffle.File, but I added them to Definition.Storage now, removed from README.md
  • Removed the testing approach you said it's too complex
  • Added a test, but I am still not sure it's what you want. Let me know. I still believe having local_storage tests as I did earlier (the first commit) is important, but I'm happy to go for what you think is best.

Copy link
Member

@achempion achempion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good, left couple of comments

tmp_dir: "/path/to/custom/tmp"

Waffle may fail to remove temporary files if the process using them crashes.
Having a periodic cleanup process or using a custom temporary directory is recommended.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we please remove this line (122)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

@doc """
Directory used for temporary files.
"""
def temp_dir() do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: defp tmp_dir()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we keep it public? then I can easily read the exact temp dir from Waffle in my cleanup genserver. (we can read it from the application env, but may be handy to have this public)

Path.join(temp_dir(), file_name)
end

@doc """
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can skip on doc here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


with_mock Waffle.Storage.S3,
put: fn DummyDefinition, _, {%{file_name: "favicon.ico", path: path}, nil} ->
String.starts_with?(path, tmp_dir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will test still pass if key configuration Application.put_env(:waffle, :tmp_dir, tmp_dir) is removed from it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we leave the default env :tmp_dir (nil), then this test fails, because the file will be written to /tmp instead of waffletest/store_tmp

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With which error it fails with? I can't see any asserts here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah no sorry- missed that. added assert here and in the other test where it was neither done

Application.put_env(:waffle, :recv_timeout, 5_000)
end

test "custom tmp_dir used for temp files and succeeds if exists" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do a simpler approach with having a simple unit test for generate_temporary_path/1 function insdie the file_test.exs file (we would need to create it)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, done!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find the file_test.exs in the PR

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forgot to git add, done now

|> Kernel.<>(string_extension)

Path.join(System.tmp_dir(), file_name)
Path.join(temp_dir(), file_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmp_dir()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@cbecker
Copy link
Author

cbecker commented Jan 16, 2026

Thanks for the feedback, ready for another round

Application.put_env(:waffle, :recv_timeout, 5_000)
end

test "custom tmp_dir used for temp files and succeeds if exists" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find the file_test.exs in the PR


with_mock Waffle.Storage.S3,
put: fn DummyDefinition, _, {%{file_name: "favicon.ico", path: path}, nil} ->
String.starts_with?(path, tmp_dir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With which error it fails with? I can't see any asserts here

File.rm_rf!(tmp_dir)
end

test "default tmp_dir used for temp files and succeeds if exists" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can skp on updating the store_test as file_test should be enough for this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me know if you want to remove the store tests. I think it doesn't hurt to have them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to remove them to reduce test complexity

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, reverted back to master

File.mkdir_p("waffletest/uploads")
File.mkdir_p("waffletest/tmp")
System.put_env("TMPDIR", "waffletest/tmp")
Application.put_env(:waffle, :tmp_dir, "waffletest/tmp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to keep the default tmpdir setting

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, reverted

Copy link
Member

@achempion achempion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left some comments, plrease remove the tests from store_test

@@ -0,0 +1,38 @@
defmodule WaffleTest.File do
use ExUnit.Case
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be async: false to not overlap with other tests on global state changes

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, default is false from ExUnit.Case's docs. Anyway specified now explicitly.

    * `:async` - configures tests in this module to run concurrently with
      tests in other modules. Tests in the same module never run concurrently.
      It should be enabled only if tests do not change any global state.
      Defaults to `false`.

describe "generate_temporary_path/1" do
test "uses configured tmp_dir" do
previous = Application.get_env(:waffle, :tmp_dir, :not_set)
custom_tmp = System.tmp_dir() <> "/waffle_test_custom"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this inside the module attribute?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's only used for this test, not in general, so I am not sure it makes sense. I did it anyway.

use ExUnit.Case

describe "generate_temporary_path/1" do
test "uses configured tmp_dir" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, can we add a couple of changes

  • move path into the module attribute
  • use on_exit callback for the cleanup
  • the test flow can be simpler:
    1. on_exit setup
    2. put env
    3. call function and assert on the same line

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok done!

@cbecker cbecker changed the title Add :temp_dir application config setting Add :tmp_dir application config setting Jan 16, 2026
Copy link
Member

@achempion achempion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking great, left a couple of comments

File.rm_rf!(tmp_dir)
end

test "default tmp_dir used for temp files and succeeds if exists" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to remove them to reduce test complexity

def setup do
File.mkdir_p!(@custom_tmpdir)

on_exit fn ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as we need it only inside a single test, it can be written like this

test "uses configured tmp_dir" do
  File.mkdir_p!(@custom_tmpdir)
  
  on_exit fn ->
    Application.delete_env(:waffle, :tmp_dir)
    File.rm_rf(@custom_tmpdir)
  end

  Application.put_env(:waffle, :tmp_dir, @custom_tmpdir)

  assert Waffle.File.generate_temporary_path() |> String.starts_with?(@custom_tmpdir)
end

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. not sure it makes sense to keep the module attribute, as it's only used here now- kept for now, as it's what you wanted earlier. No setup function anymore for the module.

defmodule WaffleTest.File do
use ExUnit.Case, async: false

@custom_tmpdir System.tmp_dir() <> "/waffle_test_custom"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: @custom_tmp_dir

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

assert Waffle.File.generate_temporary_path() |> String.starts_with?(@custom_tmpdir)
end

test "generates path in default tmp_dir when config not set" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "uses system tmp_dir"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Path.join(tmp_dir(), file_name)
end

def tmp_dir() do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please make it private? Any public interface is hard to change once external apps/libraries will start using it

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, done.

@cbecker
Copy link
Author

cbecker commented Jan 16, 2026

Done now, ready for another round.

@cbecker
Copy link
Author

cbecker commented Jan 17, 2026

@achempion I think it's ready, let me know what you think. thanks!

Copy link
Member

@achempion achempion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great, please squash git commits so I can merge keeping the clean git history

assert Waffle.File.generate_temporary_path() |> String.starts_with?(@custom_tmp_dir)
on_exit fn ->
Application.delete_env(:waffle, :tmp_dir)
File.rm_rf(@custom_tmp_dir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: File.rm_rf!/1

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

@achempion
Copy link
Member

please check the CI build message

@cbecker cbecker force-pushed the cb/add-temp-dir-config branch from 8d28548 to f58ce94 Compare January 17, 2026 17:55
@cbecker
Copy link
Author

cbecker commented Jan 17, 2026

all good, should be ok now. I don't know how to make CI run, seems to not happen by default on new commits.

@achempion achempion merged commit 2d32220 into elixir-waffle:master Jan 18, 2026
1 check passed
@cbecker
Copy link
Author

cbecker commented Jan 18, 2026

@achempion thanks! Is it possible to create an Hex release with these changes?

@achempion
Copy link
Member

achempion commented Jan 18, 2026 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants