makit 0.0.99 → 0.0.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +41 -0
- data/exe/makit +5 -0
- data/lib/makit/apache.rb +7 -11
- data/lib/makit/cli/build_commands.rb +500 -0
- data/lib/makit/cli/generators/base_generator.rb +74 -0
- data/lib/makit/cli/generators/dotnet_generator.rb +50 -0
- data/lib/makit/cli/generators/generator_factory.rb +49 -0
- data/lib/makit/cli/generators/node_generator.rb +50 -0
- data/lib/makit/cli/generators/ruby_generator.rb +77 -0
- data/lib/makit/cli/generators/rust_generator.rb +50 -0
- data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -0
- data/lib/makit/cli/generators/templates/node_templates.rb +161 -0
- data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -0
- data/lib/makit/cli/generators/templates/ruby/gemspec.rb +40 -0
- data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -0
- data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -0
- data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -0
- data/lib/makit/cli/generators/templates/ruby/test.rb +39 -0
- data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -0
- data/lib/makit/cli/generators/templates/ruby/version.rb +29 -0
- data/lib/makit/cli/generators/templates/rust_templates.rb +128 -0
- data/lib/makit/cli/main.rb +48 -19
- data/lib/makit/cli/project_commands.rb +868 -0
- data/lib/makit/cli/repository_commands.rb +661 -0
- data/lib/makit/cli/utility_commands.rb +521 -0
- data/lib/makit/command_runner.rb +187 -128
- data/lib/makit/commands/compatibility.rb +365 -0
- data/lib/makit/commands/factory.rb +359 -0
- data/lib/makit/commands/middleware/base.rb +73 -0
- data/lib/makit/commands/middleware/cache.rb +248 -0
- data/lib/makit/commands/middleware/command_logger.rb +323 -0
- data/lib/makit/commands/middleware/unified_logger.rb +243 -0
- data/lib/makit/commands/middleware/validator.rb +269 -0
- data/lib/makit/commands/request.rb +254 -0
- data/lib/makit/commands/result.rb +323 -0
- data/lib/makit/commands/runner.rb +317 -0
- data/lib/makit/commands/strategies/base.rb +160 -0
- data/lib/makit/commands/strategies/synchronous.rb +134 -0
- data/lib/makit/commands.rb +24 -3
- data/lib/makit/configuration/gitlab_helper.rb +60 -0
- data/lib/makit/configuration/project.rb +127 -0
- data/lib/makit/configuration/rakefile_helper.rb +43 -0
- data/lib/makit/configuration/step.rb +34 -0
- data/lib/makit/configuration.rb +14 -0
- data/lib/makit/content/default_gitignore.rb +4 -2
- data/lib/makit/content/default_rakefile.rb +4 -2
- data/lib/makit/content/gem_rakefile.rb +4 -2
- data/lib/makit/context.rb +1 -0
- data/lib/makit/data.rb +9 -10
- data/lib/makit/directories.rb +48 -52
- data/lib/makit/directory.rb +38 -52
- data/lib/makit/docs/files.rb +5 -10
- data/lib/makit/docs/rake.rb +16 -20
- data/lib/makit/dotnet/cli.rb +65 -0
- data/lib/makit/dotnet/project.rb +153 -0
- data/lib/makit/dotnet/solution.rb +38 -0
- data/lib/makit/dotnet/solution_classlib.rb +239 -0
- data/lib/makit/dotnet/solution_console.rb +264 -0
- data/lib/makit/dotnet/solution_maui.rb +354 -0
- data/lib/makit/dotnet/solution_wasm.rb +275 -0
- data/lib/makit/dotnet/solution_wpf.rb +304 -0
- data/lib/makit/dotnet.rb +54 -171
- data/lib/makit/email.rb +46 -17
- data/lib/makit/environment.rb +22 -19
- data/lib/makit/examples/runner.rb +370 -0
- data/lib/makit/exceptions.rb +45 -0
- data/lib/makit/fileinfo.rb +3 -5
- data/lib/makit/files.rb +12 -16
- data/lib/makit/gems.rb +40 -39
- data/lib/makit/git/cli.rb +54 -0
- data/lib/makit/git/repository.rb +90 -0
- data/lib/makit/git.rb +44 -91
- data/lib/makit/gitlab_runner.rb +0 -1
- data/lib/makit/humanize.rb +31 -23
- data/lib/makit/indexer.rb +15 -24
- data/lib/makit/logging/configuration.rb +305 -0
- data/lib/makit/logging/format_registry.rb +84 -0
- data/lib/makit/logging/formatters/base.rb +39 -0
- data/lib/makit/logging/formatters/console_formatter.rb +127 -0
- data/lib/makit/logging/formatters/json_formatter.rb +65 -0
- data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -0
- data/lib/makit/logging/formatters/text_formatter.rb +64 -0
- data/lib/makit/logging/log_request.rb +115 -0
- data/lib/makit/logging/logger.rb +159 -0
- data/lib/makit/logging/sinks/base.rb +91 -0
- data/lib/makit/logging/sinks/console.rb +72 -0
- data/lib/makit/logging/sinks/file_sink.rb +92 -0
- data/lib/makit/logging/sinks/structured.rb +129 -0
- data/lib/makit/logging/sinks/unified_file_sink.rb +303 -0
- data/lib/makit/logging.rb +452 -37
- data/lib/makit/markdown.rb +18 -18
- data/lib/makit/mp/basic_object_mp.rb +5 -4
- data/lib/makit/mp/command_mp.rb +5 -5
- data/lib/makit/mp/command_request.mp.rb +3 -2
- data/lib/makit/mp/project_mp.rb +85 -96
- data/lib/makit/mp/string_mp.rb +245 -73
- data/lib/makit/nuget.rb +27 -25
- data/lib/makit/port.rb +25 -27
- data/lib/makit/process.rb +127 -29
- data/lib/makit/protoc.rb +27 -24
- data/lib/makit/rake/cli.rb +196 -0
- data/lib/makit/rake.rb +6 -6
- data/lib/makit/ruby/cli.rb +185 -0
- data/lib/makit/ruby.rb +25 -0
- data/lib/makit/secrets.rb +18 -18
- data/lib/makit/serializer.rb +29 -27
- data/lib/makit/services/builder.rb +186 -0
- data/lib/makit/services/error_handler.rb +226 -0
- data/lib/makit/services/repository_manager.rb +229 -0
- data/lib/makit/services/validator.rb +112 -0
- data/lib/makit/setup/classlib.rb +53 -0
- data/lib/makit/setup/gem.rb +250 -0
- data/lib/makit/setup/runner.rb +40 -0
- data/lib/makit/show.rb +16 -16
- data/lib/makit/storage.rb +32 -37
- data/lib/makit/symbols.rb +12 -0
- data/lib/makit/task_hooks.rb +125 -0
- data/lib/makit/task_info.rb +63 -21
- data/lib/makit/tasks/at_exit.rb +13 -0
- data/lib/makit/tasks/build.rb +18 -0
- data/lib/makit/tasks/clean.rb +11 -0
- data/lib/makit/tasks/hook_manager.rb +239 -0
- data/lib/makit/tasks/init.rb +47 -0
- data/lib/makit/tasks/integrate.rb +15 -0
- data/lib/makit/tasks/pull_incoming.rb +12 -0
- data/lib/makit/tasks/setup.rb +6 -0
- data/lib/makit/tasks/sync.rb +11 -0
- data/lib/makit/tasks/task_monkey_patch.rb +79 -0
- data/lib/makit/tasks.rb +5 -150
- data/lib/makit/test_cache.rb +239 -0
- data/lib/makit/v1/makit.v1_pb.rb +34 -35
- data/lib/makit/v1/makit.v1_services_pb.rb +2 -0
- data/lib/makit/version.rb +1 -57
- data/lib/makit/wix.rb +23 -23
- data/lib/makit/yaml.rb +18 -6
- data/lib/makit.rb +2 -261
- metadata +109 -145
- data/lib/makit/cli/clean.rb +0 -14
- data/lib/makit/cli/clone.rb +0 -59
- data/lib/makit/cli/init.rb +0 -38
- data/lib/makit/cli/make.rb +0 -54
- data/lib/makit/cli/new.rb +0 -37
- data/lib/makit/cli/nuget_cache.rb +0 -38
- data/lib/makit/cli/pull.rb +0 -31
- data/lib/makit/cli/setup.rb +0 -71
- data/lib/makit/cli/work.rb +0 -21
- data/lib/makit/content/default_gitignore.txt +0 -222
| @@ -0,0 +1,250 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            require_relative "../configuration/project"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Makit
         | 
