opensource 2.0.0 → 2.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10f6493f56895d2dbfaa012c2203ae1b6c08aa3c0a12144d6cc6e9e3a838eaea
4
- data.tar.gz: 5b54333690d71a3fb7c16684b477a7880d6ff4d117024ec118eaa07d150e787c
3
+ metadata.gz: 88a46d31221547e064e035afd8912a8330ee23556bc1f68f4e3c01041dc6e318
4
+ data.tar.gz: 4f75381c7b2d05615bf37815991da3319a1fde8c69451dba6d8869dac4a7d1f9
5
5
  SHA512:
6
- metadata.gz: 926043857057cef9c8f676f08160226fa2b231898f20713567a8454496d1a3329442eeaa2108e69813f8fb63f5551c668d0dba1939ea287a62c6b55fa17e0638
7
- data.tar.gz: e8609f1cd3ca7b7aeac98645a5e1b354ca424be23441fa0da6e51c41816345b02333694c5305ee0d5169b3b5a00287da0aac294ea5200b8f2ba04f8524f1e305
6
+ metadata.gz: 212d14d940e64a30aefb70823dc7907d85dd46cf434199e79bcf18d1fa88a2b4be0b572d595baf81236263e68a9d5b78ab431f2b6fbb27f0d23e2ad7afccb0c2
7
+ data.tar.gz: a8b75d09d62aef6de3fe861b36ec1f02003aa95bdd4218f1b7d1122207595539bd020ac3a83e63fdcf75ceb5e324ec534dfcfa9d65a8a518cebe9a19fe9376a5
@@ -19,8 +19,8 @@ jobs:
19
19
  - "3.4"
20
20
  - "4.0"
21
21
  steps:
22
- - uses: actions/checkout@v6
23
- - uses: ruby/setup-ruby@v1
22
+ - uses: actions/checkout@v7.0.1
23
+ - uses: ruby/setup-ruby@v1.321.0
24
24
  with:
25
25
  ruby-version: ${{ matrix.ruby }}
26
26
  bundler-cache: true
data/History.md CHANGED
@@ -1,4 +1,10 @@
1
1
 
2
+ 2.1.0 / 2026-07-25
3
+ ==================
4
+
5
+ * handle missing credentials gracefully - improve ux
6
+ * Upgrade to latest deps
7
+
2
8
  2.0.0 / 2026-07-19
3
9
  ==================
4
10
 
data/exe/opensource CHANGED
@@ -39,15 +39,21 @@ option_parser = OptionParser.new do |opts|
39
39
  end
40
40
 
41
41
  begin
42
- option_parser.parse!
42
+ begin
43
+ option_parser.parse!
44
+ rescue OptionParser::ParseError => e
45
+ raise OpenSource::OptionError, e.message
46
+ end
47
+
43
48
  if options.empty?
44
49
  OpenSource.logger.info(option_parser)
45
50
  exit 0
46
51
  end
47
52
 
48
- OpenSource::License::Generator.new(options).generate
53
+ OpenSource.with_owner_credentials do
54
+ OpenSource::License::Generator.new(options).generate
55
+ end
49
56
  rescue OpenSource::Error => e
50
- # TODO: Make sure the above call raises only OpenSource::Error
51
57
  OpenSource.logger.fatal("Error: #{e.message}")
52
58
  exit 1
53
59
  end
@@ -1,7 +1,8 @@
1
1
  module OpenSource
2
- module Error
3
- def self.exception(*args)
4
- RuntimeError.new(*args).extend(self)
5
- end
6
- end
2
+ class Error < StandardError; end
3
+ class OptionError < Error; end
4
+ class ConfigError < Error; end
5
+ class MissingCredentialsError < ConfigError; end
6
+ class LicenseError < Error; end
7
+ class FileError < Error; end
7
8
  end
@@ -6,7 +6,7 @@ module OpenSource
6
6
  def initialize(options)
7
7
  @options = options
8
8
  @owner = Owner.new
9
- @license = ERB.new(File.read("#{File.expand_path("../templates", __FILE__)}/#{@options[:license]}.erb"))
9
+ @license = load_license_template
10
10
  end
11
11
 
12
12
  def generate
