tiny-sharp-pkg 0.0.1

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.
@@ -0,0 +1,109 @@
1
+ require "dotenv/substitutions/variable"
2
+ require "dotenv/substitutions/command" if RUBY_VERSION > "1.8.7"
3
+
4
+ module Dotenv
5
+ # Error raised when encountering a syntax error while parsing a .env file.
6
+ class FormatError < SyntaxError; end
7
+
8
+ # Parses the `.env` file format into key/value pairs.
9
+ # It allows for variable substitutions, command substitutions, and exporting of variables.
10
+ class Parser
11
+ @substitutions = [
12
+ Dotenv::Substitutions::Command,
13
+ Dotenv::Substitutions::Variable
14
+ ]
15
+
16
+ LINE = /
17
+ (?:^|\A) # beginning of line
18
+ \s* # leading whitespace
19
+ (?<export>export\s+)? # optional export
20
+ (?<key>[\w.]+) # key
21
+ (?: # optional separator and value
22
+ (?:\s*=\s*?|:\s+?) # separator
23
+ (?<value> # optional value begin
24
+ \s*'(?:\\'|[^'])*' # single quoted value
25
+ | # or
26
+ \s*"(?:\\"|[^"])*" # double quoted value
27
+ | # or
28
+ [^\#\n]+ # unquoted value
29
+ )? # value end
30
+ )? # separator and value end
31
+ \s* # trailing whitespace
32
+ (?:\#.*)? # optional comment
33
+ (?:$|\z) # end of line
34
+ /x
35
+
36
+ QUOTED_STRING = /\A(['"])(.*)\1\z/m
37
+
38
+ class << self
39
+ attr_reader :substitutions
40
+
41
+ def call(...)
42
+ new(...).call
43
+ end
44
+ end
45
+
46
+ def initialize(string, overwrite: false)
47
+ # Convert line breaks to same format
48
+ @string = string.gsub(/\r\n?/, "\n")
49
+ @hash = {}
50
+ @overwrite = overwrite
51
+ end
52
+
53
+ def call
54
+ @string.scan(LINE) do
55
+ match = $LAST_MATCH_INFO
56
+
57
+ if existing?(match[:key])
58
+ # Use value from already defined variable
59
+ @hash[match[:key]] = ENV[match[:key]]
60
+ elsif match[:export] && !match[:value]
61
+ # Check for exported variable with no value
62
+ if !@hash.member?(match[:key])
63
+ raise FormatError, "Line #{match.to_s.inspect} has an unset variable"
64
+ end
65
+ else
66
+ @hash[match[:key]] = parse_value(match[:value] || "")
67
+ end
68
+ end
69
+
70
+ @hash
71
+ end
72
+
73
+ private
74
+
75
+ # Determine if a variable is already defined and should not be overwritten.
76
+ def existing?(key)
77
+ !@overwrite && key != "DOTENV_LINEBREAK_MODE" && ENV.key?(key)
78
+ end
79
+
80
+ def parse_value(value)
81
+ # Remove surrounding quotes
82
+ value = value.strip.sub(QUOTED_STRING, '\2')
83
+ maybe_quote = Regexp.last_match(1)
84
+
85
+ # Expand new lines in double quoted values
86
+ value = expand_newlines(value) if maybe_quote == '"'
87
+
88
+ # Unescape characters and performs substitutions unless value is single quoted
89
+ if maybe_quote != "'"
90
+ value = unescape_characters(value)
91
+ self.class.substitutions.each { |proc| value = proc.call(value, @hash) }
92
+ end
93
+
94
+ value
95
+ end
96
+
97
+ def unescape_characters(value)
98
+ value.gsub(/\\([^$])/, '\1')
99
+ end
100
+
101
+ def expand_newlines(value)
102
+ if (@hash["DOTENV_LINEBREAK_MODE"] || ENV["DOTENV_LINEBREAK_MODE"]) == "legacy"
103
+ value.gsub('\n', "\n").gsub('\r', "\r")
104
+ else
105
+ value.gsub('\n', "\\\\\\n").gsub('\r', "\\\\\\r")
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,10 @@
1
+ # If you use gems that require environment variables to be set before they are
2
+ # loaded, then list `dotenv` in the `Gemfile` before those other gems and
3
+ # require `dotenv/load`.
4
+ #
5
+ # gem "dotenv", require: "dotenv/load"
6
+ # gem "gem-that-requires-env-variables"
7
+ #
8
+
9
+ require "dotenv/load"
10
+ warn '[DEPRECATION] `require "dotenv/rails-now"` is deprecated. Use `require "dotenv/load"` instead.', caller(1..1).first
@@ -0,0 +1,111 @@
1
+ # Since rubygems doesn't support optional dependencies, we have to manually check
2
+ unless Gem::Requirement.new(">= 6.1").satisfied_by?(Gem::Version.new(Rails.version))
3
+ warn "dotenv 3.0 only supports Rails 6.1 or later. Use dotenv ~> 2.0."
4
+ return
5
+ end
6
+
7
+ require "dotenv/replay_logger"
8
+ require "dotenv/log_subscriber"
9
+
10
+ Dotenv.instrumenter = ActiveSupport::Notifications
11
+
12
+ # Watch all loaded env files with Spring
13
+ ActiveSupport::Notifications.subscribe("load.dotenv") do |*args|
14
+ if defined?(Spring) && Spring.respond_to?(:watch)
15
+ event = ActiveSupport::Notifications::Event.new(*args)
16
+ Spring.watch event.payload[:env].filename if Rails.application
17
+ end
18
+ end
19
+
20
+ module Dotenv
21
+ # Rails integration for using Dotenv to load ENV variables from a file
22
+ class Rails < ::Rails::Railtie
23
+ delegate :files, :files=, :overwrite, :overwrite=, :autorestore, :autorestore=, :logger, to: "config.dotenv"
24
+
25
+ def initialize
26
+ super
27
+ config.dotenv = ActiveSupport::OrderedOptions.new.update(
28
+ # Rails.logger is not available yet, so we'll save log messages and replay them when it is
29
+ logger: Dotenv::ReplayLogger.new,
30
+ overwrite: false,
31
+ files: [
32
+ ".env.#{env}.local",
33
+ (".env.local" unless env.test?),
34
+ ".env.#{env}",
35
+ ".env"
36
+ ].compact,
37
+ autorestore: env.test? && !defined?(ClimateControl) && !defined?(IceAge)
38
+ )
39
+ end
40
+
41
+ # Public: Load dotenv
42
+ #
43
+ # This will get called during the `before_configuration` callback, but you
44
+ # can manually call `Dotenv::Rails.load` if you needed it sooner.
45
+ def load
46
+ Dotenv.load(*files.map { |file| root.join(file).to_s }, overwrite: overwrite)
47
+ end
48
+
49
+ def overload
50
+ deprecator.warn("Dotenv::Rails.overload is deprecated. Set `Dotenv::Rails.overwrite = true` and call Dotenv::Rails.load instead.")
51
+ Dotenv.load(*files.map { |file| root.join(file).to_s }, overwrite: true)
52
+ end
53
+
54
+ # Internal: `Rails.root` is nil in Rails 4.1 before the application is
55
+ # initialized, so this falls back to the `RAILS_ROOT` environment variable,
56
+ # or the current working directory.
57
+ def root
58
+ ::Rails.root || Pathname.new(ENV["RAILS_ROOT"] || Dir.pwd)
59
+ end
60
+
61
+ # Set a new logger and replay logs
62
+ def logger=(new_logger)
63
+ logger.replay new_logger if logger.is_a?(ReplayLogger)
64
+ config.dotenv.logger = new_logger
65
+ end
66
+
67
+ # The current environment that the app is running in.
68
+ #
69
+ # When running `rake`, the Rails application is initialized in development, so we have to
70
+ # check which rake tasks are being run to determine the environment.
71
+ #
72
+ # See https://github.com/bkeepers/dotenv/issues/219
73
+ def env
74
+ @env ||= if defined?(Rake.application) && Rake.application.top_level_tasks.grep(TEST_RAKE_TASKS).any?
75
+ env = Rake.application.options.show_tasks ? "development" : "test"
76
+ ActiveSupport::EnvironmentInquirer.new(env)
77
+ else
78
+ ::Rails.env
79
+ end
80
+ end
81
+ TEST_RAKE_TASKS = /^(default$|test(:|$)|parallel:spec|spec(:|$))/
82
+
83
+ def deprecator # :nodoc:
84
+ @deprecator ||= ActiveSupport::Deprecation.new
85
+ end
86
+
87
+ # Rails uses `#method_missing` to delegate all class methods to the
88
+ # instance, which means `Kernel#load` gets called here. We don't want that.
89
+ def self.load
90
+ instance.load
91
+ end
92
+
93
+ initializer "dotenv", after: :initialize_logger do |app|
94
+ if logger.is_a?(ReplayLogger)
95
+ self.logger = ActiveSupport::TaggedLogging.new(::Rails.logger).tagged("dotenv")
96
+ end
97
+ end
98
+
99
+ initializer "dotenv.deprecator" do |app|
100
+ app.deprecators[:dotenv] = deprecator if app.respond_to?(:deprecators)
101
+ end
102
+
103
+ initializer "dotenv.autorestore" do |app|
104
+ require "dotenv/autorestore" if autorestore
105
+ end
106
+
107
+ config.before_configuration { load }
108
+ end
109
+
110
+ Railtie = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("Dotenv::Railtie", "Dotenv::Rails", Dotenv::Rails.deprecator)
111
+ end
@@ -0,0 +1,20 @@
1
+ module Dotenv
2
+ # A logger that can be used before the apps real logger is initialized.
3
+ class ReplayLogger < Logger
4
+ def initialize
5
+ super(nil) # Doesn't matter what this is, it won't be used.
6
+ @logs = []
7
+ end
8
+
9
+ # Override the add method to store logs so we can replay them to a real logger later.
10
+ def add(*args, &block)
11
+ @logs.push([args, block])
12
+ end
13
+
14
+ # Replay the store logs to a real logger.
15
+ def replay(logger)
16
+ @logs.each { |args, block| logger.add(*args, &block) }
17
+ @logs.clear
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ require "English"
2
+
3
+ module Dotenv
4
+ module Substitutions
5
+ # Substitute shell commands in a value.
6
+ #
7
+ # SHA=$(git rev-parse HEAD)
8
+ #
9
+ module Command
10
+ class << self
11
+ INTERPOLATED_SHELL_COMMAND = /
12
+ (?<backslash>\\)? # is it escaped with a backslash?
13
+ \$ # literal $
14
+ (?<cmd> # collect command content for eval
15
+ \( # require opening paren
16
+ (?:[^()]|\g<cmd>)+ # allow any number of non-parens, or balanced
17
+ # parens (by nesting the <cmd> expression
18
+ # recursively)
19
+ \) # require closing paren
20
+ )
21
+ /x
22
+
23
+ def call(value, env)
24
+ # Process interpolated shell commands
25
+ value.gsub(INTERPOLATED_SHELL_COMMAND) do |*|
26
+ # Eliminate opening and closing parentheses
27
+ command = $LAST_MATCH_INFO[:cmd][1..-2]
28
+
29
+ if $LAST_MATCH_INFO[:backslash]
30
+ # Command is escaped, don't replace it.
31
+ $LAST_MATCH_INFO[0][1..]
32
+ else
33
+ # Execute the command and return the value
34
+ `#{Variable.call(command, env)}`.chomp
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ require "English"
2
+
3
+ module Dotenv
4
+ module Substitutions
5
+ # Substitute variables in a value.
6
+ #
7
+ # HOST=example.com
8
+ # URL="https://$HOST"
9
+ #
10
+ module Variable
11
+ class << self
12
+ VARIABLE = /
13
+ (\\)? # is it escaped with a backslash?
14
+ (\$) # literal $
15
+ (?!\() # shouldn't be followed by parenthesis
16
+ \{? # allow brace wrapping
17
+ ([A-Z0-9_]+)? # optional alpha nums
18
+ \}? # closing brace
19
+ /xi
20
+
21
+ def call(value, env)
22
+ value.gsub(VARIABLE) do |variable|
23
+ match = $LAST_MATCH_INFO
24
+
25
+ if match[1] == "\\"
26
+ variable[1..]
27
+ elsif match[3]
28
+ env[match[3]] || ENV[match[3]] || ""
29
+ else
30
+ variable
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ desc "Load environment settings from .env"
2
+ task :dotenv do
3
+ require "dotenv"
4
+ Dotenv.load
5
+ end
6
+
7
+ task environment: :dotenv
@@ -0,0 +1,44 @@
1
+ module Dotenv
2
+ EXPORT_COMMAND = "export ".freeze
3
+ # Class for creating a template from a env file
4
+ class EnvTemplate
5
+ def initialize(env_file)
6
+ @env_file = env_file
7
+ end
8
+
9
+ def create_template
10
+ File.open(@env_file, "r") do |env_file|
11
+ File.open("#{@env_file}.template", "w") do |env_template|
12
+ env_file.each do |line|
13
+ if is_comment?(line)
14
+ env_template.puts line
15
+ elsif (var = var_defined?(line))
16
+ if line.match(EXPORT_COMMAND)
17
+ env_template.puts "export #{var}=#{var}"
18
+ else
19
+ env_template.puts "#{var}=#{var}"
20
+ end
21
+ elsif line_blank?(line)
22
+ env_template.puts
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def is_comment?(line)
32
+ line.strip.start_with?("#")
33
+ end
34
+
35
+ def var_defined?(line)
36
+ match = Dotenv::Parser::LINE.match(line)
37
+ match && match[:key]
38
+ end
39
+
40
+ def line_blank?(line)
41
+ line.strip.length.zero?
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Dotenv
2
+ VERSION = "3.2.0".freeze
3
+ end