| 5 | 
            +
              module Setup
         | 
| 6 | 
            +
                class Gem
         | 
| 7 | 
            +
                  def self.run
         | 
| 8 | 
            +
                    project = Makit::Configuration::Project.default
         | 
| 9 | 
            +
                    Makit::Logging.default_logger.info("Setting up Ruby gem project: #{project.name}")
         | 
| 10 | 
            +
                    
         | 
| 11 | 
            +
                    # Create basic gem structure
         | 
| 12 | 
            +
                    create_gem_structure(project)
         | 
| 13 | 
            +
                    
         | 
| 14 | 
            +
                    # Update build and test steps
         | 
| 15 | 
            +
                    update_build_step(project)
         | 
| 16 | 
            +
                    update_test_step(project)
         | 
| 17 | 
            +
                    
         | 
| 18 | 
            +
                    project.save
         | 
| 19 | 
            +
                    Makit::Logging.default_logger.info("Ruby gem project setup completed")
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  private
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def self.create_gem_structure(project)
         | 
| 25 | 
            +
                    # Create directories
         | 
| 26 | 
            +
                    FileUtils.mkdir_p("lib/#{project.name}")
         | 
| 27 | 
            +
                    FileUtils.mkdir_p("test")
         | 
| 28 | 
            +
                    FileUtils.mkdir_p("exe")
         | 
| 29 | 
            +
                    
         | 
| 30 | 
            +
                    # Create basic gem files
         | 
| 31 | 
            +
                    create_gemspec(project)
         | 
| 32 | 
            +
                    create_gemfile(project)
         | 
| 33 | 
            +
                    create_main_lib(project)
         | 
| 34 | 
            +
                    create_version_file(project)
         | 
| 35 | 
            +
                    create_rakefile(project)
         | 
| 36 | 
            +
                    create_test_helper(project)
         | 
| 37 | 
            +
                    create_test_file(project)
         | 
| 38 | 
            +
                    create_readme(project)
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def self.create_gemspec(project)
         | 
| 42 | 
            +
                    gemspec_content = <<~GEMSPEC
         | 
| 43 | 
            +
                      # frozen_string_literal: true
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      require_relative "lib/#{project.name}/version"
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      Gem::Specification.new do |spec|
         | 
| 48 | 
            +
                        spec.name = "#{project.name}"
         | 
| 49 | 
            +
                        spec.version = #{project.name.capitalize}::VERSION
         | 
| 50 | 
            +
                        spec.authors = ["Your Name"]
         | 
| 51 | 
            +
                        spec.email = ["your.email@example.com"]
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                        spec.summary = "A Ruby gem"
         | 
| 54 | 
            +
                        spec.description = "A Ruby gem description"
         | 
| 55 | 
            +
                        spec.homepage = "https://github.com/yourusername/#{project.name}"
         | 
| 56 | 
            +
                        spec.license = "MIT"
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                        spec.files = Dir["lib/**/*.rb", "exe/**/*", "README.md", "LICENSE.txt"]
         | 
| 59 | 
            +
                        spec.bindir = "exe"
         | 
| 60 | 
            +
                        spec.executables = []
         | 
| 61 | 
            +
                        spec.require_paths = ["lib"]
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                        spec.add_development_dependency "bundler", "~> 2.0"
         | 
| 64 | 
            +
                        spec.add_development_dependency "rake", "~> 13.0"
         | 
| 65 | 
            +
                        spec.add_development_dependency "minitest", "~> 5.0"
         | 
| 66 | 
            +
                      end
         | 
| 67 | 
            +
                    GEMSPEC
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    File.write("#{project.name}.gemspec", gemspec_content)
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  def self.create_gemfile(project)
         | 
| 73 | 
            +
                    gemfile_content = <<~GEMFILE
         | 
| 74 | 
            +
                      # frozen_string_literal: true
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      source "https://rubygems.org"
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      # Specify your gem's dependencies in #{project.name}.gemspec
         | 
| 79 | 
            +
                      gemspec
         | 
| 80 | 
            +
                    GEMFILE
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    File.write("Gemfile", gemfile_content)
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  def self.create_main_lib(project)
         | 
| 86 | 
            +
                    main_lib_content = <<~MAIN_LIB
         | 
| 87 | 
            +
                      # frozen_string_literal: true
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                      require_relative "#{project.name}/version"
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      module #{project.name.capitalize}
         | 
| 92 | 
            +
                        class Error < StandardError; end
         | 
| 93 | 
            +
                        # Your code goes here...
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    MAIN_LIB
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    File.write("lib/#{project.name}.rb", main_lib_content)
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  def self.create_version_file(project)
         | 
| 101 | 
            +
                    version_content = <<~VERSION
         | 
| 102 | 
            +
                      # frozen_string_literal: true
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                      module #{project.name.capitalize}
         | 
| 105 | 
            +
                        VERSION = "#{project.version}"
         | 
| 106 | 
            +
                      end
         | 
| 107 | 
            +
                    VERSION
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    File.write("lib/#{project.name}/version.rb", version_content)
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  def self.create_rakefile(project)
         | 
| 113 | 
            +
                    rakefile_content = <<~RAKEFILE
         | 
| 114 | 
            +
                      # frozen_string_literal: true
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                      require "bundler/gem_tasks"
         | 
| 117 | 
            +
                      require "minitest/test_task"
         | 
| 118 | 
            +
                      require "makit"
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                      Minitest::TestTask.create
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                      task :default => [:build, :install] do
         | 
| 123 | 
            +
                      end
         | 
| 124 | 
            +
                    RAKEFILE
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    File.write("Rakefile", rakefile_content)
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                  def self.create_test_helper(project)
         | 
| 130 | 
            +
                    test_helper_content = <<~TEST_HELPER
         | 
| 131 | 
            +
                      # frozen_string_literal: true
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                      require "minitest/autorun"
         | 
| 134 | 
            +
                      require_relative "../lib/#{project.name}"
         | 
| 135 | 
            +
                    TEST_HELPER
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    File.write("test/test_helper.rb", test_helper_content)
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                  def self.create_test_file(project)
         | 
| 141 | 
            +
                    test_content = <<~TEST
         | 
| 142 | 
            +
                      # frozen_string_literal: true
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                      require "test_helper"
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                      class #{project.name.capitalize}Test < Minitest::Test
         | 
| 147 | 
            +
                        def test_that_it_has_a_version_number
         | 
| 148 | 
            +
                          refute_nil ::#{project.name.capitalize}::VERSION
         | 
| 149 | 
            +
                        end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                        def test_it_does_something_useful
         | 
| 152 | 
            +
                          assert false
         | 
| 153 | 
            +
                        end
         | 
| 154 | 
            +
                      end
         | 
| 155 | 
            +
                    TEST
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                    File.write("test/#{project.name}_test.rb", test_content)
         | 
| 158 | 
            +
                  end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                  def self.create_readme(project)
         | 
| 161 | 
            +
                    readme_content = <<~README
         | 
| 162 | 
            +
                      # #{project.name.capitalize}
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                      Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/#{project.name}`. To experiment with that code, run `bin/console` for an interactive prompt.
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                      TODO: Delete this and the text above, and describe your gem
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                      ## Installation
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                      Add this line to your application's Gemfile:
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                      ```ruby
         | 
| 173 | 
            +
                      gem "#{project.name}"
         | 
| 174 | 
            +
                      ```
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                      And then execute:
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                          $ bundle
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                      Or install it yourself as:
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                          $ gem install #{project.name}
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                      ## Usage
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                      ```ruby
         | 
| 187 | 
            +
                      require "#{project.name}"
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                      # TODO: Write usage instructions here
         | 
| 190 | 
            +
                      ```
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                      ## Development
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                      After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests.
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                      ## Contributing
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                      Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/#{project.name}.
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                      ## License
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                      The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
         | 
| 203 | 
            +
                    README
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                    File.write("README.md", readme_content)
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  def self.update_build_step(project)
         | 
| 209 | 
            +
                    build_commands = [
         | 
| 210 | 
            +
                      "bundle exec rake build"
         | 
| 211 | 
            +
                    ]
         | 
| 212 | 
            +
                    
         | 
| 213 | 
            +
                    steps = project.steps
         | 
| 214 | 
            +
                    if steps.any? { |step| step.name == "build" }
         | 
