command.rb 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. require "English"
  2. module Dotenv
  3. module Substitutions
  4. # Substitute shell commands in a value.
  5. #
  6. # SHA=$(git rev-parse HEAD)
  7. #
  8. module Command
  9. class << self
  10. INTERPOLATED_SHELL_COMMAND = /
  11. (?<backslash>\\)? # is it escaped with a backslash?
  12. \$ # literal $
  13. (?<cmd> # collect command content for eval
  14. \( # require opening paren
  15. (?:[^()]|\g<cmd>)+ # allow any number of non-parens, or balanced
  16. # parens (by nesting the <cmd> expression
  17. # recursively)
  18. \) # require closing paren
  19. )
  20. /x
  21. def call(value, _env, overwrite: false)
  22. # Process interpolated shell commands
  23. value.gsub(INTERPOLATED_SHELL_COMMAND) do |*|
  24. # Eliminate opening and closing parentheses
  25. command = $LAST_MATCH_INFO[:cmd][1..-2]
  26. if $LAST_MATCH_INFO[:backslash]
  27. # Command is escaped, don't replace it.
  28. $LAST_MATCH_INFO[0][1..]
  29. else
  30. # Execute the command and return the value
  31. `#{command}`.chomp
  32. end
  33. end
  34. end
  35. end
  36. end
  37. end
  38. end