tex-core add tag
samcarter
When I save a test with l3build, I would like to copy the pdf from the ./build/test folder to another folder. To make sure this only happens when I save a test and not when I check a test or do something else, I though I could try to hack the `save()` function. To do this I copied the function from `l3build-check.lua` to my `build.lua` file:

```lua
#!/usr/bin/env texlua
module = "document"
checkruns    = 2
checkengines = { "pdftex" }

function save(names)
  checkinit()
  local engines = options["engine"] or {stdengine}
  if names == nil then
    print("Arguments are required for the save command")
    return 1
  end
  for _,name in pairs(names) do
    local test_filename, kind = testexists(name)
    if not test_filename then
      print('Test "' .. name .. '" not found')
      return 1
    end
    local test_type = test_types[kind]
    if test_type.expectation and locate({unpackdir, testfiledir}, {name .. test_type.expectation}) then
      print("Saved " .. test_type.test .. " file would override a "
        .. test_type.expectation .. " file of the same name")
      return 1
    end
    for _,engine in pairs(engines) do
      local testengine = engine == stdengine and "" or ("." .. engine)
      local out_file = name .. testengine .. test_type.reference
      local gen_file = name .. "." .. engine .. test_type.generated
      print("Creating and copying " .. out_file)
      runtest(name, engine, false, test_type.test, test_type)
      ren(testdir, gen_file, out_file)
      cp(out_file, testdir, testfiledir)
      if fileexists(unpackdir .. "/" .. test_type.reference) then
        print("Saved " .. test_type.reference
          .. " file overrides unpacked version of the same name")
        return 1
      end
    end
  end
  print("Quack")
  return 0
end
```

In the third to last line I added some dummy output, but unfortunately it seems the modified version of the `save()` function does not get picked up when I run 

```bash
l3build save testname
```

If I make the same changes directly in `l3build-check.lua` the modifications get picked up. 

What am I doing wrong?
Top Answer
Phelype Oleinik
The function `save` is special because it is called by name by the build target (as in `l3build save`), thus it is stored in a list of known targets called `target_list`.  Redefining the function `save` changes what `save` means when you call it, but it does not update the reference to `save` in `target_list`, so it retains the old function.  After changing the `save` function you have to update the `target_list` with:
```lua
function save(names)
  ...
end
target_list["save"].func = save -- Update save in the target_list
```

Here's the build file with that and the line for copying the PDF file added:
```lua
#!/usr/bin/env texlua
module = "document"
checkruns    = 2
checkengines = { "pdftex" }

function save(names)
  checkinit()
  local engines = options["engine"] or {stdengine}
  if names == nil then
    print("Arguments are required for the save command")
    return 1
  end
  for _,name in pairs(names) do
    local test_filename, kind = testexists(name)
    if not test_filename then
      print('Test "' .. name .. '" not found')
      return 1
    end
    local test_type = test_types[kind]
    if test_type.expectation and locate({unpackdir, testfiledir}, {name .. test_type.expectation}) then
      print("Saved " .. test_type.test .. " file would override a "
        .. test_type.expectation .. " file of the same name")
      return 1
    end
    for _,engine in pairs(engines) do
      local testengine = engine == stdengine and "" or ("." .. engine)
      local out_file = name .. testengine .. test_type.reference
      local gen_file = name .. "." .. engine .. test_type.generated
      print("Creating and copying " .. out_file)
      runtest(name, engine, false, test_type.test, test_type)
      ren(testdir, gen_file, out_file)
      cp(out_file, testdir, testfiledir)
      cp(name .. ".pdf", testdir, testfiledir) --      <--- Added to copy the pdf to the test dir
      if fileexists(unpackdir .. "/" .. test_type.reference) then
        print("Saved " .. test_type.reference
          .. " file overrides unpacked version of the same name")
        return 1
      end
    end
  end
  print("Quack!") --      <--- Added for important diagnostic messages :)
  return 0
end
target_list["save"].func = save -- Update save in the target_list
```

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.