fal 1.2.0__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fal might be problematic. Click here for more details.

Files changed (150) hide show
  1. {fal-1.2.0 → fal-1.2.1}/PKG-INFO +1 -1
  2. {fal-1.2.0 → fal-1.2.1}/fal.egg-info/PKG-INFO +1 -1
  3. {fal-1.2.0 → fal-1.2.1}/src/fal/_fal_version.py +2 -2
  4. {fal-1.2.0 → fal-1.2.1}/src/fal/logging/isolate.py +20 -0
  5. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/utils/download_utils.py +48 -39
  6. {fal-1.2.0 → fal-1.2.1}/.gitignore +0 -0
  7. {fal-1.2.0 → fal-1.2.1}/README.md +0 -0
  8. {fal-1.2.0 → fal-1.2.1}/fal.egg-info/SOURCES.txt +0 -0
  9. {fal-1.2.0 → fal-1.2.1}/fal.egg-info/dependency_links.txt +0 -0
  10. {fal-1.2.0 → fal-1.2.1}/fal.egg-info/entry_points.txt +0 -0
  11. {fal-1.2.0 → fal-1.2.1}/fal.egg-info/requires.txt +0 -0
  12. {fal-1.2.0 → fal-1.2.1}/fal.egg-info/top_level.txt +0 -0
  13. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/README.md +0 -0
  14. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  15. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  16. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  17. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  18. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  19. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  20. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  21. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  22. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  23. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  24. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  25. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  26. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  27. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  28. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  29. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  30. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  31. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  32. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  33. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  34. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  35. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  36. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  37. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  38. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  39. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  40. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  41. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  42. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  43. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  44. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  45. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  46. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  47. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  48. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  49. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  50. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  51. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  52. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  53. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  54. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  55. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  56. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  57. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  58. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  59. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  60. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  61. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  62. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  63. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  64. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  65. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  66. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  67. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  68. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  69. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  70. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  71. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  72. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  73. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  74. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  75. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  76. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  77. {fal-1.2.0 → fal-1.2.1}/openapi-fal-rest/pyproject.toml +0 -0
  78. {fal-1.2.0 → fal-1.2.1}/openapi_rest.config.yaml +0 -0
  79. {fal-1.2.0 → fal-1.2.1}/pyproject.toml +0 -0
  80. {fal-1.2.0 → fal-1.2.1}/setup.cfg +0 -0
  81. {fal-1.2.0 → fal-1.2.1}/src/fal/__init__.py +0 -0
  82. {fal-1.2.0 → fal-1.2.1}/src/fal/__main__.py +0 -0
  83. {fal-1.2.0 → fal-1.2.1}/src/fal/_serialization.py +0 -0
  84. {fal-1.2.0 → fal-1.2.1}/src/fal/_version.py +0 -0
  85. {fal-1.2.0 → fal-1.2.1}/src/fal/api.py +0 -0
  86. {fal-1.2.0 → fal-1.2.1}/src/fal/app.py +0 -0
  87. {fal-1.2.0 → fal-1.2.1}/src/fal/apps.py +0 -0
  88. {fal-1.2.0 → fal-1.2.1}/src/fal/auth/__init__.py +0 -0
  89. {fal-1.2.0 → fal-1.2.1}/src/fal/auth/auth0.py +0 -0
  90. {fal-1.2.0 → fal-1.2.1}/src/fal/auth/local.py +0 -0
  91. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/__init__.py +0 -0
  92. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/apps.py +0 -0
  93. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/auth.py +0 -0
  94. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/debug.py +0 -0
  95. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/deploy.py +0 -0
  96. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/doctor.py +0 -0
  97. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/keys.py +0 -0
  98. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/main.py +0 -0
  99. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/parser.py +0 -0
  100. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/run.py +0 -0
  101. {fal-1.2.0 → fal-1.2.1}/src/fal/cli/secrets.py +0 -0
  102. {fal-1.2.0 → fal-1.2.1}/src/fal/console/__init__.py +0 -0
  103. {fal-1.2.0 → fal-1.2.1}/src/fal/console/icons.py +0 -0
  104. {fal-1.2.0 → fal-1.2.1}/src/fal/console/ux.py +0 -0
  105. {fal-1.2.0 → fal-1.2.1}/src/fal/container.py +0 -0
  106. {fal-1.2.0 → fal-1.2.1}/src/fal/exceptions/__init__.py +0 -0
  107. {fal-1.2.0 → fal-1.2.1}/src/fal/exceptions/_base.py +0 -0
  108. {fal-1.2.0 → fal-1.2.1}/src/fal/exceptions/auth.py +0 -0
  109. {fal-1.2.0 → fal-1.2.1}/src/fal/flags.py +0 -0
  110. {fal-1.2.0 → fal-1.2.1}/src/fal/logging/__init__.py +0 -0
  111. {fal-1.2.0 → fal-1.2.1}/src/fal/logging/style.py +0 -0
  112. {fal-1.2.0 → fal-1.2.1}/src/fal/logging/trace.py +0 -0
  113. {fal-1.2.0 → fal-1.2.1}/src/fal/logging/user.py +0 -0
  114. {fal-1.2.0 → fal-1.2.1}/src/fal/py.typed +0 -0
  115. {fal-1.2.0 → fal-1.2.1}/src/fal/rest_client.py +0 -0
  116. {fal-1.2.0 → fal-1.2.1}/src/fal/sdk.py +0 -0
  117. {fal-1.2.0 → fal-1.2.1}/src/fal/sync.py +0 -0
  118. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/__init__.py +0 -0
  119. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/exceptions.py +0 -0
  120. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/file/__init__.py +0 -0
  121. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/file/file.py +0 -0
  122. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/file/providers/fal.py +0 -0
  123. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/file/providers/gcp.py +0 -0
  124. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/file/providers/r2.py +0 -0
  125. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/file/types.py +0 -0
  126. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/image/__init__.py +0 -0
  127. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/image/image.py +0 -0
  128. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/optimize.py +0 -0
  129. {fal-1.2.0 → fal-1.2.1}/src/fal/toolkit/utils/__init__.py +0 -0
  130. {fal-1.2.0 → fal-1.2.1}/src/fal/utils.py +0 -0
  131. {fal-1.2.0 → fal-1.2.1}/src/fal/workflows.py +0 -0
  132. {fal-1.2.0 → fal-1.2.1}/tests/__init__.py +0 -0
  133. {fal-1.2.0 → fal-1.2.1}/tests/cli/__init__.py +0 -0
  134. {fal-1.2.0 → fal-1.2.1}/tests/cli/test_apps.py +0 -0
  135. {fal-1.2.0 → fal-1.2.1}/tests/cli/test_auth.py +0 -0
  136. {fal-1.2.0 → fal-1.2.1}/tests/cli/test_deploy.py +0 -0
  137. {fal-1.2.0 → fal-1.2.1}/tests/cli/test_keys.py +0 -0
  138. {fal-1.2.0 → fal-1.2.1}/tests/cli/test_run.py +0 -0
  139. {fal-1.2.0 → fal-1.2.1}/tests/cli/test_secrets.py +0 -0
  140. {fal-1.2.0 → fal-1.2.1}/tests/conftest.py +0 -0
  141. {fal-1.2.0 → fal-1.2.1}/tests/integration_test.py +0 -0
  142. {fal-1.2.0 → fal-1.2.1}/tests/mainify_package/__init__.py +0 -0
  143. {fal-1.2.0 → fal-1.2.1}/tests/mainify_package/impl.py +0 -0
  144. {fal-1.2.0 → fal-1.2.1}/tests/mainify_package/utils.py +0 -0
  145. {fal-1.2.0 → fal-1.2.1}/tests/mainify_target.py +0 -0
  146. {fal-1.2.0 → fal-1.2.1}/tests/test_apps.py +0 -0
  147. {fal-1.2.0 → fal-1.2.1}/tests/test_stability.py +0 -0
  148. {fal-1.2.0 → fal-1.2.1}/tests/toolkit/file_test.py +0 -0
  149. {fal-1.2.0 → fal-1.2.1}/tests/toolkit/image_test.py +0 -0
  150. {fal-1.2.0 → fal-1.2.1}/tools/demo_script.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fal
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: fal is an easy-to-use Serverless Python Framework
5
5
  Author: Features & Labels <support@fal.ai>