| 215 | 
            +
                      build_step = steps.find { |step| step.name == "build" }
         | 
| 216 | 
            +
                      build_step.commands = build_commands
         | 
| 217 | 
            +
                    else
         | 
| 218 | 
            +
                      build_step = Makit::Configuration::Step.new(
         | 
| 219 | 
            +
                        name: "build", 
         | 
| 220 | 
            +
                        description: "Build the gem", 
         | 
| 221 | 
            +
                        commands: build_commands
         | 
| 222 | 
            +
                      )
         | 
| 223 | 
            +
                      project.add_step(build_step)
         | 
| 224 | 
            +
                    end
         | 
| 225 | 
            +
                    build_step.commands = build_commands
         | 
| 226 | 
            +
                    project.save
         | 
| 227 | 
            +
                  end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                  def self.update_test_step(project)
         | 
| 230 | 
            +
                    test_commands = [
         | 
| 231 | 
            +
                      "bundle exec rake test"
         | 
| 232 | 
            +
                    ]
         | 
| 233 | 
            +
                    
         | 
| 234 | 
            +
                    steps = project.steps
         | 
| 235 | 
            +
                    if steps.any? { |step| step.name == "test" }
         | 
| 236 | 
            +
                      test_step = steps.find { |step| step.name == "test" }
         | 
| 237 | 
            +
                      test_step.commands = test_commands
         | 
| 238 | 
            +
                    else
         | 
| 239 | 
            +
                      test_step = Makit::Configuration::Step.new(
         | 
| 240 | 
            +
                        name: "test", 
         | 
| 241 | 
            +
                        description: "Run the tests", 
         | 
| 242 | 
            +
                        commands: test_commands
         | 
| 243 | 
            +
                      )
         | 
| 244 | 
            +
                      project.add_step(test_step)
         | 
| 245 | 
            +
                    end
         | 
| 246 | 
            +
                    project.save
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
                end
         | 
| 249 | 
            +
              end
         | 
| 250 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            require_relative "classlib"
         | 
| 3 | 
            +
            require_relative "gem"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Makit
         | 
| 6 | 
            +
              module Setup
         | 
| 7 | 
            +
                class Runner
         | 
| 8 | 
            +
                  def self.run
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    # open .makit.json and get project type, to determine which setup to run
         | 
| 11 | 
            +
                    if File.exist?(".makit.json")
         | 
| 12 | 
            +
                      begin
         | 
| 13 | 
            +
                        project = Makit::Serializer.open(".makit.json", Makit::Configuration::Project)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                        # Check if the file contains compact JSON and resave as pretty JSON
         | 
| 16 | 
            +
                        current_content = File.read(".makit.json")
         | 
| 17 | 
            +
                        pretty_content = project.to_json_pretty
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                        # Only rewrite if the content is different (i.e., if it was compact)
         | 
| 20 | 
            +
                        if current_content.strip != pretty_content.strip
         | 
| 21 | 
            +
                          File.write(".makit.json", pretty_content)
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      rescue
         | 
| 24 | 
            +
                        raise "Error opening .makit.json"
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                      project_type = project.project_type
         | 
| 27 | 
            +
                      case project_type
         | 
| 28 | 
            +
                      when "classlib"
         | 
| 29 | 
            +
                        Makit::Setup::ClassLib.run
         | 
| 30 | 
            +
                      when "gem"
         | 
| 31 | 
            +
                        Makit::Setup::Gem.run
         | 
| 32 | 
            +
                      else
         | 
| 33 | 
            +
                        Makit::Logging.default_logger.warn("Unsupported project type: #{project_type}")
         | 
| 34 | 
            +
                        #puts "Unsupported project type: #{project_type}"
         | 
| 35 | 
            +
                      end
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
    
        data/lib/makit/show.rb
    CHANGED
    
    | @@ -8,9 +8,9 @@ module Makit | |
| 8 8 | 
             
              class Show
         | 
| 9 9 | 
             
                def modified(path)
         | 
| 10 10 | 
             
                  if File.file?(path)
         | 
| 11 | 
            -
                    puts "#{path} modified ".colorize(:grey) +  | 
| 11 | 
            +
                    puts "#{path} modified ".colorize(:grey) + Makit::Humanize.get_humanized_timestamp(File.mtime(path)).to_s.colorize(:cyan)
         | 
| 12 12 | 
             
                  elsif File.directory?(path)
         | 
| 13 | 
            -
                    puts "#{path} modified ".colorize(:grey) +  | 
| 13 | 
            +
                    puts "#{path} modified ".colorize(:grey) + Makit::Humanize.get_humanized_timestamp(Makit::Directory.modified(path)).to_s.colorize(:cyan)
         | 
| 14 14 | 
             
                  else
         | 
| 15 15 | 
             
                    puts "#{path} does not exist"
         | 
| 16 16 | 
             
                  end
         | 
| @@ -20,11 +20,11 @@ module Makit | |
| 20 20 | 
             
                  if File.file?(path)
         | 
| 21 21 | 
             
                    modified = File.mtime(path)
         | 
| 22 22 | 
             
                    age = (Time.now - modified).to_f
         | 
| 23 | 
            -
                    puts "#{path} age is ".colorize(:grey) +  | 
| 23 | 
            +
                    puts "#{path} age is ".colorize(:grey) + Makit::Humanize.get_humanized_duration(age).to_s.colorize(:cyan)
         | 
| 24 24 | 
             
                  elsif File.directory?(path)
         | 
| 25 25 | 
             
                    modified = Makit::Directory.modified(path)
         | 
| 26 | 
            -
                    age =  | 
| 27 | 
            -
                    puts "#{path} age is ".colorize(:grey) +  | 
| 26 | 
            +
                    age = Time.now(-modified).to_f
         | 
