Repository: netlify/zip-it-and-ship-it
Pull request #595 (2021-07-27 11:34:38)

fix: install Rust build target
**- Summary**

Installs the correct build target for Rust functions as part of the build command.

**- Test plan**

Existing tests updated.

**- A picture of a cute animal (not mandatory but encouraged)**

🦀 

github-actions[bot]: ## ⏱ Benchmark results

*Comparing with 96c833514c1b10081dee2a1c236e05186c2ebe01*

### largeDepsEsbuild: 11.9s
 ⬇️ **10.93% decrease** vs. 96c833514c1b10081dee2a1c236e05186c2ebe01
```
^                                                  13.3s                           13.3s                  
│  12.5s           12.7s                   12.4s    ┌──┐   12.6s           12.6s    ┌──┐   12.4s          
│   ┌──┐            ┌──┐   12.2s            ┌──┐    |  |    ┌──┐    12s     ┌──┐    |  |    ┌──┐   11.9s  
│ ──┼──┼────────────┼──┼────┌──┐────────────┼──┼────┼──┼────┼──┼────┌──┐────┼──┼────┼──┼────┼──┼────┌──┐──
│   |  |   10.6s    |  |    |  |            |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    ┌──┐    |  |    |  |    10s     |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    ┌──┐    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
└───┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴──>
    T-12    T-11    T-10    T-9     T-8     T-7     T-6     T-5     T-4     T-3     T-2     T-1      T    
```
<details>
<summary>Legend</summary>

- T-30 (96c833514c1b10081dee2a1c236e05186c2ebe01): 13.2s
- T-29 (5d48d64bea0d963efa9dbe64925baef24002a9a4): 12.4s
- T-28 (bd7206ea53810a73ea9938f4e34e2826a142ae2d): 14.3s
- T-27 (69fdb7b0f312a6e007e6cedd6a40494772756eef): 11.4s
- T-26 (57a644f24c7bfd2c0ab1e19360465a3301157162): 13.8s
- T-25 (a9a9e610e1324bbcbee604561605dd12c8a7c4c8): 13.2s
- T-24 (8e299a25c7449b440f7a07849d73b8f184a3245c): 12.6s
- T-23 (cebf521a0a5e42ee0244108aa86367f74524f1be): 10.5s
- T-22 (b789589e534a4cc26c6a56636039b9a22f07a2e3): 12.9s
- T-21 (2e25a52b4d23522c64a01c78f7dba16291a085cf): 12.3s
- T-20 (fec9333941c4b8d0a6a648fd755ddecca07fc892): 12.1s
- T-19 (bd61ad00330f73d247dac787734abc9efeaba4b1): 12.7s
- T-18 (9c3d239efb5f53d53ada4c2d92db6f48b7401096): 13.9s
- T-17 (d790873c4cfb82de3f9d5cc64c2ecb45f4c4112f): 10.6s
- T-16 (c18abffd799ee05a0336a34fffd9a1d48e71c550): 10.9s
- T-15 (a0b35e4de9ee40eb9eed4fdd85a16796983fe154): 9.8s
- T-14 (f9084030bf84398023793983490c294b7b8ff483): 14s
- T-13 (b8eb5f8da62d48468c4aff35f2ed65b175bb14c7): 9.6s
- T-12 (cc6070c8f5a0b44163e3167be9b0beab9bf1c644): 12.5s
- T-11 (d1f77ee0caf96a19702d81abd85b8814ed62ab1c): 10.6s
- T-10 (2a11f56404dfdb6d92881751e9a21ed11f432ec8): 12.7s
- T-9 (30ec7f6a4e97007c2f5e0c40b85b196884acd10f): 12.2s
- T-8 (49c33d8209130930cdeed3b953ac874047cba15a): 10s
- T-7 (0bc0ff937f2bfc93d930c78ea4afb7ede53e30c1): 12.4s
- T-6 (69142468b5054449c51186dd64f79ec67ea7899b): 13.3s
- T-5 (d5392a0cb21fa9b712f5dd8c9d4703f6b080afbf): 12.6s
- T-4 (000ffff7ecbceeeb73e4b305859db4a1f8ff1e18): 12s
- T-3 (a36adf0bfcb253ec0271e974752f52a29796476e): 12.6s
- T-2 (01ae53482bc80186659d9a214394315f71135aa5): 13.3s
- T-1 (786deef392e4fa94987bd3667f5def20d1f34e5c): 12.4s
- **T (current commit): 11.9s**</details>
### largeDepsZisi: 53.8s
 ⬇️ **18.19% decrease** vs. 96c833514c1b10081dee2a1c236e05186c2ebe01