6
6
  Requires-Python: >=3.8
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fal
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: fal is an easy-to-use Serverless Python Framework
5
5
  Author: Features & Labels <support@fal.ai>
6
6
  Requires-Python: >=3.8
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.2.0'
16
- __version_tuple__ = version_tuple = (1, 2, 0)
15
+ __version__ = version = '1.2.1'
16
+ __version_tuple__ = version_tuple = (1, 2, 1)
@@ -17,11 +17,31 @@ class IsolateLogPrinter:
17
17
 
18
18
  def __init__(self, debug: bool = False) -> None:
19
19
  self.debug = debug
20
+ self._current_source: LogSource | None = None
21
+
22
+ def _maybe_print_header(self, source: LogSource):
23
+ from fal.console import console
24
+
25
+ if source == self._current_source:
26
+ return
27
+
28
+ msg = {
29
+ LogSource.BUILDER: "Building the environment",
30
+ LogSource.BRIDGE: "Unpacking user code",
31
+ LogSource.USER: "Running",
32
+ }.get(source)
33
+
34
+ if msg:
35
+ console.print(f"==> {msg}", style="bold green")
36
+
37
+ self._current_source = source
20
38
 
21
39
  def print(self, log: Log):
22
40
  if log.level < LogLevel.INFO and not self.debug:
23
41
  return
24
42
 
