From dbb64ac1d11fcab72e6fdc427c82d553fab565dc Mon Sep 17 00:00:00 2001
From: Hideki Igarashi <hideki.develop@gmail.com>
Date: Thu, 2 Dec 2021 00:44:59 +0900
Subject: [PATCH] Add support for asdf format as Node.js version file

---
 .github/workflows/versions.yml |  3 ++-
 __tests__/data/.tool-versions  |  1 +
 __tests__/installer.test.ts    | 20 +++++++++++---------
 action.yml                     |  2 +-
 dist/setup/index.js            | 14 +++++++++-----
 docs/advanced-usage.md         |  2 +-
 src/installer.ts               | 12 ++++++++----
 7 files changed, 33 insertions(+), 21 deletions(-)
 create mode 100644 __tests__/data/.tool-versions

diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml
index 3d8067bc9..926945ca1 100644
--- a/.github/workflows/versions.yml
+++ b/.github/workflows/versions.yml
@@ -84,12 +84,13 @@ jobs:
       fail-fast: false
       matrix:
         os: [ubuntu-latest, windows-latest, macos-latest]
+        node-version-file: [.nvmrc, .tool-versions]
     steps:
       - uses: actions/checkout@v3
       - name: Setup node from node version file
         uses: ./
         with:
-          node-version-file: '__tests__/data/.nvmrc'
+          node-version-file: '__tests__/data/${{ matrix.node-version-file }}'
       - name: Verify node
         run: __tests__/verify-node.sh 14
 
diff --git a/__tests__/data/.tool-versions b/__tests__/data/.tool-versions
new file mode 100644
index 000000000..317343f30
--- /dev/null
+++ b/__tests__/data/.tool-versions
@@ -0,0 +1 @@
+nodejs 14.0.0
diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts
index 68767c025..f480947f4 100644
--- a/__tests__/installer.test.ts
+++ b/__tests__/installer.test.ts
@@ -946,15 +946,17 @@ describe('setup-node', () => {
 describe('helper methods', () => {
   describe('parseNodeVersionFile', () => {
     each`
-      contents            | expected
-      ${'12'}             | ${'12'}
-      ${'12.3'}           | ${'12.3'}
-      ${'12.3.4'}         | ${'12.3.4'}
-      ${'v12.3.4'}        | ${'12.3.4'}
-      ${'lts/erbium'}     | ${'lts/erbium'}
-      ${'lts/*'}          | ${'lts/*'}
-      ${''}               | ${''}
-      ${'unknown format'} | ${'unknown format'}
+      contents                                     | expected
+      ${'12'}                                      | ${'12'}
+      ${'12.3'}                                    | ${'12.3'}
+      ${'12.3.4'}                                  | ${'12.3.4'}
+      ${'v12.3.4'}                                 | ${'12.3.4'}
+      ${'lts/erbium'}                              | ${'lts/erbium'}
+      ${'lts/*'}                                   | ${'lts/*'}
+      ${'nodejs 12.3.4'}                           | ${'12.3.4'}
+      ${'ruby 2.3.4\nnodejs 12.3.4\npython 3.4.5'} | ${'12.3.4'}
+      ${''}                                        | ${''}
+      ${'unknown format'}                          | ${'unknown format'}
     `.it('parses "$contents"', ({contents, expected}) => {
       expect(im.parseNodeVersionFile(contents)).toBe(expected);
     });
diff --git a/action.yml b/action.yml
index 7bed73dc1..b4838e83b 100644
--- a/action.yml
+++ b/action.yml
@@ -8,7 +8,7 @@ inputs:
   node-version:
     description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0.'
   node-version-file:
-    description: 'File containing the version Spec of the version to use.  Examples: .nvmrc, .node-version.'
+    description: 'File containing the version Spec of the version to use.  Examples: .nvmrc, .node-version, .tool-versions.'
   architecture:
     description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
   check-latest:
diff --git a/dist/setup/index.js b/dist/setup/index.js
index fcafff7cd..21712535f 100644
--- a/dist/setup/index.js
+++ b/dist/setup/index.js
@@ -70963,11 +70963,15 @@ function translateArchToDistUrl(arch) {
     }
 }
 function parseNodeVersionFile(contents) {
-    let nodeVersion = contents.trim();
-    if (/^v\d/.test(nodeVersion)) {
-        nodeVersion = nodeVersion.substring(1);
-    }
-    return nodeVersion;
+    var _a;
+    const found = contents.match(/^(?:nodejs\s+)?v?(?<version>[^\s]+)$/m);
+    const nodeVersion = (_a = found === null || found === void 0 ? void 0 : found.groups) === null || _a === void 0 ? void 0 : _a.version;
+    if (nodeVersion) {
+        return nodeVersion;
+    }
+    // In the case of an unknown format,
+    // return as is and evaluate the version separately.
+    return contents.trim();
 }
 exports.parseNodeVersionFile = parseNodeVersionFile;
 function isLatestSyntax(versionSpec) {
diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md
index 36c1ec8b3..cc068b3ff 100644
--- a/docs/advanced-usage.md
+++ b/docs/advanced-usage.md
@@ -56,7 +56,7 @@ steps:
 
 ## Node version file
 
-The `node-version-file` input accepts a path to a file containing the version of Node.js to be used by a project, for example `.nvmrc` or `.node-version`. If both the `node-version` and the `node-version-file` inputs are provided then the `node-version` input is used.
+The `node-version-file` input accepts a path to a file containing the version of Node.js to be used by a project, for example `.nvmrc`, `.node-version` or `.tool-versions`. If both the `node-version` and the `node-version-file` inputs are provided then the `node-version` input is used.
 See [supported version syntax](https://github.com/actions/setup-node#supported-version-syntax)
 > The action will search for the node version file relative to the repository root.
 
diff --git a/src/installer.ts b/src/installer.ts
index cd4619ea0..14429f475 100644
--- a/src/installer.ts
+++ b/src/installer.ts
@@ -487,12 +487,16 @@ function translateArchToDistUrl(arch: string): string {
 }
 
 export function parseNodeVersionFile(contents: string): string {
-  let nodeVersion = contents.trim();
+  const found = contents.match(/^(?:nodejs\s+)?v?(?<version>[^\s]+)$/m);
+  const nodeVersion = found?.groups?.version;
 
-  if (/^v\d/.test(nodeVersion)) {
-    nodeVersion = nodeVersion.substring(1);
+  if (nodeVersion) {
+    return nodeVersion;
   }
-  return nodeVersion;
+
+  // In the case of an unknown format,
+  // return as is and evaluate the version separately.
+  return contents.trim();
 }
 
 function isLatestSyntax(versionSpec): boolean {