```
^                                                 1m 14.3s                                                
│                 1m 8.7s                           ┌──┐                                                  
│                   ┌──┐                            |  |  1m 5.3s         1m 7.1s 1m 8.3s 1m 7.1s         
│ 1m 4.1s           |  |  1m 1.5s          1m 4s    |  |    ┌──┐  1m 3.6s   ┌──┐    ┌──┐    ┌──┐          
│ ──┌──┐────────────┼──┼────┌──┐────────────┌──┐────┼──┼────┼──┼────┌──┐────┼──┼────┼──┼────┼──┼──────────
│   |  |   54.9s    |  |    |  |            |  |    |  |    |  |    |  |    |  |    |  |    |  |          
│   |  |    ┌──┐    |  |    |  |   52.8s    |  |    |  |    |  |    |  |    |  |    |  |    |  |   53.8s  
│   |  |    |  |    |  |    |  |    ┌──┐    |  |    |  |    |  |    |  |    |  |    |  |    |  |    ┌──┐  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
│   |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |  |    |▒▒|  
└───┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴──>
    T-12    T-11    T-10    T-9     T-8     T-7     T-6     T-5     T-4     T-3     T-2     T-1      T    
```
<details>
<summary>Legend</summary>

- T-30 (96c833514c1b10081dee2a1c236e05186c2ebe01): 1m 3.6s
- T-29 (5d48d64bea0d963efa9dbe64925baef24002a9a4): 1m 2.1s
- T-28 (bd7206ea53810a73ea9938f4e34e2826a142ae2d): 1m 11.7s
- T-27 (69fdb7b0f312a6e007e6cedd6a40494772756eef): 54.7s
- T-26 (57a644f24c7bfd2c0ab1e19360465a3301157162): 1m 6.5s
- T-25 (a9a9e610e1324bbcbee604561605dd12c8a7c4c8): 1m 9.5s
- T-24 (8e299a25c7449b440f7a07849d73b8f184a3245c): 1m 3.8s
- T-23 (cebf521a0a5e42ee0244108aa86367f74524f1be): 51.2s
- T-22 (b789589e534a4cc26c6a56636039b9a22f07a2e3): 1m 8.3s
- T-21 (2e25a52b4d23522c64a01c78f7dba16291a085cf): 1m 3.4s
- T-20 (fec9333941c4b8d0a6a648fd755ddecca07fc892): 1m 4.1s
- T-19 (bd61ad00330f73d247dac787734abc9efeaba4b1): 1m 7.9s
- T-18 (9c3d239efb5f53d53ada4c2d92db6f48b7401096): 1m 17.1s
- T-17 (d790873c4cfb82de3f9d5cc64c2ecb45f4c4112f): 54.3s
- T-16 (c18abffd799ee05a0336a34fffd9a1d48e71c550): 58.4s
- T-15 (a0b35e4de9ee40eb9eed4fdd85a16796983fe154): 51.8s
- T-14 (f9084030bf84398023793983490c294b7b8ff483): 1m 15.1s
- T-13 (b8eb5f8da62d48468c4aff35f2ed65b175bb14c7): 51s
- T-12 (cc6070c8f5a0b44163e3167be9b0beab9bf1c644): 1m 4.1s
- T-11 (d1f77ee0caf96a19702d81abd85b8814ed62ab1c): 54.9s
- T-10 (2a11f56404dfdb6d92881751e9a21ed11f432ec8): 1m 8.7s
- T-9 (30ec7f6a4e97007c2f5e0c40b85b196884acd10f): 1m 1.5s
- T-8 (49c33d8209130930cdeed3b953ac874047cba15a): 52.8s
- T-7 (0bc0ff937f2bfc93d930c78ea4afb7ede53e30c1): 1m 4s
- T-6 (69142468b5054449c51186dd64f79ec67ea7899b): 1m 14.3s
- T-5 (d5392a0cb21fa9b712f5dd8c9d4703f6b080afbf): 1m 5.3s
- T-4 (000ffff7ecbceeeb73e4b305859db4a1f8ff1e18): 1m 3.6s
- T-3 (a36adf0bfcb253ec0271e974752f52a29796476e): 1m 7.1s
- T-2 (01ae53482bc80186659d9a214394315f71135aa5): 1m 8.3s
- T-1 (786deef392e4fa94987bd3667f5def20d1f34e5c): 1m 7.1s
- **T (current commit): 53.8s**</details>
<!--delta:benchmark@{}-->

