Truffle: Truffle compiler option 'contracts_build_directory' inconsistent behavior

Created on 21 Mar 2018  ·  14Comments  ·  Source: trufflesuite/truffle

Truffle compiler option contracts_build_directory is described here.

I'm having trouble with Truffle's inconsistent behavior on that configuration parameter.

I'm setting it as follows:

contracts_build_directory: "../../artifacts"

When I execute truffle compile, all artifacts are created in a folder named "artifacts" which is located two levels above the project's root directory.

When I execute truffle migrate --network=development, I get the following error message:

Running migration: 1_initial_migration.js
fs.js:904
  return binding.readdir(pathModule._makeLong(path), options.encoding);
                 ^

Error: ENOENT: no such file or directory, scandir '<see_below>\artifacts'

Where <see_below> is a full path which ends only one level above the project's root directory.

I can therefore resolve this problem as follows:

  1. Run truffle compile
  2. Change contracts_build_directory from "../../artifacts" to "../../../artifacts"
  3. Run truffle migrate --network=development

This solution is inappropriate of course.

My project directory structure is as follows:

project folder:
    contracts folder:
        sol files
    migrations folder:
        1_initial_migration.js file
        2_deploy_contracts.js file
    test folder:
        js files
    truffle-config.js file

My truffle configuration (in truffle-config.js) is as follows:

// See <http://truffleframework.com/docs/advanced/configuration>
module.exports = {
    contracts_build_directory: "../../artifacts",
    networks: {
        development: {
            host:       "127.0.0.1",
            network_id: "*",
            port:       8545,
            gas:        4712388,      // Gas limit used for deploys
            gasPrice:   100000000000, // Gas price used for deploys
        },
    },
    mocha: {
        useColors: true,
        bail:      true,   // Abort after first test failure
        reporter:  "list", // See <https://mochajs.org/#reporters>
    },
    solc: {
        optimizer: {
            enabled: true,
            runs:    5000000,
        },
    },
};

To my understanding, the problem stems from the fact that truffle migrate "steps into" the migrations folder and runs from there (hence an additional ..\ is required in the value of the contracts_build_directory parameter).

UPDATE:

If I delete all the artifacts, and then run truffle migrate without preceding it with truffle compile (i.e., letting truffle migrate do the compilation), then it works only when the contracts_build_directory option is NOT specified. Any other way (even setting it to the default value ./build/contracts or to the "trivial" value ./) - the migration fails.

So in short, there seem to be a "collision" between truffle migrate and contracts_build_directory.

Migrations

Most helpful comment

I got problem at return binding.readdir(pathModule.toNamespacedPath(path), options.encoding) instead. I'm on Linux but toNamespacedPath seems to only work on Windows, might this be a problem with OS detection? I'm using Arch.

I found a workaround:

var path = require('path');
module.exports = {
    contracts_build_directory: path.join(__dirname, /* your output dir */)
}

All 14 comments

@barakman Thanks for this report. Will investigate.

I got problem at return binding.readdir(pathModule.toNamespacedPath(path), options.encoding) instead. I'm on Linux but toNamespacedPath seems to only work on Windows, might this be a problem with OS detection? I'm using Arch.

I found a workaround:

var path = require('path');
module.exports = {
    contracts_build_directory: path.join(__dirname, /* your output dir */)
}

I'm having this issue as well, is there an official solution for it or just this workaround for now?

@RobertoC27 There's no official solution - out of curiosity which OS are you using?

I’m on windows 10, but I was working on a VM with Ubuntu 16.04 and issue was there.

Enviado desde mi iPhone

El jun. 4, 2018, a la(s) 9:51 a. m., c-g-e-w-e-k-e-> <[email protected]notifications@github.com> escribió:

@RobertoC27https://github.com/RobertoC27 There's no official solution - out of curiosity which OS are you using?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/trufflesuite/truffle/issues/862#issuecomment-394404937, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AH4ReZ2a1LKmvlmuE8fCX0_ddyuuqkpfks5t5VeXgaJpZM4S1VR4.

Just to make it clear, I’m working on Windows 10 and the issue can be reproduced consistently, but when working with a VM with Ubuntu 16.04 issue was present as well. In Ubuntu the problem was that the migrations.sol file could not be found. Solved it by changing the line that was something like “require(./migrations.sol)” and changed it to
“Require(migrations)”.

