1
+ #
2
+ # DownloadCacher.cmake
3
+ # Copyright 2021-2022 ItJustWorksTM
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ # function for cleaning the cache
19
+ function (clear_download_cache)
20
+ # delete all contents in the cached folder
21
+ file (REMOVE_RECURSE "${SMCE_DIR} /cached_downloads/" )
22
+ message (STATUS "Cache cleared" )
23
+ endfunction ()
24
+
25
+ #[================================================================================================================[.rst:
26
+ cached_download
27
+ --------------------
28
+
29
+ Function to allow for caching of various downloads.
30
+
31
+ Usage:
32
+ .. code-block:: cmake
33
+
34
+ cached_download (URL <url> DEST <dest-var> [RESULT_VARIABLE <res-var>] [FORCE_UPDATE])
35
+
36
+ Where ``<url>`` is the URL to the file to be downloaded, ``<dest-var>`` is the name of the variable to store the absolute
37
+ real path to the download location passed to the parent scope by the function, ``<res-var>``
38
+ is the name of the variable to store the result of all processes passed to the parent scope by
39
+ the function, ``[FORCE_UPDATE]`` will define whether an already cached download should be re-downloaded and cached.
40
+
41
+
42
+ Note:
43
+ No additional arguments except for the ones defined are allowed in the function call.
44
+ Uses SHA256 to create a uniquely hashed download location for each download.
45
+ Download file is locked until the file has been downloaded and cached, this is done in order to avoid
46
+ possible race conditions.
47
+ #]================================================================================================================]
48
+ function (cached_download)
49
+ # initialize the cache download directory
50
+ file (MAKE_DIRECTORY "${SMCE_DIR} /cached_downloads" )
51
+
52
+ # parse args
53
+ set (options FORCE_UPDATE)
54
+ set (oneValueArgs URL RESULT_VARIABLE DEST)
55
+ set (multiValueArgs)
56
+ cmake_parse_arguments ("ARG" "${options} " "${oneValueArgs} " "${multiValueArgs} " ${ARGN} )
57
+
58
+ if (${ARG_UNPARSED_ARGUMENTS} )
59
+ if (DEFINED ARG_RESULT_VARIABLE)
60
+ set ("Function was called with too many arguments" PARENT_SCOPE)
61
+ else ()
62
+ message (FATAL_ERROR "Function was called with too many arguments" )
63
+ endif ()
64
+ endif ()
65
+
66
+ # use SHA256 hash to URL to create unique identifier, lock download location mutex-style
67
+ string (SHA256 hashed_dest "${ARG_URL} " )
68
+ set (download_path "${SMCE_DIR} /cached_downloads/${hashed_dest} " )
69
+ file (TOUCH "${download_path} .lock" )
70
+ file (LOCK "${download_path} .lock" )
71
+
72
+ # check if plugin has already been downloaded and cached before
73
+ if (EXISTS "${download_path} " )
74
+ set (index 1)
75
+ else ()
76
+ set (index -1)
77
+ endif ()
78
+
79
+ # if download has been cached previously and is requested a forced re-download, clean previous download and re-cache
80
+ if (${index} GREATER -1 AND ${ARG_FORCE_UPDATE} )
81
+ file (REMOVE "${download_path} " )
82
+ set (${index} -1)
83
+ endif ()
84
+
85
+ # if download has not been cached, download. Otherwise pass.
86
+ if (${index} LESS 0)
87
+ message (DEBUG "Downloading" )
88
+
89
+ file (DOWNLOAD "${ARG_URL} " "${download_path} " STATUS dlstatus)
90
+ list (GET dlstatus 0 dlstatus_code)
91
+ if (dlstatus_code)
92
+ list (GET dlstatus 1 dlstatus_message)
93
+ file (REMOVE "${download_path} " )
94
+ file (REMOVE "${download_path} .lock" )
95
+ if (DEFINED ARG_RESULT_VARIABLE)
96
+ set ("${ARG_RESULT_VARIABLE} " "${dlstatus} " PARENT_SCOPE)
97
+ else ()
98
+ message (FATAL_ERROR "Download failed: (${dlstatus_code} ) ${dlstatus_message} " )
99
+ endif ()
100
+ endif ()
101
+ message (DEBUG "Download complete" )
102
+ message (DEBUG "Cached!" )
103
+ else ()
104
+ message (DEBUG "Has already been cached!" )
105
+ endif ()
106
+
107
+ # Unlock file and output absolute real path to download location
108
+ file (LOCK "${download_path} .lock" RELEASE)
109
+ file (REMOVE "${download_path} .lock" )
110
+
111
+ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.19" )
112
+ file (REAL_PATH "${download_path} " download_path)
113
+ else ()
114
+ get_filename_component (download_path "${download_path} " REALPATH)
115
+ endif ()
116
+
117
+ set ("${ARG_DEST} " "${download_path} " PARENT_SCOPE)
118
+ endfunction ()
0 commit comments