From bf80c8cc648c91a260b68ae18264386a88f34984 Mon Sep 17 00:00:00 2001
From: Scott Haug <scott.haug@gmail.com>
Date: Wed, 13 Mar 2024 17:13:12 -0700
Subject: [PATCH 1/3] feat: support custom git config

This allows for, among other things, mapping URLs to provide authentication for private repos.
---
 README.md  | 22 ++++++++++++++++++++++
 lib/pip.js | 11 +++++++++++
 test.js    | 26 ++++++++++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/README.md b/README.md
index d9127adb..64f2387f 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,28 @@ custom:
 With `Dockerfile` the path to the Dockerfile that must be in the current folder (or a subfolder).
 Please note the `dockerImage` and the `dockerFile` are mutually exclusive.
 
+To install requirements with custom git settings (e.g., to map private repositories with
+authentication parameters), add the following to your `serverless.yml`:
+
+```yaml
+custom:
+  pythonRequirements:
+    dockerizePip: true
+    dockerGit: true
+```
+
+The `dockerGit` option will mount your `$HOME/.gitconfig` as a volume in the docker container.
+
+In case you want to use a different git configuration, you can specify the path (absolute) to it through `dockerGitConfig` option:
+
+```yaml
+custom:
+  pythonRequirements:
+    dockerizePip: true
+    dockerGit: true
+    dockerGitConfig: /home/.git/config
+```
+
 To install requirements from private git repositories, add the following to your `serverless.yml`:
 
 ```yaml
diff --git a/lib/pip.js b/lib/pip.js
index 40140d36..929e3b6a 100644
--- a/lib/pip.js
+++ b/lib/pip.js
@@ -286,6 +286,17 @@ async function installRequirements(targetFolder, pluginInstance, funcOptions) {
         );
       }
 
+      if (options.dockerGit) {
+        const homePath = require('os').homedir();
+        const gitConfigPath = options.dockerGitConfig || `${homePath}/.gitconfig`;
+
+        // Mount necessary git files to work with private repos
+        dockerCmd.push(
+          '-v',
+          `${gitConfigPath}:/root/.gitconfig:z`
+        );
+      }
+
       // If we want a download cache...
       const dockerDownloadCacheDir = '/var/useDownloadCache';
       if (options.useDownloadCache) {
diff --git a/test.js b/test.js
index b97f3fdc..2b78c862 100644
--- a/test.js
+++ b/test.js
@@ -223,6 +223,32 @@ test(
   { skip: !canUseDocker() || brokenOn('win32') }
 );
 
+test(
+  'dockerGitConfig option correctly resolves docker command',
+  async (t) => {
+    process.chdir('tests/base');
+    const path = npm(['pack', '../..']);
+    npm(['i', path]);
+    const stdout = sls(['package'], {
+      noThrow: true,
+      env: {
+        dockerizePip: true,
+        dockerGit: true,
+        dockerGitConfig: `${__dirname}${sep}tests${sep}base${sep}custom_gitconfig`,
+        dockerImage: 'break the build to log the command',
+      },
+    });
+    t.true(
+      stdout.includes(
+        `-v ${__dirname}${sep}tests${sep}base${sep}custom_gitconfig:/root/.gitconfig:z`
+      ),
+      'docker command properly resolved'
+    );
+    t.end();
+  },
+  { skip: !canUseDocker() || brokenOn('win32') }
+)
+
 test('default pythonBin can package flask with default options', async (t) => {
   process.chdir('tests/base');
   const path = npm(['pack', '../..']);

From 76f7f34b75f93fa581d3ece7d1ec4074477f3aff Mon Sep 17 00:00:00 2001
From: Scott Haug <scott.haug@gmail.com>
Date: Tue, 19 Mar 2024 13:36:01 -0700
Subject: [PATCH 2/3] Prettify

---
 lib/pip.js | 8 +++-----
 test.js    | 2 +-
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/lib/pip.js b/lib/pip.js
index 929e3b6a..b1a238cd 100644
--- a/lib/pip.js
+++ b/lib/pip.js
@@ -288,13 +288,11 @@ async function installRequirements(targetFolder, pluginInstance, funcOptions) {
 
       if (options.dockerGit) {
         const homePath = require('os').homedir();
-        const gitConfigPath = options.dockerGitConfig || `${homePath}/.gitconfig`;
+        const gitConfigPath =
+          options.dockerGitConfig || `${homePath}/.gitconfig`;
 
         // Mount necessary git files to work with private repos
-        dockerCmd.push(
-          '-v',
-          `${gitConfigPath}:/root/.gitconfig:z`
-        );
+        dockerCmd.push('-v', `${gitConfigPath}:/root/.gitconfig:z`);
       }
 
       // If we want a download cache...
diff --git a/test.js b/test.js
index 2b78c862..e2efb935 100644
--- a/test.js
+++ b/test.js
@@ -247,7 +247,7 @@ test(
     t.end();
   },
   { skip: !canUseDocker() || brokenOn('win32') }
-)
+);
 
 test('default pythonBin can package flask with default options', async (t) => {
   process.chdir('tests/base');

From 1f895e8c13ce4a18ce6dc6fbad2dabee2f2b6eca Mon Sep 17 00:00:00 2001
From: Scott Haug <scott.haug@gmail.com>
Date: Wed, 27 Mar 2024 17:25:01 -0700
Subject: [PATCH 3/3] Add missing checks

---
 index.js                  | 3 +++
 tests/base/serverless.yml | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/index.js b/index.js
index ca8b191f..8fb0fea3 100644
--- a/index.js
+++ b/index.js
@@ -44,6 +44,8 @@ class ServerlessPythonRequirements {
         dockerizePip: false,
         dockerSsh: false,
         dockerPrivateKey: null,
+        dockerGit: false,
+        dockerGitOptions: null,
         dockerImage: null,
         dockerFile: null,
         dockerEnv: false,
@@ -86,6 +88,7 @@ class ServerlessPythonRequirements {
     if (
       !options.dockerizePip &&
       (options.dockerSsh ||
+        options.dockerGit ||
         options.dockerImage ||
         options.dockerFile ||
         options.dockerPrivateKey)
diff --git a/tests/base/serverless.yml b/tests/base/serverless.yml
index 87423210..bcee3fcf 100644
--- a/tests/base/serverless.yml
+++ b/tests/base/serverless.yml
@@ -12,6 +12,8 @@ custom:
     dockerizePip: ${env:dockerizePip, self:custom.defaults.dockerizePip}
     dockerSsh: ${env:dockerSsh, self:custom.defaults.dockerSsh}
     dockerPrivateKey: ${env:dockerPrivateKey, self:custom.defaults.dockerPrivateKey}
+    dockerGit: ${env:dockerGit, self:custom.defaults.dockerGit}
+    dockerGitOptions: ${env:dockerGitOptions, self:custom.defaults.dockerGitOptions}
     dockerImage: ${env:dockerImage, self:custom.defaults.dockerImage}
     slim: ${env:slim, self:custom.defaults.slim}
     slimPatterns: ${file(./slimPatterns.yml):slimPatterns, self:custom.defaults.slimPatterns}
@@ -29,6 +31,8 @@ custom:
     dockerizePip: false
     dockerSsh: false
     dockerPrivateKey: ''
+    dockerGit: false
+    dockerGitOptions: ''
     dockerImage: ''
     individually: false
     useStaticCache: true