Class: StackOperations::MkStack

Inherits:
MkTree
  • Object
show all
Defined in:
lib/mk_stack/mk_stack.rb

Instance Method Summary collapse

Methods inherited from MkTree

#mk_dir_tree, #print_tree

Constructor Details

#initialize(options, args) ⇒ MkStack

Returns a new instance of MkStack.



75
76
77
78
79
# File 'lib/mk_stack/mk_stack.rb', line 75

def initialize(options, args)
  @options = options
  @root_name = args[0]
  @date = args[1] || Date.today.strftime('%y%m%d')
end

Instance Method Details

#ensure_root_nameObject



131
132
133
134
135
136
# File 'lib/mk_stack/mk_stack.rb', line 131

def ensure_root_name
  if @root_name.nil? || @root_name.empty?
    max_num = find_max_ordinal
    @root_name = max_num > 0 ? "#{max_num}th" : "1st"
  end
end

#find_max_ordinalObject



126
127
128
129
130
# File 'lib/mk_stack/mk_stack.rb', line 126

def find_max_ordinal
  candidates = Dir.glob("_stack_*_*").select { |d| d =~ /^_stack_(\d+)(st|nd|rd|th)_(\d{6})$/ }
  ordinals = candidates.map { |d| d[/^_stack_(\d+)/, 1].to_i }.compact
  ordinals.any? ? ordinals.max : 0
end

#next_available_dir(root_name, date) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/mk_stack/mk_stack.rb', line 100

def next_available_dir(root_name, date)
  n = 1
  if root_name =~ /^(\d+)(st|nd|rd|th)$/
    n = $1.to_i
  elsif root_name =~ /^(\d+)(st|nd|rd|th)_(.+)$/
    n = $1.to_i
  end

  candidates = Dir.glob("_stack_*_*").select do |d|
    d =~ /^_stack_(\d+)(st|nd|rd|th)_(\d{6})$/
  end
  if candidates.any?
    ordinals = candidates.map do |d|
      if d =~ /^_stack_(\d+)(st|nd|rd|th)_(\d{6})$/
        $1.to_i
      else
        nil
      end
    end.compact
    n = ordinals.max + 1
  end

  base_name = ordinal(n)
  dir = "_stack_#{base_name}_#{date}"
  [base_name, dir]
end

#ordinal(n) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/mk_stack/mk_stack.rb', line 80

def ordinal(n)
  abs_n = n.to_i.abs
  if (11..13).include?(abs_n % 100)
    "#{n}th"
  else
    case abs_n % 10
    when 1; "#{n}st"
    when 2; "#{n}nd"
    when 3; "#{n}rd"
    else    "#{n}th"
    end
  end
end

#pull_root_name(dir_name) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/mk_stack/mk_stack.rb', line 93

def pull_root_name(dir_name)
  if dir_name =~ /^_stack_(.+)_(\d{6})$/
    $1
  else
    dir_name
  end
end

#runObject



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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/mk_stack/mk_stack.rb', line 137

def run
  ensure_root_name
  @root_name, dir = next_available_dir(@root_name, @date)

  # 1. 現在のツリーを取得
  current_tree = mk_dir_tree(".", 1, 1)

  # 2. 移動対象の決定
  exclude = ['.', '..', dir, '.vscode', 'project.code-workspace', '.git']
  all_entries = Dir.glob('*', File::FNM_DOTMATCH) - exclude
  moved_entries = []
  
  unless @options[:empty]
    all_entries.each do |entry|
      next if @options[:no_dir_move] && File.directory?(entry)
      moved_entries << entry
    end
  end

  # 3. 仮想ツリーの構築 (Hashの操作としてmvをシミュレート)
  virtual_tree = {}
  current_tree.each do |k, v|
    virtual_tree[k] = v unless moved_entries.include?(k)
  end
  
  moved_tree = {}
  moved_entries.each do |entry|
    moved_tree[entry] = current_tree[entry]
  end
  virtual_tree[dir] = moved_tree
  virtual_tree = virtual_tree.sort.to_h

  # 4. Before表示
  puts "Before stack:"
  puts "."
  print_tree(current_tree)

  # 5. 操作の表示 (Dry Run or Execute)
  puts "\nOperations:"
  prefix = @options[:dryrun] ? "[Dry Run] " : ""
  puts "#{prefix}mkdir #{dir}"
  if moved_entries.empty?
    puts "#{prefix}mv nothing (to) #{dir}"
  else
    moved_entries.each do |entry|
      puts "#{prefix}mv #{entry} (to) #{dir}"
    end
  end

  # 6. After表示
  puts "\nAfter stack:"
  puts "."
  print_tree(virtual_tree)

  # 7. 実行 (-e 指定時)
  unless @options[:dryrun]
    Dir.mkdir(dir) unless Dir.exist?(dir)
    moved_entries.each do |entry|
      FileUtils.mv(entry, dir)
    end
    puts "\nExecution completed."
  end
end