| 27 | 
            +
                    puts "#{path} age is ".colorize(:grey) + Makit::Humanize.get_humanized_duration(age).to_s.colorize(:cyan)
         | 
| 28 28 | 
             
                  else
         | 
| 29 29 | 
             
                    puts "#{path} does not exist"
         | 
| 30 30 | 
             
                  end
         | 
| @@ -33,9 +33,9 @@ module Makit | |
| 33 33 | 
             
                def file(path)
         | 
| 34 34 | 
             
                  if File.file?(path)
         | 
| 35 35 | 
             
                    modified = File.mtime(path)
         | 
| 36 | 
            -
                     | 
| 36 | 
            +
                    (Time.now - modified).to_f
         | 
| 37 37 | 
             
                    humanized_size = Makit::Humanize.get_humanized_size(File.size(path))
         | 
| 38 | 
            -
                    #puts "#{file_symbol} ".colorize(:grey) + "#{humanized_size.rjust(10)} ".colorize(:cyan) + " #{path} ".colorize(:grey)
         | 
| 38 | 
            +
                    # puts "#{file_symbol} ".colorize(:grey) + "#{humanized_size.rjust(10)} ".colorize(:cyan) + " #{path} ".colorize(:grey)
         | 
| 39 39 | 
             
                    puts "#{file_symbol} ".colorize(:grey) + "#{File.basename(path)} ".colorize(:green) + "#{humanized_size.rjust(10)} ".colorize(:cyan) + " #{path} ".colorize(:grey) # + "modified #{Makit::Humanize.get_humanized_timestamp(modified)}".colorize(:grey) + " age #{Makit::Humanize.get_humanized_duration(age)}".colorize(:grey)
         | 
| 40 40 | 
             
                  else
         | 
| 41 41 | 
             
                    puts "#{path} does not exist"
         | 
| @@ -49,8 +49,8 @@ module Makit | |
| 49 49 | 
             
                end
         | 
| 50 50 |  | 
| 51 51 | 
             
                def file_symbol
         | 
| 52 | 
            -
                   | 
| 53 | 
            -
                  #"\u{1F4C4}"
         | 
| 52 | 
            +
                  # 📄 (U+1F4C4) – "Page with Curl"
         | 
| 53 | 
            +
                  # "\u{1F4C4}"
         | 
| 54 54 | 
             
                  "@"
         | 
| 55 55 | 
             
                end
         | 
| 56 56 |  | 
| @@ -71,9 +71,9 @@ module Makit | |
| 71 71 |  | 
| 72 72 | 
             
                def size(path)
         | 
| 73 73 | 
             
                  if File.file?(path)
         | 
| 74 | 
            -
                    puts "#{path} size is ".colorize(:grey) +  | 
| 74 | 
            +
                    puts "#{path} size is ".colorize(:grey) + Makit::Humanize.get_humanized_size(File.size(path)).to_s.colorize(:cyan)
         | 
| 75 75 | 
             
                  elsif File.directory?(path)
         | 
| 76 | 
            -
                    puts "#{path} size is ".colorize(:grey) +  | 
| 76 | 
            +
                    puts "#{path} size is ".colorize(:grey) + Makit::Humanize.get_humanized_size(Makit::Directory.get_size(path)).to_s.colorize(:cyan)
         | 
| 77 77 | 
             
                  else
         | 
| 78 78 | 
             
                    puts "#{path} does not exist"
         | 
| 79 79 | 
             
                  end
         | 
| @@ -81,16 +81,16 @@ module Makit | |
| 81 81 |  | 
| 82 82 | 
             
                def task(task)
         | 
| 83 83 | 
             
                  puts ("=" * 80).colorize(:grey)
         | 
| 84 | 
            -
                  puts "  ".colorize(:grey) +  | 
| 85 | 
            -
                  #puts ("=" * 100).colorize(:grey)
         | 
| 84 | 
            +
                  puts "  ".colorize(:grey) + task.to_s.colorize(:green)
         | 
| 85 | 
            +
                  # puts ("=" * 100).colorize(:grey)
         | 
| 86 86 | 
             
                end
         | 
| 87 87 |  | 
| 88 88 | 
             
                def info(text)
         | 
| 89 | 
            -
                  puts "  ".colorize(:grey) +  | 
| 89 | 
            +
                  puts "  ".colorize(:grey) + text.to_s.colorize(:cyan)
         | 
| 90 90 | 
             
                end
         | 
| 91 91 |  | 
| 92 92 | 
             
                def success(text)
         | 
| 93 | 
            -
                  puts "  ".colorize(:grey) +  | 
| 93 | 
            +
                  puts "  ".colorize(:grey) + text.to_s.colorize(:green)
         | 
| 94 94 | 
             
                end
         | 
| 95 95 |  | 
| 96 96 | 
             
                def version(path)
         | 
| @@ -104,7 +104,7 @@ module Makit | |
| 104 104 | 
             
                end
         | 
| 105 105 |  | 
| 106 106 | 
             
                def git_branch
         | 
| 107 | 
            -
                  puts "#{git_branch_symbol} ".colorize(:grey) +  | 
| 107 | 
            +
                  puts "#{git_branch_symbol} ".colorize(:grey) + Makit::Git::Repository.branch.to_s.colorize(:green) + " branch".colorize(:grey)
         | 
| 108 108 | 
             
                end
         | 
| 109 109 | 
             
              end
         | 
| 110 110 | 
             
            end
         | 
    
        data/lib/makit/storage.rb
    CHANGED
    
    | @@ -7,18 +7,17 @@ module Makit | |
| 7 7 | 
             
              class Storage
         | 
| 8 8 | 
             
                # declare a private class variable, connection_string
         | 