El jun. 4, 2018, a la(s) 9:51 a. m., c-g-e-w-e-k-e-> <[email protected]notifications@github.com> escribió:

@RobertoC27https://github.com/RobertoC27 There's no official solution - out of curiosity which OS are you using?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/trufflesuite/truffle/issues/862#issuecomment-394404937, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AH4ReZ2a1LKmvlmuE8fCX0_ddyuuqkpfks5t5VeXgaJpZM4S1VR4.

Good afternoon everyone,

Is there any advance on this issue? I'm facing exactly the same and I'm running out of options, I really need to change the directory of artifacts. It's the same issue:

  1. Change contracts_build_directory
  2. Run truffle compile
  3. Run truffle migrate --network=development
  4. It fails with the following stack trace:

Using network 'development'.

Running migration: 1_initial_migration.js
fs.js:119
throw err;
^

Error: ENOENT: no such file or directory, scandir './src/contracts/'
at Object.readdirSync (fs.js:759:3)
at FS.getContractName (/Users/madog/.nvm/versions/node/v10.7.0/lib/node_modules/truffle/build/cli.bundled.js:101719:22)
at FS.require (/Users/madog/.nvm/versions/node/v10.7.0/lib/node_modules/truffle/build/cli.bundled.js:101698:28)
at Resolver.require (/Users/madog/.nvm/versions/node/v10.7.0/lib/node_modules/truffle/build/cli.bundled.js:59966:25)
at Object.require (/Users/madog/.nvm/versions/node/v10.7.0/lib/node_modules/truffle/build/cli.bundled.js:69602:36)
at ResolverIntercept.require (/Users/madog/.nvm/versions/node/v10.7.0/lib/node_modules/truffle/build/cli.bundled.js:197047:32)
at /Users/madog/Documents/repos/dev/cycleapp/migrations/1_initial_migration.js:1:28
at Script.runInContext (vm.js:102:20)
at Script.runInNewContext (vm.js:108:17)
at /Users/madog/.nvm/versions/node/v10.7.0/lib/node_modules/truffle/build/cli.bundled.js:101639:14
at FSReqWrap.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:53:3)

Thanks for any advice!

@nicosquare you can check my workaround above

Thanks for raising this issue @barakman !

We've finally merged a fix for this into truffle@next via #1331.

Can you reopen this issue? For the users of Truffle version 4 the bug is still there.

contracts_build_directory: path.join(__dirname

I got problem at return binding.readdir(pathModule.toNamespacedPath(path), options.encoding) instead. I'm on Linux but toNamespacedPath seems to only work on Windows, might this be a problem with OS detection? I'm using Arch.

I found a workaround:

var path = require('path');
module.exports = {
    contracts_build_directory: path.join(__dirname, /* your output dir */)
}

Where do you put this snipped to make it work?

@alexiskattan into your truffle-config.js

@cgewecke:

Almost two and a half years later, the contracts_build_directory compiler option is still not handled properly on Windows.

I'm on Truffle 5.1.36 now, and truffle test always ends up converting my contracts build directory (where Truffle creates all JSON artifacts) from './<my_project_folder>/build/contracts' (which is also the default BTW) to some temporary Windows directory, for example, 'C:\\Users\\LOCALC~1\\AppData\\Local\\Temp\\test--12372-H5iUC1JGbek1' (the suffix changes on every execution).

This, in turn, causes a full rebuild upon every execution (i.e., truffle compile --all is always executed automatically before the actual test begins).

I have added some printouts in your code (file cli.bundled.js), and found out that the problem my be stemming from when function prepareConfigAndRunTests is called with this temporary directory.

I believe that the problem might be here:

      Environment.detect(config)
        .then(() => copyArtifactsToTempDir(config))
        .then(({ config, temporaryDirectory }) => {
          return prepareConfigAndRunTests({
            config,
            files,
            temporaryDirectory
          });
        })

And since I know that this problem does not occur on neither Linux nor MacOS, I believe that it possibly stems from Environment.detect.

What I don't get is, when printing all Truffle configurable directories (contracts_directory, build_directory, test_directory, contracts_build_directory, etc) in your code, why the only one which is replaced with a temporary directory is contracts_build_directory.

Any help would be very much appreciated, as I am currently left to wait on compilation before every test.

Thanks

@CruzMolina:

Any chance to get some help with that (see previous message)?

Was this page helpful?
0 / 5 - 0 ratings