@@ -15,16 +15,62 @@ module OpenSource
15
15
  end
16
16
 
17
17
  private
18
+ def load_license_template
19
+ unless OpenSource::SUPPORTED_LICENSES.include?(@options[:license])
20
+ raise LicenseError, "Unsupported license #{@options[:license].inspect}. Supported licenses: #{OpenSource::SUPPORTED_LICENSES.join(', ')}"
21
+ end
22
+
23
+ ERB.new(File.read(template_path))
24
+ rescue OpenSource::Error
25
+ raise
26
+ rescue SystemCallError => ex
27
+ raise LicenseError, "Unable to read #{@options[:license]} license template: #{ex.message}"
28
+ end
29
+
30
+ def template_path
31
+ "#{File.expand_path("../templates", __FILE__)}/#{@options[:license]}.erb"
32
+ end
33
+
18
34
  def create_license_file
19
- f = File.new("#{Dir.pwd}/LICENSE", 'w')
20
- f.write(@license.result(binding))
21
- f.close
35
+ license_content = render_license
36
+
37
+ File.open(license_path, 'w') do |file|
38
+ file.write(license_content)
39
+ end
40
+ rescue OpenSource::Error
41
+ raise
42
+ rescue SystemCallError => ex
43
+ raise FileError, "Unable to write #{license_path}: #{ex.message}"
22
44
  end
23
45
 
24
46
  def append_to_file
25
- File.open(File.expand_path(@options[:append]), 'a') do |f|
26
- f << "\n## License\n\n#{@license.result(binding)}"
47
+ append_path = File.expand_path(@options[:append])
48
+ license_content = render_license(markdown: true)
49
+
50
+ File.open(append_path, 'a') do |file|
51
+ file << "\n## License\n\n#{license_content}"
27
52
  end
53
+ rescue OpenSource::Error
54
+ raise
55
+ rescue SystemCallError => ex
56
+ raise FileError, "Unable to append license to #{append_path}: #{ex.message}"
57
+ end
58
+
59
+ def license_path
60
+ "#{Dir.pwd}/LICENSE"
61
+ end
62
+
63
+ def render_license(markdown: false)
64
+ previous_owner_email = @owner_email
65
+ @owner_email = markdown ? @owner.markdown_supported_email : @owner.license_email
66
+
67
+ @license.result(binding)
68
+ rescue OpenSource::Error
69
+ raise
70
+ rescue StandardError => ex
71
+ raise LicenseError, "Unable to render #{@options[:license]} license: #{ex.message}"
72
+ ensure
73
+ @owner_email = previous_owner_email
28
74
  end
29
75
  end
30
76
  end
@@ -4,15 +4,15 @@ module OpenSource
4
4
  module License
5
5
  class Owner
6
6
  def credentials=(credentials)
7
- config_file = File.new(CONFIG_PATH, 'w')
8
- file_contents = YAML.dump(credentials)
9
- config_file.write(file_contents)
10
- rescue StandardError => ex
11
- OpenSource.logger.fatal("Unable to access #{CONFIG_PATH}")
7
+ File.open(CONFIG_PATH, 'w') do |config_file|
8
+ config_file.write(YAML.dump(credentials))
9
+ end
10
+ rescue SystemCallError => ex
11
+ raise ConfigError, "Unable to write #{CONFIG_PATH}: #{ex.message}"
12
12
  end
13
13
 
14
14
  def credentials
15
- @credentials ||= YAML.load_file(CONFIG_PATH)
15
+ @credentials ||= load_credentials
16
16
  end
17
17
 
18
18
  def email
@@ -23,9 +23,43 @@ module OpenSource
23
23
  "&lt;#{credentials[:email]}&gt;"
24
24
  end
25
25
 
26
+ def license_email
27
+ "<#{credentials[:email]}>"
28
+ end
29
+
26
30
  def name
27
31
  credentials[:name]
28
32
  end
