Class: HybridPlatformsConductor::PlatformHandler

Inherits:
Plugin
  • Object
show all
Includes:
Comparable
Defined in:
lib/hybrid_platforms_conductor/platform_handler.rb

Overview

Common ancestor to any platform handler

Constant Summary

Constants included from LoggerHelpers

LoggerHelpers::LEVELS_MODIFIERS, LoggerHelpers::LEVELS_TO_STDERR

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Plugin

extend_config_dsl_with, valid?

Methods included from LoggerHelpers

#err, #init_loggers, #log_component=, #log_debug?, #log_level=, #out, #section, #set_loggers_format, #stderr_device, #stderr_device=, #stderr_displayed?, #stdout_device, #stdout_device=, #stdout_displayed?, #stdouts_to_s, #with_progress_bar

Constructor Details

#initialize(platform_type, repository_path, logger: Logger.new($stdout), logger_stderr: Logger.new($stderr), config: Config.new, cmd_runner: CmdRunner.new, name: nil) ⇒ PlatformHandler

Constructor

Parameters
  • platform_type (Symbol): Platform type

  • repository_path (String): Repository path

  • logger (Logger): Logger to be used [default: Logger.new(STDOUT)]

  • logger_stderr (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]

  • config (Config): Config to be used. [default: Config.new]

  • cmd_runner (CmdRunner): Command executor to be used. [default: CmdRunner.new]

  • name (String or nil): Platform name, or nil for defaults (based on path or git remote) [default: nil]



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 72

def initialize(
  platform_type,
  repository_path,
  logger: Logger.new($stdout),
  logger_stderr: Logger.new($stderr),
  config: Config.new,
  cmd_runner: CmdRunner.new,
  name: nil
)
  super(logger: logger, logger_stderr: logger_stderr, config: config)
  @platform_type = platform_type
  @repository_path = repository_path
  @cmd_runner = cmd_runner
  @name = name
  init if respond_to?(:init)
end

Instance Attribute Details

#actions_executorObject

Before deploying, need to set some components in case the plugins need them



60
61
62
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 60

def actions_executor
  @actions_executor
end

#nodes_handlerObject

Before deploying, need to set some components in case the plugins need them



60
61
62
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 60

def nodes_handler
  @nodes_handler
end

#platform_typeObject (readonly)

Platform type

Symbol


57
58
59
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 57

def platform_type
  @platform_type
end

#repository_pathObject (readonly)

Repository path

String


53
54
55
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 53

def repository_path
  @repository_path
end

Class Method Details

.inherited(subclass) ⇒ Object

Callback called when a subclass inherits this class.

Parameters
  • subclass (Class): The inheriting class



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 16

def self.inherited(subclass)
  # Make sure we define automatically a helper for such a platform
  mixin = Module.new
  platform_type = subclass.name.split('::').last.gsub(/([a-z\d])([A-Z\d])/, '\1_\2').downcase.to_sym
  mixin.define_method("#{platform_type}_platform".to_sym) do |path: nil, git: nil, branch: 'master', name: nil, &platform_config_code|
    repository_path =
      if !path.nil?
        path
      elsif !git.nil?
        # Clone in a local repository
        local_repository_path = "#{@git_platforms_dir}/#{name.nil? ? File.basename(git)[0..-File.extname(git).size - 1] : name}"
        unless File.exist?(local_repository_path)
          branch = "refs/heads/#{branch}" unless branch.include?('/')
          local_ref = "refs/remotes/origin/#{branch.split('/').last}"
          section "Cloning #{git} (#{branch} => #{local_ref}) into #{local_repository_path}" do
            git_repo = Git.init(local_repository_path)
            git_repo.add_remote('origin', git).fetch(ref: "#{branch}:#{local_ref}")
            git_repo.checkout local_ref
          end
        end
        local_repository_path
      else
        raise 'The platform has to be defined with either a path or a git URL'
      end
    @platforms_info[platform_type] = {} unless @platforms_info.key?(platform_type)
    raise "Platform repository path #{repository_path} is declared several times." if @platforms_info.values.any? { |known_platforms_info| known_platforms_info.key?(repository_path) }

    @platforms_info[platform_type][repository_path] = name.nil? ? {} : { name: name }
    platform_config_code&.call(repository_path)
  end
  # Register this new mixin in the Config DSL
  extend_config_dsl_with(mixin)
  super