43
+ self._maybe_print_header(log.source)
44
+
25
45
  if log.source == LogSource.USER:
26
46
  stream = sys.stderr if log.level == LogLevel.STDERR else sys.stdout
27
47
  print(log.message, file=stream)
@@ -1,11 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import hashlib
4
+ import os
4
5
  import shutil
5
6
  import subprocess
6
7
  import sys
7
8
  from pathlib import Path, PurePath
8
- from tempfile import TemporaryDirectory
9
+ from tempfile import NamedTemporaryFile, TemporaryDirectory
9
10
  from urllib.parse import urlparse
10
11
  from urllib.request import Request, urlopen
11
12
 
@@ -215,10 +216,14 @@ def _download_file_python(
215
216
  Returns:
216
217
  The path where the downloaded file has been saved.
217
218
  """
218
- import shutil
219
- import tempfile
220
-
221
- with tempfile.NamedTemporaryFile(delete=False) as temp_file:
219
+ basename = os.path.basename(target_path)
220
+ # NOTE: using the same directory to avoid potential copies across temp fs and target
221
+ # fs, and also to be able to atomically rename a downloaded file into place.
222
+ with NamedTemporaryFile(
223
+ delete=False,
224
+ dir=os.path.dirname(target_path),
225
+ prefix=f"{basename}.tmp",
226
+ ) as temp_file:
222
227
  try:
223
228
  file_path = temp_file.name
224
229
 
@@ -232,13 +237,14 @@ def _download_file_python(
232
237
 
233
238
  print(progress_msg, end="\r\n")
234
239
 
235
- # Move the file when the file is downloaded completely. Since the
236
- # file used is temporary, in a case of an interruption, the downloaded
237
- # content will be lost. So, it is safe to redownload the file in such cases.
238
- shutil.move(file_path, target_path)
240
+ # NOTE: Atomically renaming the file into place when the file is downloaded
241
+ # completely.
242
+ #
243
+ # Since the file used is temporary, in a case of an interruption, the
244
+ # downloaded content will be lost. So, it is safe to redownload the file in
245
+ # such cases.
246
+ os.rename(file_path, target_path)
239
247
 
240
- except Exception as error:
241
- raise error
242
248
  finally:
243
249
  Path(temp_file.name).unlink(missing_ok=True)
244
250
 
@@ -403,35 +409,38 @@ def clone_repository(
403
409
  print(f"Removing the existing repository: {local_repo_path} ")
404
410
  shutil.rmtree(local_repo_path)
405
411
 
406
- # Temporary directory to download the repo into.
407
- temp_dir = TemporaryDirectory()
408
- temp_dir_path = temp_dir.name
409
-
410
- try:
411
- print(f"Cloning the repository '{https_url}' .")
412
-
413
- # Clone with disabling the logs and advices for detached HEAD state.
414
- clone_command = [
415
- "git",
416
- "clone",
417
- "--recursive",
418
- https_url,
419
- temp_dir_path,
420
- ]
421
- subprocess.check_call(clone_command)
422
-
423
- if commit_hash:
424
- checkout_command = ["git", "checkout", commit_hash]
425
- subprocess.check_call(checkout_command, cwd=temp_dir_path)
426
-
427
- # Move the repository when the clone and checkout is finished.
428
- shutil.move(temp_dir_path, local_repo_path)
429
-
430
- except Exception as error:
431
- print(f"{error}\nFailed to clone repository '{https_url}' .")
432
- temp_dir.cleanup()
412
+ # NOTE: using the target_dir to be able to avoid potential copies across temp fs
413
+ # and target fs, and also to be able to atomically rename repo_name dir into place
414
+ # when we are done setting it up.
415
+ os.makedirs(target_dir, exist_ok=True) # type: ignore[arg-type]
416
+ with TemporaryDirectory(
417
+ dir=target_dir,
418
+ suffix=f"{local_repo_path.name}.tmp",
419
+ ) as temp_dir:
420
+ try:
421
+ print(f"Cloning the repository '{https_url}' .")
422
+
423
+ # Clone with disabling the logs and advices for detached HEAD state.
424
+ clone_command = [
425
+ "git",
426
+ "clone",
427
+ "--recursive",
428
+ https_url,
429
+ temp_dir,
430
+ ]
431
+ subprocess.check_call(clone_command)
432
+
433
+ if commit_hash:
434
+ checkout_command = ["git", "checkout", commit_hash]
435
+ subprocess.check_call(checkout_command, cwd=temp_dir)
436
+
437
+ # NOTE: Atomically renaming the repository directory into place when the
438
+ # clone and checkout are done.
439
+ os.rename(temp_dir, local_repo_path)
433
440
 
434
- raise error
441
+ except Exception as error:
442
+ print(f"{error}\nFailed to clone repository '{https_url}' .")
443
+ raise error
435
444
 
436
445
  if include_to_path:
437
446
  __add_local_path_to_sys_path(local_repo_path)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes