class Tweezer::Gemfile

Attributes

ast[R]
comments[R]

Public Class Methods

load(file = Bundler.default_gemfile) click to toggle source
# File lib/tweezer/gemfile.rb, line 16
def self.load(file = Bundler.default_gemfile)
  new(File.read(file), file)
end
new(source, file = nil) click to toggle source
# File lib/tweezer/gemfile.rb, line 9
def initialize(source, file = nil)
  @ast, @comments = Parser::CurrentRuby.parse_with_comments(source, file)
  @file = file

  load_nodes!(@ast.children)
end

Public Instance Methods

add_gem(*args) click to toggle source

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength

# File lib/tweezer/gemfile.rb, line 36
def add_gem(*args)
  gem = Gem.new(*args)
  fail GemAlreadyPresent if gems.include? gem
  gems << gem

  if groups.include?(gem.groups)
    gem_groups = gem.groups
    gem.groups = []

    if groups[gem_groups].size == 1
      gem_to_group_block!(groups[gem_groups].first)
    end

    append_to_group_block! gem.to_node, groups: gem_groups
  else
    groups[gem.groups] = [gem] unless gem.groups.empty?
    append_before_first_block! gem.to_node
  end
end
alter_gem(name, **options) click to toggle source

rubocop:enable Metrics/MethodLength rubocop:enable Metrics/AbcSize

# File lib/tweezer/gemfile.rb, line 58
def alter_gem(name, **options)
  gem = gems.find { |g| g.name == name } || fail(GemNotPresent)
  old_node = gem.to_node
  gem.alter!(options)
  replace_gem!(old_node, gem.to_node)
end
dump() click to toggle source
# File lib/tweezer/gemfile.rb, line 65
def dump
  dumped = Unparser.unparse(ast, comments).dup
  dumped << "\n" unless dumped[-1] == "\n"
  dumped
end
gems() click to toggle source
# File lib/tweezer/gemfile.rb, line 25
def gems
  @gems ||= []
end
groups() click to toggle source

Maps arrays of groups to arrays of Gems

# File lib/tweezer/gemfile.rb, line 30
def groups
  @groups ||= Hash.new { |h, k| h[k] = [] }
end
save!() click to toggle source
# File lib/tweezer/gemfile.rb, line 20
def save!
  fail unless @file
  File.write(@file, dump)
end

Private Instance Methods

append_before_first_block!(new_node) click to toggle source
# File lib/tweezer/gemfile.rb, line 96
def append_before_first_block!(new_node)
  appended = false
  nodes = ast.children.flat_map do |node|
    if block?(node) && !appended
      appended = true
      next [new_node, blank_line, node, blank_line]
    end

    [node]
  end
  nodes << new_node unless nodes.include? new_node

  @ast = @ast.updated(nil, nodes)
end
append_to_group_block!(new_node, groups: []) click to toggle source
# File lib/tweezer/gemfile.rb, line 111
def append_to_group_block!(new_node, groups: [])
  nodes = ast.children.map do |node|
    if group_block?(node) && groups_from_group_block(node) == groups
      append_block_child(node, new_node)
    else
      node
    end
  end

  @ast = @ast.updated(nil, nodes)
end
gem_to_group_block!(gem) click to toggle source
# File lib/tweezer/gemfile.rb, line 128
def gem_to_group_block!(gem)
  nodes = ast.children.flat_map do |node|
    next [node] unless node == gem.to_node

    gem_groups = gem.groups
    gem.groups = []

    [blank_line, group_block(gem_groups, gem), blank_line]
  end

  @ast = @ast.updated(nil, nodes)
end
group_block(groups, *gems) click to toggle source
# File lib/tweezer/gemfile.rb, line 141
def group_block(groups, *gems)
  s(:block,
    s(:send, nil, :group,
      *(groups.map { |group| s(:sym, group) })),
    s(:args),
    *gems.map(&:to_node))
end
load_block_node!(node) click to toggle source
# File lib/tweezer/gemfile.rb, line 89
def load_block_node!(node)
  fail ArgumentError unless block?(node)
  gems = load_nodes!(block_children(node))
  groups[groups_from_group_block(node)].concat(gems) if group_block?(node)
  nil
end
load_node!(node) click to toggle source
# File lib/tweezer/gemfile.rb, line 79
def load_node!(node)
  return load_block_node!(node) if block? node
  return unless Gem.gem_node?(node)

  gem = Gem.new(node)
  gems << gem
  groups[gem.groups] << gem unless gem.groups.empty?
  gem
end
load_nodes!(nodes) click to toggle source
# File lib/tweezer/gemfile.rb, line 75
def load_nodes!(nodes)
  nodes.map { |node| load_node! node }.compact
end
replace_gem!(old_node, new_node) click to toggle source
# File lib/tweezer/gemfile.rb, line 123
def replace_gem!(old_node, new_node)
  nodes = ast.children.map { |node| node == old_node ? new_node : node }
  @ast = @ast.updated(nil, nodes)
end