end

Instance Method Details

#<=>(other) ⇒ Object

Order relation

Parameters
  • other (Object): Other object to compare to

Result
  • Integer: -1, 0, or +1 depending on whether the receiver is less than, equal to, or greater than the other object



188
189
190
191
192
193
194
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 188

def <=>(other)
  if other.is_a?(PlatformHandler)
    name <=> other.name
  else
    super
  end
end

#impacts_from(_files_diffs) ⇒ Object

Get the list of impacted nodes and services from a files diff.

API
  • This is the default implementation, and is meant to be overriden by Platform Handlers.

Parameters
  • files_diffs (Hash< String, Hash< Symbol, Object > >): List of diffs info, per file name having a diff. Diffs info have the following properties:

    • moved_to (String): The new file path, in case it has been moved [optional]

    • diff (String): The diff content

Result
  • Array<String>: The list of nodes impacted by this diff

  • Array<String>: The list of services impacted by this diff

  • Boolean: Are there some files that have a global impact (meaning all nodes are potentially impacted by this diff)?



108
109
110
111
112
113
114
115
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 108

def impacts_from(_files_diffs)
  # By default, consider all nodes of the platform are impacted by whatever diff.
  [
    [],
    [],
    true
  ]
end

#infoObject

Get some information from this platform. This information identifies the code level that is currently checked out.

Result
  • Hash<Symbol,Object>: Description of this platform:

    • repo_name (String): The repository name

    • commit (Hash<Symbol,Object>): Information on the checked out Git commit

      • id (String): Commit ID

      • ref (String): Associated reference

      • message (String): Associated message

      • date (Time): Commit date in UTC

      • author (Hash<Symbol,Object>): Information on the author:

        • name (String): Name of the commit author

        • email (String): Email of the commit author

  • status (Hash<Symbol,Object>): Information on the checked out Git status

    • changed_files (Array<String>): List of changed files

    • added_files (Array<String>): List of added files

    • deleted_files (Array<String>): List of deleted files

    • untracked_files (Array<String>): List of untracked files



136
137
138
139
140
141
142
143
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
176
177
178
179
180
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 136

def info
  # Keep info in a memory cache, so that we don't query git for nothing
  unless defined?(@info)
    git = nil
    begin
      git = Git.open(@repository_path)
    rescue
      log_debug "Platform #{@repository_path} is not a git repository"
    end
    @info =
      if git
        git_status = git.status
        git_commit = git.log.first
        {
          repo_name:
            if @name.nil?
              git.remotes.empty? ? File.basename(@repository_path) : File.basename(git.remotes.first.url).gsub(/\.git$/, '')
            else
              @name
            end,
          commit: {
            id: git_commit.sha,
            ref: git_commit.name,
            message: git_commit.message,
            date: git_commit.date.utc,
            author: {
              name: git_commit.author.name,
              email: git_commit.author.email
            }
          },
          status: {
            changed_files: git_status.changed.keys,
            added_files: git_status.added.keys,
            deleted_files: git_status.deleted.keys,
            untracked_files: git_status.untracked.keys
          }
        }
      else
        {
          repo_name: @name.nil? ? File.basename(@repository_path) : @name
        }
      end
  end
  @info
end

#nameObject

Return the name of the platform

Result
  • String: Name of the platform



93
94
95
# File 'lib/hybrid_platforms_conductor/platform_handler.rb', line 93

def name
  info[:repo_name]
end