| 9 9 | 
             
                attr_accessor :directory #= nil
         | 
| 10 | 
            -
                attr_accessor :protoc_json_serializer # = Makit::Serializer::new()
         | 
| 11 | 
            -
                attr_accessor :protoc_binary_serializer # = Makit::Serializer::new()
         | 
| 10 | 
            +
                attr_accessor :protoc_json_serializer, :protoc_binary_serializer # = Makit::Serializer::new() # = Makit::Serializer::new()
         | 
| 12 11 |  | 
| 13 12 | 
             
                def initialize(directory)
         | 
| 14 13 | 
             
                  @directory = directory
         | 
| 15 | 
            -
                  @protoc_json_serializer = Makit::Serializer | 
| 16 | 
            -
                  @protoc_binary_serializer = Makit::Serializer | 
| 14 | 
            +
                  @protoc_json_serializer = Makit::Serializer.new(Makit::Proto3Formats::JSON)
         | 
| 15 | 
            +
                  @protoc_binary_serializer = Makit::Serializer.new(Makit::Proto3Formats::BINARY)
         | 
| 17 16 | 
             
                end
         | 
| 18 17 |  | 
| 19 18 | 
             
                def save(object, key)
         | 
| 20 | 
            -
                  #puts "=" * 80
         | 
| 21 | 
            -
                  #puts "Saving object to storage"
         | 
| 19 | 
            +
                  # puts "=" * 80
         | 
| 20 | 
            +
                  # puts "Saving object to storage"
         | 
| 22 21 | 
             
                  # puts "=" * 80
         | 
| 23 22 | 
             
                  raise "directory is nil" if @directory.nil?
         | 
| 24 23 | 
             
                  raise "Object is nil" if object.nil?
         | 
| @@ -26,14 +25,14 @@ module Makit | |
| 26 25 |  | 
| 27 26 | 
             
                  # get the fully qualfied type name of the object
         | 
| 28 27 | 
             
                  type_name = object.class.to_s
         | 
| 29 | 
            -
                  #puts "Type name: #{type_name}"
         | 
| 28 | 
            +
                  # puts "Type name: #{type_name}"
         | 
| 30 29 |  | 
| 31 30 | 
             
                  type_rel_dir = type_name.downcase.gsub("::", "/")
         | 
| 32 | 
            -
                  #puts "Type relative directory: #{type_rel_dir}"
         | 
| 31 | 
            +
                  # puts "Type relative directory: #{type_rel_dir}"
         | 
| 33 32 |  | 
| 34 33 | 
             
                  # extract the file extension from the key
         | 
| 35 34 | 
             
                  file_extension = File.extname(key)
         | 
| 36 | 
            -
                  #puts "File extension: #{file_extension}"
         | 
| 35 | 
            +
                  # puts "File extension: #{file_extension}"
         | 
| 37 36 |  | 
| 38 37 | 
             
                  serializer = nil
         | 
| 39 38 | 
             
                  if file_extension == ".json"
         | 
| @@ -44,22 +43,20 @@ module Makit | |
| 44 43 | 
             
                    raise "Unknown file extension: #{file_extension}"
         | 
| 45 44 | 
             
                  end
         | 
| 46 45 | 
             
                  bytes = serializer.serialize(object)
         | 
| 47 | 
            -
                  #puts "Serialized object size: #{bytes.size} bytes"
         | 
| 46 | 
            +
                  # puts "Serialized object size: #{bytes.size} bytes"
         | 