Patch:
diff --git a/src/runtimes/rust/builder.js b/src/runtimes/rust/builder.js
index 92e4c79..a103c42 100644
--- a/src/runtimes/rust/builder.js
+++ b/src/runtimes/rust/builder.js
@@ -13,6 +13,8 @@ const { runCommand } = require('../../utils/shell')
 const { BUILD_TARGET, MANIFEST_NAME } = require('./constants')
 
 const build = async ({ srcDir }) => {
+  await installBuildTarget()
+
   // We compile the binary to a temporary directory so that we don't pollute
   // the user's functions directory.
   const { path: targetDirectory } = await tmp.dir()
@@ -64,4 +66,17 @@ const checkRustToolchain = async () => {
   }
 }
 
+let buildTargetInstallation
+
+// Installs the build target defined in `BUILD_TARGET`. The Promise is saved to
+// `buildTargetInstallation` so that we run the command just once for multiple
+// Rust functions.
+const installBuildTarget = () => {
+  if (buildTargetInstallation === undefined) {
+    buildTargetInstallation = runCommand('rustup', ['target', 'add', BUILD_TARGET])
+  }
+
+  return buildTargetInstallation
+}
+
 module.exports = { build }


Test patch:
diff --git a/tests/main.js b/tests/main.js
index 4091e95..f069468 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -1662,12 +1662,16 @@ test.serial(
 
 test.serial('Builds Rust functions from source if the `buildRustSource` feature flag is enabled', async (t) => {
   shellUtilsStub.callsFake(async (...args) => {
-    const directory = join(args[2].env.CARGO_TARGET_DIR, args[1][2], 'release')
-    const binaryPath = join(directory, 'hello')
+    const [rootCommand] = args
 
-    await makeDir(directory)
+    if (rootCommand === 'cargo') {
+      const directory = join(args[2].env.CARGO_TARGET_DIR, args[1][2], 'release')
+      const binaryPath = join(directory, 'hello')
 
-    return pWriteFile(binaryPath, '')
+      await makeDir(directory)
+
+      return pWriteFile(binaryPath, '')
+    }
   })
 
   const fixtureName = 'rust-source'
@@ -1679,15 +1683,21 @@ test.serial('Builds Rust functions from source if the `buildRustSource` feature
     },
   })
 
-  t.is(shellUtilsStub.callCount, 1)
+  t.is(shellUtilsStub.callCount, 2)
 
   const { args: call1 } = shellUtilsStub.getCall(0)
+  const { args: call2 } = shellUtilsStub.getCall(1)
 
-  t.is(call1[0], 'cargo')
-  t.is(call1[1][0], 'build')
-  t.is(call1[1][1], '--target')
+  t.is(call1[0], 'rustup')
+  t.is(call1[1][0], 'target')
+  t.is(call1[1][1], 'add')
   t.is(call1[1][2], 'x86_64-unknown-linux-musl')
 
+  t.is(call2[0], 'cargo')
+  t.is(call2[1][0], 'build')
+  t.is(call2[1][1], '--target')
+  t.is(call2[1][2], 'x86_64-unknown-linux-musl')
+
   t.is(files[0].mainFile, join(FIXTURES_DIR, fixtureName, 'rust-func-1', 'src', 'main.rs'))
   t.is(files[0].name, 'rust-func-1')
   t.is(files[0].runtime, 'rs')