Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8328169
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T01:21:13+00:00 2026-06-09T01:21:13+00:00

I have a multi-project setup for a game. There is a very specific sub

  • 0

I have a multi-project setup for a game. There is a very specific sub project called ‘resources’ that only contains files like images, sounds and texfiles to be packed into a jar.

I have a custom task that processes images and packs them. Inside ‘src/main’ I’m using a folder ‘preprocess’ where images should go and an ‘unmanaged’ folder where everything else goes. By running my task all images in ‘preprocess’ gets packed and output to ‘resources’ and everything in ‘unmanaged’ is copied as is.

val texturePacker = TaskKey[Unit]("texture-packer", "Runs libgdx's Texture Packer")

val texturePackerTask = texturePacker := {
  println("Packaging textures...")
  val inputDir = file("resources/src/main/preprocess")
  val outputDir = file("resources/src/main/resources")

  val folders = inputDir.asFile.listFiles filter (_.isDirectory)

  println("Sub-Folders:" + folders.mkString(", "))

  // Run Texture Packer
  for (subfolder <- folders) {
    println("Building assets for:" + subfolder)
    val args = Array(subfolder.toString, outputDir.toString, subfolder.getName)
    com.badlogic.gdx.tools.imagepacker.TexturePacker2.main(args)
  }

  // Copy unmanaged resources
  IO.copyDirectory(file("resources/src/main/unmanaged"), file("resources/src/main/resources"))
}

And then inside the settings the ‘resources’ project:

...
packageBin in Compile <<= packageBin in Compile dependsOn(texturePacker)
...

The other sub projects have a dependency on packageBin associated with their run. That way whenever I run the project I get the most up to date state of resources. I don’t want it to be on demand. The problem is that it takes a long time to process for every run. I know SBT supports caching SBT FAQ but I don’t understand how to adapt it to my task.

How can I make my custom task avoid redoing the work if the files in a subfolder from the folders list were not modified?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T01:21:15+00:00Added an answer on June 9, 2026 at 1:21 am

    Solution

    Here is a solution that might suite you. However, I don’t fully understand how FileFunction.cached works (more information after the code), so this is probably not the best possible solution:

    val testCache = TaskKey[Unit]("test-cache", "Test SBT's cache")
    
    val testCacheTask = testCache := {
      println("Testing cache ...")
    
      val inputDir = file("test/src")   /* Take direct subdirectories from here */
      val outputDir = file("test/dest") /* Create archives here */
      val cacheDir = file("test/cache") /* Store cache information here */
    
      /* Get all direct subdirectories of inputDir */
      val folders = inputDir.asFile.listFiles.filter{_.isDirectory}
    
      folders.foreach{folder =>
        /* Get all files in the folder (not recursively) */
        val files = folder.listFiles.toSet
    
        /* Wrap actual function in a function that provides basic caching
         * functionalities.
         */
        val cachedFun =
          FileFunction.cached(cacheDir / folder.name,
                              FilesInfo.lastModified, /* inStyle */
                              FilesInfo.exists)       /* outStyle */
                             {(inFiles: Set[File]) =>
    
            createJarFromFolder(folder,
                                inFiles,
                                outputDir / (folder.name + ".jar"))
          }
    
        /* Call wrapped function with files in the current folder */
        cachedFun(files)
      }
    }
    
    /* Creates a JAR archive with all files (this time recursively) in
     * the given folder.
     */
    val createJarFromFolder = (folder: File, inFiles: Set[File], outJar: File) => {
      println("At least one of the %d files in %s have changed. Creating %s."
              .format(inFiles.size, folder, outJar))
    
      /* Replace this by your actual operation */
      val cmdSeq = Seq("jar", "cf", outJar.toString, "-C" , folder + "/", ".")
      println("cmdSeq = " + cmdSeq)
      println("jar: " + cmdSeq.!!)
    
      Set(outJar)
    }
    

    Notes

    • My understanding of cached is, that it checks the inFiles for modifications, and that it invokes the actual operation if one of the files in the set changed. The exact meaning of changed is determined by the inStyle argument to cached.

    • It would be nice to directly pass a directory to cached, such that the actual operation is performed if anything in that directory changes. However, I doubt that it is currently possible.

    • I don’t quite get what the behaviour with respect to the set of files returned by the actual operation is (here:Set(outJar)). I assume that the outStyle argument to cached is related to this, and I expected createJarFromFolder to be called whenever the JAR does not exist (regardless of changes to the input files), but that doesn’t seem to be the case. That is, if you delete a JAR file but not change one of the files in the corresponding directory, the JAR will not be recreated.

    • The code is somewhat dodgy, because it only considers the files that are at the top of a particular folder when it comes to deciding if changes occurred in that folder. You probably want to make that recursive.

    Epilogue

    I’d love to see a better way of using SBT’s caching feature. Should you get more information, e.g., from the mailing list, please post them here.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a multi-module project. I thought I can compile only a single module
We have a multi-module maven project that uses a profile that defines a buildnumber-maven-plugin
I have a project using ASIHTTP to multi download files from a site when
We have a multi-module project documented with the (excellent) Sphinx. Our setup is not
(Re-written for clarity) I have a multi-project solution that I am looking to convert
I have a multi-module maven project with an installer sub-project. The installer will be
I have a multi-module Maven project that is a Java web application. I am
I'm working on a multi-project, and right now I have a structure that resembles
I've written a multi-project .vstemplate file, which works alright, except that the projects have
I'm new to Maven. I have a multi-module maven 2 project that has the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.