Class: Licensee::License

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
ContentHelper, HashHelper
Defined in:
lib/licensee/license.rb

Constant Summary collapse

YAML_DEFAULTS =

Preserved for backwards compatibility

Licensee::LicenseMeta.members
PSEUDO_LICENSES =

Pseudo-license are license placeholders with no content

‘other` - The project had a license, but we were not able to detect it `no-license` - The project is not licensed (e.g., all rights reserved)

NOTE: A lack of detected license will be a nil license

%w[other no-license].freeze
DEFAULT_OPTIONS =

Default options to use when retrieving licenses via #all

{
  hidden:   false,
  featured: nil,
  pseudo:   true
}.freeze
SOURCE_PREFIX =
%r{https?://(?:www\.)?}i
SOURCE_SUFFIX =
%r{(?:\.html?|\.txt|/)(?:\?[^\s]*)?}i
HASH_METHODS =
%i[
  key spdx_id meta url rules fields other? gpl? lgpl? cc?
].freeze

Constants included from ContentHelper

ContentHelper::DIGEST, ContentHelper::END_OF_TERMS_REGEX, ContentHelper::NORMALIZATIONS, ContentHelper::REGEXES, ContentHelper::START_REGEX, ContentHelper::STRIP_METHODS, ContentHelper::VARIETAL_WORDS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HashHelper

#to_h

Methods included from ContentHelper

const_missing, #content_hash, #content_normalized, #content_without_title_and_version, format_percent, #length, #length_delta, #similarity, title_regex, #wordset, wrap

Constructor Details

#initialize(key) ⇒ License

Returns a new instance of License.



113
114
115
# File 'lib/licensee/license.rb', line 113

def initialize(key)
  @key = key.downcase
end

Instance Attribute Details

#keyObject (readonly)

Returns the value of attribute key.



81
82
83
# File 'lib/licensee/license.rb', line 81

def key
  @key
end

Class Method Details

.all(options = {}) ⇒ Object

All license objects defined via Licensee (via choosealicense.com)

Options:

  • :hidden - boolean, return hidden licenses (default: false)

  • :featured - boolean, return only (non)featured licenses (default: all)

Returns an Array of License objects.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/licensee/license.rb', line 20

def all(options = {})
  @all[options] ||= begin
    # TODO: Remove in next major version to avoid breaking change
    options[:pseudo] ||= options[:psuedo] unless options[:psuedo].nil?

    options = DEFAULT_OPTIONS.merge(options)
    output = licenses.dup
    output.reject!(&:hidden?) unless options[:hidden]
    output.reject!(&:pseudo_license?) unless options[:pseudo]
    output.sort_by!(&:key)
    if options[:featured].nil?
      output
    else
      output.select { |l| l.featured? == options[:featured] }
    end
  end
end

.find(key, options = {}) ⇒ Object Also known as: [], find_by_key



44
45
46
47
# File 'lib/licensee/license.rb', line 44

def find(key, options = {})
  options = { hidden: true }.merge(options)
  keys_licenses(options)[key.downcase]
end

.find_by_title(title) ⇒ Object

Given a license title or nickname, fuzzy match the license



52
53
54
55
56
# File 'lib/licensee/license.rb', line 52

def find_by_title(title)
  License.all(hidden: true, pseudo: false).find do |license|
    title =~ /\A(the )?#{license.title_regex}( license)?\z/i
  end
end

.keysObject



38
39
40
41
42
# File 'lib/licensee/license.rb', line 38

def keys
  @keys ||= license_files.map do |license_file|
    ::File.basename(license_file, '.txt').downcase
  end + PSEUDO_LICENSES
end

.license_dirObject



58
59
60
# File 'lib/licensee/license.rb', line 58

def license_dir
  ::File.expand_path '../../vendor/choosealicense.com/_licenses', __dir__
end

.license_filesObject



62
63
64
# File 'lib/licensee/license.rb', line 62

def license_files
  @license_files ||= Dir.glob("#{license_dir}/*.txt")
end

.spdx_dirObject



66
67
68
# File 'lib/licensee/license.rb', line 66

def spdx_dir
  ::File.expand_path '../../vendor/license-list-XML/src', __dir__
end

Instance Method Details

#==(other) ⇒ Object



226
227
228
# File 'lib/licensee/license.rb', line 226

def ==(other)
  other.is_a?(self.class) && key == other.key
end

#contentObject Also known as: to_s, text, body

The license body (e.g., contents - frontmatter)



215
216
217
# File 'lib/licensee/license.rb', line 215

def content
  @content ||= parts[2] if parts && parts[2]
end

#content_for_mustacheObject

Returns a string with ‘[fields]` replaced by `{{fields}}` Does not mangle non-supported fields in the form of `[field]`



249
250
251
# File 'lib/licensee/license.rb', line 249

def content_for_mustache
  @content_for_mustache ||= content.gsub(LicenseField::FIELD_REGEX, '{{{\1}}}')
end

#creative_commons?Boolean Also known as: cc?

Is this license a Creative Commons license?

Returns:

  • (Boolean)


209
210
211
# File 'lib/licensee/license.rb', line 209

def creative_commons?
  key.start_with?('cc-')
end

#fieldsObject

Returns an array of strings of substitutable fields in the license body



243
244
245
# File 'lib/licensee/license.rb', line 243

def fields
  @fields ||= LicenseField.from_content(content)
end

#gpl?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/licensee/license.rb', line 200

def gpl?
  key == 'gpl-2.0' || key == 'gpl-3.0'
end

#inspectObject



238
239
240
# File 'lib/licensee/license.rb', line 238

def inspect
  "#<Licensee::License key=#{key}>"
end

#lgpl?Boolean

Returns:

  • (Boolean)


204
205
206
# File 'lib/licensee/license.rb', line 204

def lgpl?
  key == 'lgpl-2.1' || key == 'lgpl-3.0'
end

#metaObject

License metadata from YAML front matter with defaults merged in



123
124
125
# File 'lib/licensee/license.rb', line 123

def meta
  @meta ||= LicenseMeta.from_yaml(yaml)
end

#nameObject

Returns the human-readable license name



134
135
136
137
138
# File 'lib/licensee/license.rb', line 134

def name
  return key.tr('-', ' ').capitalize if pseudo_license?

  title || spdx_id
end

#name_without_versionObject



140
141
142
# File 'lib/licensee/license.rb', line 140

def name_without_version
  /(.+?)(( v?\d\.\d)|$)/.match(name)[1]
end

#other?Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/licensee/license.rb', line 196

def other?
  key == 'other'
end

#pathObject

Path to vendored license file on disk



118
119
120
# File 'lib/licensee/license.rb', line 118

def path
  @path ||= File.expand_path "#{@key}.txt", Licensee::License.license_dir
end

#pseudo_license?Boolean

Returns:

  • (Boolean)


230
231
232
# File 'lib/licensee/license.rb', line 230

def pseudo_license?
  PSEUDO_LICENSES.include?(key)
end

#rulesObject



234
235
236
# File 'lib/licensee/license.rb', line 234

def rules
  @rules ||= LicenseRules.from_meta(meta)
end

#source_regexObject

Returns a regex that will match the license source

The following variations are supported (as presumed identical):

  1. HTTP or HTTPS

  2. www or non-www

  3. .txt, .html, .htm, or / suffix

Returns the regex, or nil if no source exists



185
186
187
188
189
190
191
192
193
194
# File 'lib/licensee/license.rb', line 185

def source_regex
  return @source_regex if defined? @source_regex
  return unless meta.source

  source = meta.source.dup.sub(/\A#{SOURCE_PREFIX}/o, '')
  source = source.sub(/#{SOURCE_SUFFIX}\z/o, '')

  escaped_source = Regexp.escape(source)
  @source_regex = /#{SOURCE_PREFIX}#{escaped_source}(?:#{SOURCE_SUFFIX})?/i
end

#spdx_idObject



127
128
129
130
131
# File 'lib/licensee/license.rb', line 127

def spdx_id
  return meta.spdx_id if meta.spdx_id
  return 'NOASSERTION' if key == 'other'
  return 'NONE' if key == 'no-license'
end

#title_regexObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/licensee/license.rb', line 144

def title_regex
  return @title_regex if defined? @title_regex

  string = name.downcase.sub('*', 'u')
  simple_title_regex = Regexp.new string, 'i'
  string.sub!(/\Athe /i, '')
  string.sub!(/,? version /, ' ')
  string.sub!(/v(\d+\.\d+)/, '\1')
  string = Regexp.escape(string)
  string = string.sub(/\\ licen[sc]e/i, '(?:\ licen[sc]e)?')
  version_match = string.match(/\d+\\.(\d+)/)
  if version_match
    vsub = if version_match[1] == '0'
             ',?\s+(?:version\ |v(?:\. )?)?\1(\2)?'
           else
             ',?\s+(?:version\ |v(?:\. )?)?\1\2'
           end
    string = string.sub(/\\ (\d+)(\\.\d+)/, vsub)
  end
  string = string.sub(/\bgnu\\ /, '(?:GNU )?')
  title_regex = Regexp.new string, 'i'

  string = key.sub('-', '[- ]')
  string.sub!('.', '\.')
  string << '(?:\ licen[sc]e)?'
  key_regex = Regexp.new string, 'i'

  parts = [simple_title_regex, title_regex, key_regex]
  parts.push Regexp.new meta.nickname.sub(/\bGNU /i, '(?:GNU )?') if meta.nickname

  @title_regex = Regexp.union parts
end

#urlObject



222
223
224
# File 'lib/licensee/license.rb', line 222

def url
  URI.join(Licensee::DOMAIN, "/licenses/#{key}/").to_s
end