33
+
34
+ private
35
+ def load_credentials
36
+ credentials = YAML.load_file(CONFIG_PATH)
37
+ credentials = normalize_credentials(credentials)
38
+
39
+ unless credentials.key?(:name) && credentials.key?(:email)
40
+ raise ConfigError, "Invalid configuration in #{CONFIG_PATH}; run `opensource --setup` to recreate it"
41
+ end
42
+
43
+ credentials
44
+ rescue OpenSource::Error
45
+ raise
46
+ rescue Errno::ENOENT
47
+ raise MissingCredentialsError, "Missing #{CONFIG_PATH}; run `opensource --setup` first"
48
+ rescue Psych::Exception => ex
49
+ raise ConfigError, "Unable to parse #{CONFIG_PATH}: #{ex.message}"
50
+ rescue SystemCallError => ex
51
+ raise ConfigError, "Unable to read #{CONFIG_PATH}: #{ex.message}"
52
+ end
53
+
54
+ def normalize_credentials(credentials)
55
+ unless credentials.is_a?(Hash)
56
+ raise ConfigError, "Invalid configuration in #{CONFIG_PATH}; run `opensource --setup` to recreate it"
57
+ end
58
+
59
+ credentials.each_with_object({}) do |(key, value), normalized|
60
+ normalized[key.to_sym] = value if key.respond_to?(:to_sym)
61
+ end
62
+ end
29
63
  end
30
64
  end
31
65
  end
@@ -187,7 +187,7 @@ APPENDIX: How to apply the Apache License to your work.
187
187
  same "printed page" as the copyright notice for easier
188
188
  identification within third-party archives.
189
189
 
190
- Copyright <%= Time.now.year %> <%= @owner.name %> <%= @owner.markdown_supported_email %>
190
+ Copyright <%= Time.now.year %> <%= @owner.name %> <%= @owner_email %>
191
191
 
192
192
  Licensed under the Apache License, Version 2.0 (the "License");
193
193
  you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- Copyright (c) <%= Time.now.year %> <%= @owner.name %> <%= @owner.markdown_supported_email %>
1
+ Copyright (c) <%= Time.now.year %> <%= @owner.name %> <%= @owner_email %>
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
@@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
632
632
  the "copyright" line and a pointer to where the full notice is found.
633
633
 
634
634
  <one line to give the program's name and a brief idea of what it does.>
635
- Copyright (C) <%= Time.now.year %> <%= @owner.name %> <%= @owner.markdown_supported_email %>
635
+ Copyright (C) <%= Time.now.year %> <%= @owner.name %> <%= @owner_email %>
636
636
 
637
637
  This program is free software: you can redistribute it and/or modify
638
638
  it under the terms of the GNU General Public License as published by
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
652
652
  If the program does terminal interaction, make it output a short
653
653
  notice like this when it starts in an interactive mode:
654
654
 
655
- Copyright (C) <%= Time.now.year %> <%= @owner.name %> <%= @owner.markdown_supported_email %>
655
+ Copyright (C) <%= Time.now.year %> <%= @owner.name %> <%= @owner_email %>
656
656
  This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
657
  This is free software, and you are welcome to redistribute it
658
658
  under certain conditions; type `show c' for details.
@@ -1,5 +1,5 @@
1
1
  ISC License (ISC)
2
- Copyright (c) <%= Time.now.year %>, <%= @owner.name %> <%= @owner.markdown_supported_email %>
2
+ Copyright (c) <%= Time.now.year %>, <%= @owner.name %> <%= @owner_email %>
3
3
 
4
4
  Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
5
5
 
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) <%= Time.now.year %> <%= @owner.name %> <%= @owner.markdown_supported_email %>
3
+ Copyright (c) <%= Time.now.year %> <%= @owner.name %> <%= @owner_email %>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
@@ -1,3 +1,3 @@
1
1
  module OpenSource
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
data/lib/open_source.rb CHANGED
@@ -27,4 +27,14 @@ module OpenSource
27
27
  owner = License::Owner.new
28
28
  owner.credentials = owner_credentials
29
29
  end
30
+
31
+ def self.with_owner_credentials(interactive: $stdin.tty?)
32
+ yield
33
+ rescue MissingCredentialsError
34
+ raise unless interactive
35
+
36
+ OpenSource.logger.info("Owner credentials are not set. Let's set them up now.")
37
+ setup_owner_credentials
38
+ yield
39
+ end
30
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opensource
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mohnish Thallavajhula