29
29
30
30
# global in-memory cache of the LicenseCache
31
31
_LICENSE_CACHE = None
32
+ # list of all additional directories included in the license cache
33
+ _CACHED_DIRECTORIES = []
32
34
33
35
LICENSE_INDEX_LOCK_TIMEOUT = 60 * 4
34
36
LICENSE_INDEX_DIR = 'license_index'
@@ -58,6 +60,7 @@ def load_or_build(
58
60
timeout = LICENSE_INDEX_LOCK_TIMEOUT ,
59
61
licenses_data_dir = None ,
60
62
rules_data_dir = None ,
63
+ additional_directories = None ,
61
64
):
62
65
"""
63
66
Load or build and save and return a LicenseCache object.
@@ -92,6 +95,8 @@ def load_or_build(
92
95
from licensedcode .models import licenses_data_dir as ldd
93
96
from licensedcode .models import rules_data_dir as rdd
94
97
from licensedcode .models import load_licenses
98
+ from licensedcode .models import load_licenses_from_multiple_dirs
99
+ from licensedcode .models import get_license_dirs
95
100
from scancode import lockfile
96
101
97
102
licenses_data_dir = licenses_data_dir or ldd
@@ -106,13 +111,21 @@ def load_or_build(
106
111
# Here, the cache is either stale or non-existing: we need to
107
112
# rebuild all cached data (e.g. mostly the index) and cache it
108
113
109
- licenses_db = load_licenses (licenses_data_dir = licenses_data_dir )
114
+ if additional_directories :
115
+ additional_license_dirs = get_license_dirs (additional_dirs = additional_directories )
116
+ combined_directories = [licenses_data_dir ] + additional_license_dirs
117
+ licenses_db = load_licenses_from_multiple_dirs (license_directories = combined_directories )
118
+ else :
119
+ licenses_db = load_licenses (licenses_data_dir = licenses_data_dir )
110
120
121
+ # create a single merged index containing license data from licenses_data_dir
122
+ # and data from additional directories
111
123
index = build_index (
112
124
licenses_db = licenses_db ,
113
125
licenses_data_dir = licenses_data_dir ,
114
126
rules_data_dir = rules_data_dir ,
115
127
index_all_languages = index_all_languages ,
128
+ additional_directories = additional_directories ,
116
129
)
117
130
118
131
spdx_symbols = build_spdx_symbols (licenses_db = licenses_db )
@@ -143,27 +156,50 @@ def build_index(
143
156
licenses_data_dir = None ,
144
157
rules_data_dir = None ,
145
158
index_all_languages = False ,
159
+ additional_directories = None ,
146
160
):
147
161
"""
148
162
Return an index built from rules and licenses directories
149
163
150
164
If ``index_all_languages`` is True, include texts and rules in all languages.
151
165
Otherwise, only include the English license texts and rules (the default)
166
+ If ``additional_directories`` is not None, we will include licenses and rules
167
+ from these additional directories in the returned index.
152
168
"""
153
169
from licensedcode .index import LicenseIndex
170
+ from licensedcode .models import get_license_dirs
171
+ from licensedcode .models import get_rule_dirs
154
172
from licensedcode .models import get_rules
173
+ from licensedcode .models import get_rules_from_multiple_dirs
155
174
from licensedcode .models import get_all_spdx_key_tokens
156
175
from licensedcode .models import get_license_tokens
157
176
from licensedcode .models import licenses_data_dir as ldd
158
177
from licensedcode .models import rules_data_dir as rdd
159
178
from licensedcode .models import load_licenses
179
+ from licensedcode .models import load_licenses_from_multiple_dirs
160
180
from licensedcode .legalese import common_license_words
161
181
162
182
licenses_data_dir = licenses_data_dir or ldd
163
183
rules_data_dir = rules_data_dir or rdd
164
184
165
- licenses_db = licenses_db or load_licenses (licenses_data_dir = licenses_data_dir )
166
- rules = get_rules (licenses_db = licenses_db , rules_data_dir = rules_data_dir )
185
+ if not licenses_db :
186
+ if additional_directories :
187
+ # combine the licenses in these additional directories with the licenses in the original DB
188
+ additional_license_dirs = get_license_dirs (additional_dirs = additional_directories )
189
+ combined_license_directories = [licenses_data_dir ] + additional_license_dirs
190
+ # generate a single combined license db with all licenses
191
+ licenses_db = load_licenses_from_multiple_dirs (license_dirs = combined_license_directories )
192
+ else :
193
+ licenses_db = load_licenses (licenses_data_dir = licenses_data_dir )
194
+
195
+ if additional_directories :
196
+ # if we have additional directories, extract the rules from them
197
+ additional_rule_dirs = get_rule_dirs (additional_dirs = additional_directories )
198
+ # then combine the rules in these additional directories with the rules in the original rules directory
199
+ combined_rule_directories = [rules_data_dir ] + additional_rule_dirs
200
+ rules = get_rules_from_multiple_dirs (licenses_db = licenses_db , rule_directories = combined_rule_directories )
201
+ else :
202
+ rules = get_rules (licenses_db = licenses_db , rules_data_dir = rules_data_dir )
167
203
168
204
legalese = common_license_words
169
205
spdx_tokens = set (get_all_spdx_key_tokens (licenses_db ))
@@ -299,33 +335,42 @@ def build_unknown_spdx_symbol(licenses_db=None):
299
335
return LicenseSymbolLike (licenses_db ['unknown-spdx' ])
300
336
301
337
302
- def get_cache (force = False , index_all_languages = False ):
338
+ def get_cache (force = False , index_all_languages = False , additional_directories = None ):
303
339
"""
304
340
Return a LicenseCache either rebuilt, cached or loaded from disk.
305
341
306
342
If ``index_all_languages`` is True, include texts in all languages when
307
343
building the license index. Otherwise, only include the English license \
308
344
texts and rules (the default)
309
345
"""
310
- populate_cache (force = force , index_all_languages = index_all_languages )
346
+ populate_cache (force = force , index_all_languages = index_all_languages , additional_directories = additional_directories )
311
347
global _LICENSE_CACHE
312
348
return _LICENSE_CACHE
313
349
314
350
315
- def populate_cache (force = False , index_all_languages = False ):
351
+ def populate_cache (force = False , index_all_languages = False , additional_directories = None ):
316
352
"""
317
353
Load or build and cache a LicenseCache. Return None.
318
354
"""
319
355
global _LICENSE_CACHE
320
- if force or not _LICENSE_CACHE :
356
+ global _CACHED_DIRECTORIES
357
+ should_rebuild_cache = additional_directories is not None \
358
+ and sorted (additional_directories ) != sorted (_CACHED_DIRECTORIES )
359
+ if should_rebuild_cache :
360
+ # otherwise we will just return previous cache on line 84
361
+ force = True
362
+ if force or not _LICENSE_CACHE or should_rebuild_cache :
321
363
_LICENSE_CACHE = LicenseCache .load_or_build (
322
364
licensedcode_cache_dir = licensedcode_cache_dir ,
323
365
scancode_cache_dir = scancode_cache_dir ,
324
366
force = force ,
325
367
index_all_languages = index_all_languages ,
326
368
# used for testing only
327
369
timeout = LICENSE_INDEX_LOCK_TIMEOUT ,
370
+ additional_directories = additional_directories ,
328
371
)
372
+ if additional_directories :
373
+ _CACHED_DIRECTORIES = additional_directories
329
374
330
375
331
376
def load_cache_file (cache_file ):
@@ -346,11 +391,15 @@ def load_cache_file(cache_file):
346
391
raise Exception (msg ) from e
347
392
348
393
349
- def get_index (force = False , index_all_languages = False ):
394
+ def get_index (force = False , index_all_languages = False , additional_directories = None ):
350
395
"""
351
396
Return and eventually build and cache a LicenseIndex.
352
397
"""
353
- return get_cache (force = force , index_all_languages = index_all_languages ).index
398
+ return get_cache (
399
+ force = force ,
400
+ index_all_languages = index_all_languages ,
401
+ additional_directories = additional_directories
402
+ ).index
354
403
355
404
356
405
get_cached_index = get_index
0 commit comments