piotrmurach/tty-link

View on GitHub
lib/tty/link/terminals/abstract.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

require_relative "../errors"

module TTY
  class Link
    module Terminals
      # Responsible for providing common terminal detection
      #
      # @abstract Override {#name?} and {#version?} to implement
      #           terminal hyperlinks detection
      #
      # @api private
      class Abstract
        # The term environment variable name
        #
        # @return [String]
        #
        # @api private
        TERM = "TERM"
        private_constant :TERM

        # The term program environment variable name
        #
        # @return [String]
        #
        # @api private
        TERM_PROGRAM = "TERM_PROGRAM"
        private_constant :TERM_PROGRAM

        # The term program version environment variable name
        #
        # @return [String]
        #
        # @api private
        TERM_PROGRAM_VERSION = "TERM_PROGRAM_VERSION"
        private_constant :TERM_PROGRAM_VERSION

        # Register a terminal class with terminals
        #
        # @param [TTY::Link::Terminal::Abstract] terminal_class
        #   the terminal class to register
        #
        # @return [void]
        #
        # @api private
        def self.inherited(terminal_class)
          super
          Terminals.register(terminal_class)
        end
        private_class_method :inherited

        # Create an {TTY::Link::Terminals::Abstract} instance
        #
        # @example
        #   terminal = TTY::Link::Terminals::Abstract.new(SemanticVersion, ENV)
        #
        # @param [TTY::Link::SemanticVersion] semantic_version
        #   the semantic version creator
        # @param [ENV, Hash{String => String}] env
        #   the environment variables
        #
        # @api public
        def initialize(semantic_version, env)
          @semantic_version = semantic_version
          @env = env
        end

        # Detect a terminal hyperlink support
        #
        # @example
        #   terminal.link?
        #   # => true
        #
        # @return [Boolean]
        #
        # @api public
        def link?
          name? && version?
        end

        protected

        # Detect a terminal name
        #
        # @example
        #   terminal.name?
        #
        # @raise [TTY::Link::AbstractMethodError]
        #   the class doesn't implement the name? method
        #
        # @abstract
        #
        # @api private
        def name?
          raise AbstractMethodError.new(self.class.name, __method__)
        end

        # Detect whether a terminal version supports terminal hyperlinks
        #
        # @example
        #   terminal.version?
        #
        # @raise [TTY::Link::AbstractMethodError]
        #   the class doesn't implement the version? method
        #
        # @abstract
        #
        # @api private
        def version?
          raise AbstractMethodError.new(self.class.name, __method__)
        end

        # The environment variables
        #
        # @example
        #   terminal.env
        #
        # @return [ENV, Hash{String => String}]
        #
        # @api private
        attr_reader :env

        # Create a {TTY::Link::SemanticVersion} instance from a version value
        #
        # @example
        #   terminal.semantic_version(1, 2, 3)
        #
        # @example
        #   terminal.semantic_version("1.2.3")
        #
        # @param [Array<Integer, String>] version
        #   the version to convert to a semantic version
        # @param [Hash{Symbol => String}] options
        #   the options to convert to a semantic version
        # @option options [String] :separator
        #   the version separator
        #
        # @return [TTY::Link::SemanticVersion]
        #
        # @see SemanticVersion#from
        #
        # @api private
        def semantic_version(*version, **options)
          @semantic_version.from(*version, **options)
        end

        # Read the term environment variable
        #
        # @example
        #   terminal.term
        #   # => "alacritty"
        #
        # @return [String, nil]
        #
        # @api private
        def term
          env[TERM]
        end

        # Read the term program environment variable
        #
        # @example
        #   terminal.term_program
        #   # => "iTerm.app"
        #
        # @return [String, nil]
        #
        # @api private
        def term_program
          env[TERM_PROGRAM]
        end

        # Read the term program version environment variable
        #
        # @example
        #   terminal.term_program_version
        #   # => "1.2.3"
        #
        # @return [String, nil]
        #
        # @api private
        def term_program_version
          env[TERM_PROGRAM_VERSION]
        end
      end # Abstract
    end # Terminals
  end # Link
end # TTY