| 48 47 |  | 
| 49 | 
            -
                  rel_filename = File.join(type_rel_dir,  | 
| 50 | 
            -
                  #puts "Relative filename: #{rel_filename}"
         | 
| 48 | 
            +
                  rel_filename = File.join(type_rel_dir, key.to_s)
         | 
| 49 | 
            +
                  # puts "Relative filename: #{rel_filename}"
         | 
| 51 50 |  | 
| 52 51 | 
             
                  filename = File.join(@directory, rel_filename)
         | 
| 53 | 
            -
                  #puts "Saving object to file: #{filename}"
         | 
| 52 | 
            +
                  # puts "Saving object to file: #{filename}"
         | 
| 54 53 |  | 
| 55 54 | 
             
                  # make sure the file directory has been created
         | 
| 56 55 | 
             
                  FileUtils.mkdir_p(File.dirname(filename)) unless File.directory?(File.dirname(filename))
         | 
| 57 56 | 
             
                  # write the bytes to the file
         | 
| 58 | 
            -
                  File. | 
| 59 | 
            -
                    file.write(bytes)
         | 
| 60 | 
            -
                  end
         | 
| 57 | 
            +
                  File.binwrite(filename, bytes)
         | 
| 61 58 |  | 
| 62 | 
            -
                  #puts "=" * 80
         | 
| 59 | 
            +
                  # puts "=" * 80
         | 
| 63 60 | 
             
                end
         | 
| 64 61 |  | 
| 65 62 | 
             
                def load(type, key)
         | 
| @@ -68,31 +65,31 @@ module Makit | |
| 68 65 |  | 
| 69 66 | 
             
                  # get the fully qualfied type name of the object
         | 
| 70 67 | 
             
                  type_name = type.to_s # object.class.to_s
         | 
| 71 | 
            -
                  #puts "Type name: #{type_name}"
         | 
| 68 | 
            +
                  # puts "Type name: #{type_name}"
         | 
| 72 69 |  | 
| 73 70 | 
             
                  type_rel_dir = type_name.downcase.gsub("::", "/")
         | 
| 74 | 
            -
                  #puts "Type relative directory: #{type_rel_dir}"
         | 
| 71 | 
            +
                  # puts "Type relative directory: #{type_rel_dir}"
         | 
| 75 72 |  | 
| 76 73 | 
             
                  # extract the file extension from the key
         | 
| 77 | 
            -
                   | 
| 78 | 
            -
                  #puts "File extension: #{file_extension}"
         | 
| 74 | 
            +
                  File.extname(key)
         | 
| 75 | 
            +
                  # puts "File extension: #{file_extension}"
         | 
| 79 76 |  | 
| 80 | 
            -
                  rel_filename = File.join(type_rel_dir,  | 
| 81 | 
            -
                  #puts "Relative filename: #{rel_filename}"
         | 
| 77 | 
            +
                  rel_filename = File.join(type_rel_dir, key.to_s)
         | 
| 78 | 
            +
                  # puts "Relative filename: #{rel_filename}"
         | 
| 82 79 |  | 
| 83 80 | 
             
                  filename = File.join(@directory, rel_filename)
         | 
| 84 | 
            -
                  #puts "Loading object from file: #{filename}"
         | 
| 81 | 
            +
                  # puts "Loading object from file: #{filename}"
         | 
| 85 82 |  | 
| 86 83 | 
             
                  # make sure the file exists
         | 
| 87 84 | 
             
                  raise "File does not exist: #{filename}" unless File.exist?(filename)
         | 
| 88 85 |  | 
| 89 86 | 
             
                  # read the bytes from the file
         | 
| 90 87 | 
             
                  bytes = File.read(filename, mode: "rb")
         | 
| 91 | 
            -
                  #puts "Read object from file: #{filename}"
         | 
| 88 | 
            +
                  # puts "Read object from file: #{filename}"
         | 
| 92 89 |  | 
| 93 90 | 
             
                  # extract the file extension from the key
         | 
| 94 91 | 
             
                  file_extension = File.extname(key)
         | 
| 95 | 
            -
                  #puts "File extension: #{file_extension}"
         | 
| 92 | 
            +
                  # puts "File extension: #{file_extension}"
         | 
| 96 93 |  | 
| 97 94 | 
             
                  serializer = nil
         | 
| 98 95 | 
             
                  if file_extension == ".json"
         | 
| @@ -104,28 +101,26 @@ module Makit | |
| 104 101 | 
             
                  end
         | 
| 105 102 |  | 
| 106 103 | 
             
                  # deserialize the object
         | 
| 107 | 
            -
                   | 
| 108 | 
            -
                  #puts "Deserialized object size: #{bytes.size} bytes"
         | 
| 104 | 
            +
                  serializer.deserialize(type, bytes)
         | 
| 105 | 
            +
                  # puts "Deserialized object size: #{bytes.size} bytes"
         | 
| 109 106 |  | 
| 110 107 | 
             
                  # if the object type inherits from Google::Protobuf::AbstractMessage,
         | 
| 111 108 | 
             
                  # then serialize to protobuf json format
         | 
| 112 | 
            -
                  #if object.is_a? Google::Protobuf::MessageExts
         | 
| 109 | 
            +
                  # if object.is_a? Google::Protobuf::MessageExts
         | 
| 113 110 | 
             
                  #  puts "Serializing to protobuf json format"
         | 
| 114 111 | 
             
                  #  serialized_object = object.to_json
         | 
| 115 112 | 
             
                  #  pretty_json = JSON.pretty_generate(JSON.parse(serialized_object))
         | 
| 116 113 | 
             
                  #  puts pretty_json
         | 
| 117 | 
            -
                  #else
         | 
| 114 | 
            +
                  # else
         | 
| 118 115 | 
             
                  #  puts "Serializing to Marshal format"
         | 
| 119 116 | 
             
                  #  serialized_object = Marshal.dump(object)
         | 
| 120 | 
            -
                  #end
         | 
| 117 | 
            +
                  # end
         | 
| 121 118 | 
             
                  # serialize the object
         | 
| 122 | 
            -
                  #serialized_object = Marshal.dump(object)
         | 
| 119 | 
            +
                  # serialized_object = Marshal.dump(object)
         | 
| 123 120 |  | 
| 124 121 | 
             
                  # save the object to the storage
         | 
| 125 122 | 
             
                  # ...
         | 
| 126 | 
            -
                  #puts "=" * 80
         | 
| 127 | 
            -
             | 
| 128 | 
            -
                  object
         | 
| 123 | 
            +
                  # puts "=" * 80
         | 
| 129 124 | 
             
                end
         | 
| 130 | 
            -
              end | 
| 131 | 
            -
            end | 
| 125 | 
            +
              end
         | 
| 126 | 
            +
            end
         | 
    
        data/lib/makit/symbols.rb
    CHANGED
    
    | @@ -4,6 +4,11 @@ require "rainbow" | |
| 4 4 |  | 
| 5 5 | 
             
            # https://symbl.cc/en/unicode/table/
         | 
| 6 6 | 
             
            module Makit
         | 
| 7 | 
            +
              # Unicode symbol utilities with colorization
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              # This class provides a collection of Unicode symbols with appropriate
         | 
| 10 | 
            +
              # colors for use in terminal output. Symbols are provided for various
         | 
| 11 | 
            +
              # purposes including status indicators, directional arrows, and decorative elements.
         | 
| 7 12 | 
             
              class Symbols
         | 
| 8 13 | 
             
                def self.checkmark
         | 
| 9 14 | 
             
                  "\u2713"
         | 
| @@ -129,6 +134,13 @@ module Makit | |
| 129 134 | 
             
                  Rainbow("\u266B").yellow  # Beamed eighth notes
         | 
| 130 135 | 
             
                end
         | 
| 131 136 |  | 
| 137 | 
            +
                # Get appropriate symbol for log severity level
         | 
| 138 | 
            +
                #
         | 
| 139 | 
            +
                # Returns a colored Unicode symbol that matches the given log severity level.
         | 
| 140 | 
            +
                # Used primarily in log formatting to provide visual indicators.
         | 
| 141 | 
            +
                #
         | 
| 142 | 
            +
                # @param severity [String] The severity level (DEBUG, WARN, ERROR, FATAL)
         | 
| 143 | 
            +
                # @return [String] Colored Unicode symbol or space for unrecognized levels
         | 
| 132 144 | 
             
                def self.get_severity_symbol(severity)
         | 
| 133 145 | 
             
                  case severity
         | 
| 134 146 | 
             
                  when "DEBUG"
         | 
| @@ -0,0 +1,125 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "fileutils"
         | 
| 4 | 
            +
            require "rake"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Makit
         | 
| 7 | 
            +
              # Task hooks for automatic timing, logging, and lifecycle management
         | 
| 8 | 
            +
              # This provides optional instrumentation for Rake tasks
         | 
| 9 | 
            +
              class TaskHooks
         | 
| 10 | 
            +
                class << self
         | 
| 11 | 
            +
                  attr_reader :enabled, :task_stack, :performance_log
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def initialize!
         | 
| 14 | 
            +
                    @enabled = false # Start disabled - must be explicitly enabled
         | 
| 15 | 
            +
                    @task_stack = []
         | 
| 16 | 
            +
                    @performance_log = "artifacts/task_performance.log"
         | 
| 17 | 
            +
                    @hooks_installed = false
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def setup!
         | 
| 21 | 
            +
                    return if @hooks_installed
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    initialize! unless defined?(@enabled)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    Rake::Task.class_eval do
         | 
| 26 | 
            +
                      alias_method :makit_original_execute, :execute
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      def execute(args = nil)
         | 
| 29 | 
            +
                        if Makit::TaskHooks.enabled?
         | 
| 30 | 
            +
                          Makit::TaskHooks.before_execute(name, args)
         | 
| 31 | 
            +
                          result = makit_original_execute(args)
         | 
| 32 | 
            +
                          Makit::TaskHooks.after_execute(name, args, result)
         | 
| 33 | 
            +
                          result
         | 
| 34 | 
            +
                        else
         | 
| 35 | 
            +
                          makit_original_execute(args)
         | 
| 36 | 
            +
                        end
         | 
| 37 | 
            +
                      rescue StandardError => e
         | 
| 38 | 
            +
                        Makit::TaskHooks.on_error(name, args, e) if Makit::TaskHooks.enabled?
         | 
| 39 | 
            +
                        raise
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    @hooks_installed = true
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def enable!
         | 
| 47 | 
            +
                    initialize! unless defined?(@enabled)
         | 
| 48 | 
            +
                    @enabled = true
         | 
| 49 | 
            +
                    puts "🔧 Task timing enabled".colorize(:grey) if defined?(String.instance_method(:colorize))
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def disable!
         | 
| 53 | 
            +
                    @enabled = false
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def enabled?
         | 
| 57 | 
            +
                    @enabled == true
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def before_execute(name, _args)
         | 
| 61 | 
            +
                    return unless enabled?
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    @task_stack.push({
         | 
| 64 | 
            +
                                       name: name,
         | 
| 65 | 
            +
                                       start_time: Time.now,
         | 
| 66 | 
            +
                                       level: @task_stack.length,
         | 
| 67 | 
            +
                                     })
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  def after_execute(name, _args, _result)
         | 
| 71 | 
            +
                    return unless enabled?
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                    task_info = @task_stack.pop
         | 
| 74 | 
            +
                    return unless task_info && task_info[:name] == name
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                    duration = Time.now - task_info[:start_time]
         | 
| 77 | 
            +
                    log_task_performance(name, duration, task_info[:level]) if duration > 0.1
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  def on_error(name, _args, error)
         | 
| 81 | 
            +
                    return unless enabled?
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    task_info = @task_stack.pop
         | 
| 84 | 
            +
                    return unless task_info
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    duration = Time.now - task_info[:start_time]
         | 
| 87 | 
            +
                    log_task_failure(name, duration, error, task_info[:level])
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  def clear_performance_logs
         | 
| 91 | 
            +
                    FileUtils.rm_f(@performance_log)
         | 
| 92 | 
            +
                    FileUtils.rm_f("artifacts/task_failures.log")
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  private
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  def log_task_performance(name, duration, level)
         | 
| 98 | 
            +
                    return if ENV["CI"] == "true" && duration < 1.0
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                    FileUtils.mkdir_p("artifacts")
         | 
| 101 | 
            +
                    File.open(@performance_log, "a") do |f|
         | 
| 102 | 
            +
                      f.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")},#{name},#{duration.round(4)},#{level}"
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
                  rescue StandardError
         | 
| 105 | 
            +
                    # Silently fail performance logging to not interrupt tasks
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  def log_task_failure(name, duration, error, _level)
         | 
| 109 | 
            +
                    failure_log = "artifacts/task_failures.log"
         | 
| 110 | 
            +
                    FileUtils.mkdir_p("artifacts")
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                    File.open(failure_log, "a") do |f|
         | 
| 113 | 
            +
                      timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
         | 
| 114 | 
            +
                      message = error.message.gsub(",", ";")
         | 
| 115 | 
            +
                      f.puts "#{timestamp},#{name},#{duration.round(4)},#{error.class.name},#{message}"
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                  rescue StandardError
         | 
| 118 | 
            +
                    # Silently fail error logging
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                # Initialize when loaded
         | 
| 123 | 
            +
                initialize!
         | 
| 124 | 
            +
              end
         | 
| 125 | 
            +
            end
         |