1# frozen_string_literal: true
2require 'rubygems/text'
3
4class Gem::Licenses
5  extend Gem::Text
6
7  NONSTANDARD = 'Nonstandard'.freeze
8
9  # Software Package Data Exchange (SPDX) standard open-source software
10  # license identifiers
11  LICENSE_IDENTIFIERS = %w(
12      0BSD
13      AAL
14      ADSL
15      AFL-1.1
16      AFL-1.2
17      AFL-2.0
18      AFL-2.1
19      AFL-3.0
20      AGPL-1.0
21      AGPL-3.0
22      AGPL-3.0-only
23      AGPL-3.0-or-later
24      AMDPLPA
25      AML
26      AMPAS
27      ANTLR-PD
28      APAFML
29      APL-1.0
30      APSL-1.0
31      APSL-1.1
32      APSL-1.2
33      APSL-2.0
34      Abstyles
35      Adobe-2006
36      Adobe-Glyph
37      Afmparse
38      Aladdin
39      Apache-1.0
40      Apache-1.1
41      Apache-2.0
42      Artistic-1.0
43      Artistic-1.0-Perl
44      Artistic-1.0-cl8
45      Artistic-2.0
46      BSD-1-Clause
47      BSD-2-Clause
48      BSD-2-Clause-FreeBSD
49      BSD-2-Clause-NetBSD
50      BSD-2-Clause-Patent
51      BSD-3-Clause
52      BSD-3-Clause-Attribution
53      BSD-3-Clause-Clear
54      BSD-3-Clause-LBNL
55      BSD-3-Clause-No-Nuclear-License
56      BSD-3-Clause-No-Nuclear-License-2014
57      BSD-3-Clause-No-Nuclear-Warranty
58      BSD-4-Clause
59      BSD-4-Clause-UC
60      BSD-Protection
61      BSD-Source-Code
62      BSL-1.0
63      Bahyph
64      Barr
65      Beerware
66      BitTorrent-1.0
67      BitTorrent-1.1
68      Borceux
69      CATOSL-1.1
70      CC-BY-1.0
71      CC-BY-2.0
72      CC-BY-2.5
73      CC-BY-3.0
74      CC-BY-4.0
75      CC-BY-NC-1.0
76      CC-BY-NC-2.0
77      CC-BY-NC-2.5
78      CC-BY-NC-3.0
79      CC-BY-NC-4.0
80      CC-BY-NC-ND-1.0
81      CC-BY-NC-ND-2.0
82      CC-BY-NC-ND-2.5
83      CC-BY-NC-ND-3.0
84      CC-BY-NC-ND-4.0
85      CC-BY-NC-SA-1.0
86      CC-BY-NC-SA-2.0
87      CC-BY-NC-SA-2.5
88      CC-BY-NC-SA-3.0
89      CC-BY-NC-SA-4.0
90      CC-BY-ND-1.0
91      CC-BY-ND-2.0
92      CC-BY-ND-2.5
93      CC-BY-ND-3.0
94      CC-BY-ND-4.0
95      CC-BY-SA-1.0
96      CC-BY-SA-2.0
97      CC-BY-SA-2.5
98      CC-BY-SA-3.0
99      CC-BY-SA-4.0
100      CC0-1.0
101      CDDL-1.0
102      CDDL-1.1
103      CDLA-Permissive-1.0
104      CDLA-Sharing-1.0
105      CECILL-1.0
106      CECILL-1.1
107      CECILL-2.0
108      CECILL-2.1
109      CECILL-B
110      CECILL-C
111      CNRI-Jython
112      CNRI-Python
113      CNRI-Python-GPL-Compatible
114      CPAL-1.0
115      CPL-1.0
116      CPOL-1.02
117      CUA-OPL-1.0
118      Caldera
119      ClArtistic
120      Condor-1.1
121      Crossword
122      CrystalStacker
123      Cube
124      D-FSL-1.0
125      DOC
126      DSDP
127      Dotseqn
128      ECL-1.0
129      ECL-2.0
130      EFL-1.0
131      EFL-2.0
132      EPL-1.0
133      EPL-2.0
134      EUDatagrid
135      EUPL-1.0
136      EUPL-1.1
137      EUPL-1.2
138      Entessa
139      ErlPL-1.1
140      Eurosym
141      FSFAP
142      FSFUL
143      FSFULLR
144      FTL
145      Fair
146      Frameworx-1.0
147      FreeImage
148      GFDL-1.1
149      GFDL-1.1-only
150      GFDL-1.1-or-later
151      GFDL-1.2
152      GFDL-1.2-only
153      GFDL-1.2-or-later
154      GFDL-1.3
155      GFDL-1.3-only
156      GFDL-1.3-or-later
157      GL2PS
158      GPL-1.0
159      GPL-1.0+
160      GPL-1.0-only
161      GPL-1.0-or-later
162      GPL-2.0
163      GPL-2.0+
164      GPL-2.0-only
165      GPL-2.0-or-later
166      GPL-2.0-with-GCC-exception
167      GPL-2.0-with-autoconf-exception
168      GPL-2.0-with-bison-exception
169      GPL-2.0-with-classpath-exception
170      GPL-2.0-with-font-exception
171      GPL-3.0
172      GPL-3.0+
173      GPL-3.0-only
174      GPL-3.0-or-later
175      GPL-3.0-with-GCC-exception
176      GPL-3.0-with-autoconf-exception
177      Giftware
178      Glide
179      Glulxe
180      HPND
181      HaskellReport
182      IBM-pibs
183      ICU
184      IJG
185      IPA
186      IPL-1.0
187      ISC
188      ImageMagick
189      Imlib2
190      Info-ZIP
191      Intel
192      Intel-ACPI
193      Interbase-1.0
194      JSON
195      JasPer-2.0
196      LAL-1.2
197      LAL-1.3
198      LGPL-2.0
199      LGPL-2.0+
200      LGPL-2.0-only
201      LGPL-2.0-or-later
202      LGPL-2.1
203      LGPL-2.1+
204      LGPL-2.1-only
205      LGPL-2.1-or-later
206      LGPL-3.0
207      LGPL-3.0+
208      LGPL-3.0-only
209      LGPL-3.0-or-later
210      LGPLLR
211      LPL-1.0
212      LPL-1.02
213      LPPL-1.0
214      LPPL-1.1
215      LPPL-1.2
216      LPPL-1.3a
217      LPPL-1.3c
218      Latex2e
219      Leptonica
220      LiLiQ-P-1.1
221      LiLiQ-R-1.1
222      LiLiQ-Rplus-1.1
223      Libpng
224      MIT
225      MIT-CMU
226      MIT-advertising
227      MIT-enna
228      MIT-feh
229      MITNFA
230      MPL-1.0
231      MPL-1.1
232      MPL-2.0
233      MPL-2.0-no-copyleft-exception
234      MS-PL
235      MS-RL
236      MTLL
237      MakeIndex
238      MirOS
239      Motosoto
240      Multics
241      Mup
242      NASA-1.3
243      NBPL-1.0
244      NCSA
245      NGPL
246      NLOD-1.0
247      NLPL
248      NOSL
249      NPL-1.0
250      NPL-1.1
251      NPOSL-3.0
252      NRL
253      NTP
254      Naumen
255      Net-SNMP
256      NetCDF
257      Newsletr
258      Nokia
259      Noweb
260      Nunit
261      OCCT-PL
262      OCLC-2.0
263      ODbL-1.0
264      OFL-1.0
265      OFL-1.1
266      OGTSL
267      OLDAP-1.1
268      OLDAP-1.2
269      OLDAP-1.3
270      OLDAP-1.4
271      OLDAP-2.0
272      OLDAP-2.0.1
273      OLDAP-2.1
274      OLDAP-2.2
275      OLDAP-2.2.1
276      OLDAP-2.2.2
277      OLDAP-2.3
278      OLDAP-2.4
279      OLDAP-2.5
280      OLDAP-2.6
281      OLDAP-2.7
282      OLDAP-2.8
283      OML
284      OPL-1.0
285      OSET-PL-2.1
286      OSL-1.0
287      OSL-1.1
288      OSL-2.0
289      OSL-2.1
290      OSL-3.0
291      OpenSSL
292      PDDL-1.0
293      PHP-3.0
294      PHP-3.01
295      Plexus
296      PostgreSQL
297      Python-2.0
298      QPL-1.0
299      Qhull
300      RHeCos-1.1
301      RPL-1.1
302      RPL-1.5
303      RPSL-1.0
304      RSA-MD
305      RSCPL
306      Rdisc
307      Ruby
308      SAX-PD
309      SCEA
310      SGI-B-1.0
311      SGI-B-1.1
312      SGI-B-2.0
313      SISSL
314      SISSL-1.2
315      SMLNJ
316      SMPPL
317      SNIA
318      SPL-1.0
319      SWL
320      Saxpath
321      Sendmail
322      SimPL-2.0
323      Sleepycat
324      Spencer-86
325      Spencer-94
326      Spencer-99
327      StandardML-NJ
328      SugarCRM-1.1.3
329      TCL
330      TCP-wrappers
331      TMate
332      TORQUE-1.1
333      TOSL
334      UPL-1.0
335      Unicode-DFS-2015
336      Unicode-DFS-2016
337      Unicode-TOU
338      Unlicense
339      VOSTROM
340      VSL-1.0
341      Vim
342      W3C
343      W3C-19980720
344      W3C-20150513
345      WTFPL
346      Watcom-1.0
347      Wsuipa
348      X11
349      XFree86-1.1
350      XSkat
351      Xerox
352      Xnet
353      YPL-1.0
354      YPL-1.1
355      ZPL-1.1
356      ZPL-2.0
357      ZPL-2.1
358      Zed
359      Zend-2.0
360      Zimbra-1.3
361      Zimbra-1.4
362      Zlib
363      bzip2-1.0.5
364      bzip2-1.0.6
365      curl
366      diffmark
367      dvipdfm
368      eCos-2.0
369      eGenix
370      gSOAP-1.3b
371      gnuplot
372      iMatix
373      libtiff
374      mpich2
375      psfrag
376      psutils
377      wxWindows
378      xinetd
379      xpp
380      zlib-acknowledgement
381  ).freeze
382
383  # exception identifiers
384  EXCEPTION_IDENTIFIERS = %w(
385      389-exception
386      Autoconf-exception-2.0
387      Autoconf-exception-3.0
388      Bison-exception-2.2
389      Bootloader-exception
390      CLISP-exception-2.0
391      Classpath-exception-2.0
392      DigiRule-FOSS-exception
393      FLTK-exception
394      Fawkes-Runtime-exception
395      Font-exception-2.0
396      GCC-exception-2.0
397      GCC-exception-3.1
398      LZMA-exception
399      Libtool-exception
400      Linux-syscall-note
401      Nokia-Qt-exception-1.1
402      OCCT-exception-1.0
403      Qwt-exception-1.0
404      WxWindows-exception-3.1
405      eCos-exception-2.0
406      freertos-exception-2.0
407      gnu-javamail-exception
408      i2p-gpl-java-exception
409      mif-exception
410      openvpn-openssl-exception
411      u-boot-exception-2.0
412  ).freeze
413
414  REGEXP = %r{
415    \A
416    (
417      #{Regexp.union(LICENSE_IDENTIFIERS)}
418      \+?
419      (\s WITH \s #{Regexp.union(EXCEPTION_IDENTIFIERS)})?
420      | #{NONSTANDARD}
421    )
422    \Z
423  }ox.freeze
424
425  def self.match?(license)
426    !REGEXP.match(license).nil?
427  end
428
429  def self.suggestions(license)
430    by_distance = LICENSE_IDENTIFIERS.group_by do |identifier|
431      levenshtein_distance(identifier, license)
432    end
433    lowest = by_distance.keys.min
434    return unless lowest < license.size
435    by_distance[lowest]
436  end
437end
438