squared 0.3.4 → 0.4.0
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/CHANGELOG.md +67 -2
- data/README.md +13 -2
- data/README.ruby.md +168 -88
- data/lib/squared/app.rb +1 -0
- data/lib/squared/common/base.rb +6 -1
- data/lib/squared/common/class.rb +1 -1
- data/lib/squared/common/format.rb +24 -12
- data/lib/squared/common/prompt.rb +2 -2
- data/lib/squared/common/shell.rb +52 -39
- data/lib/squared/common/utils.rb +54 -1
- data/lib/squared/config.rb +1 -1
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +16 -13
- data/lib/squared/workspace/project/base.rb +429 -123
- data/lib/squared/workspace/project/docker.rb +572 -0
- data/lib/squared/workspace/project/git.rb +405 -157
- data/lib/squared/workspace/project/node.rb +51 -51
- data/lib/squared/workspace/project/python.rb +115 -24
- data/lib/squared/workspace/project/ruby.rb +33 -34
- data/lib/squared/workspace/project.rb +7 -1
- data/lib/squared/workspace/repo.rb +9 -4
- data/lib/squared/workspace/series.rb +1 -1
- metadata +2 -1
| @@ -4,9 +4,11 @@ module Squared | |
| 4 4 | 
             
              module Workspace
         | 
| 5 5 | 
             
                module Project
         | 
| 6 6 | 
             
                  class Node < Git
         | 
| 7 | 
            +
                    include Prompt
         | 
| 8 | 
            +
             | 
| 7 9 | 
             
                    OPT_NPM = {
         | 
| 8 10 | 
             
                      common: %w[dry-run include-workspace-root workspaces=b? w|workspace=b].freeze,
         | 
| 9 | 
            -
                      install: %w[prefer-dedupe package-lock-only cpu= | 
| 11 | 
            +
                      install: %w[prefer-dedupe package-lock-only cpu=b libc=b os=b].freeze,
         | 
| 10 12 | 
             
                      install_base: %w[ignore-scripts install-links strict-peer-deps include=b omit=b install-strategy=b].freeze,
         | 
| 11 13 | 
             
                      install_no: %w[audit bin-links fund package-lock].freeze,
         | 
| 12 14 | 
             
                      install_as: %w[foreground-scripts g|global no-save save save-bundle save-dev E|save-exact save-optional
         | 
| @@ -37,15 +39,14 @@ module Squared | |
| 37 39 | 
             
                                       no-node-version-check no-progress non-interactive offline pnp prefer-offline prod
         | 
| 38 40 | 
             
                                       pure-lockfile skip-integrity-check strict-semver update-checksums cache-folder=p emoji=b?
         | 
| 39 41 | 
             
                                       global-folder=p https-proxy=q link-folder=p modules-folder=p mutex=q network-concurrency=i
         | 
| 40 | 
            -
                                       network-timeout=i preferred-cache-folder=p production= | 
| 41 | 
            -
             | 
| 42 | 
            -
                      update: %w[A|audit C|caret E|exact L|latest T|tilde P|pattern=q S|scope=e].freeze
         | 
| 42 | 
            +
                                       network-timeout=i preferred-cache-folder=p production=b? proxy=q otp=b registry=q].freeze,
         | 
| 43 | 
            +
                      update: %w[A|audit C|caret E|exact L|latest T|tilde P|pattern=q S|scope=b].freeze
         | 
| 43 44 | 
             
                    }.freeze
         | 
| 44 45 | 
             
                    OPT_BERRY = {
         | 
| 45 46 | 
             
                      install: %w[check-cache check-resolutions immutable immutable-cache inline-builds json refresh-lockfile
         | 
| 46 | 
            -
                                  mode= | 
| 47 | 
            -
                      update: %w[C|caret E|exact F|fixed interactive T|tilde R|recursive mode= | 
| 48 | 
            -
                      dedupe: %w[check json mode= | 
| 47 | 
            +
                                  mode=b].freeze,
         | 
| 48 | 
            +
                      update: %w[C|caret E|exact F|fixed interactive T|tilde R|recursive mode=b].freeze,
         | 
| 49 | 
            +
                      dedupe: %w[check json mode=b strategy=b].freeze,
         | 
| 49 50 | 
             
                      pack: %w[n|dry-run install-if-needed json o|out=p].freeze
         | 
| 50 51 | 
             
                    }.freeze
         | 
| 51 52 | 
             
                    private_constant :OPT_NPM, :OPT_PNPM, :OPT_YARN, :OPT_BERRY
         | 
| @@ -93,12 +94,13 @@ module Squared | |
| 93 94 | 
             
                    def initialize(*, **kwargs)
         | 
| 94 95 | 
             
                      super
         | 
| 95 96 | 
             
                      if @pass.include?(Node.ref)
         | 
| 96 | 
            -
                        initialize_ref | 
| 97 | 
            +
                        initialize_ref Node.ref
         | 
| 97 98 | 
             
                        initialize_logger(**kwargs)
         | 
| 98 99 | 
             
                      else
         | 
| 99 100 | 
             
                        initialize_build(Node.ref, prod: prod?, **kwargs)
         | 
| 100 101 | 
             
                        initialize_env(**kwargs)
         | 
| 101 102 | 
             
                      end
         | 
| 103 | 
            +
                      @buildtype = :run if script?
         | 
| 102 104 | 
             
                      @pm = {}
         | 
| 103 105 | 
             
                      @dependfile = basepath('package.json')
         | 
| 104 106 | 
             
                    end
         | 
| @@ -218,26 +220,25 @@ module Squared | |
| 218 220 | 
             
                      end
         | 
| 219 221 | 
             
                    end
         | 
| 220 222 |  | 
| 221 | 
            -
                    def copy(from: 'build', into: 'node_modules',  | 
| 223 | 
            +
                    def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, workspace: false,
         | 
| 222 224 | 
             
                             link: false, force: false, override: false, **kwargs)
         | 
| 223 | 
            -
                       | 
| 224 | 
            -
             | 
| 225 | 
            +
                      glob = kwargs[:include]
         | 
| 226 | 
            +
                      pass = kwargs[:exclude]
         | 
| 225 227 | 
             
                      if @copy && !override
         | 
| 226 | 
            -
                        return super  | 
| 228 | 
            +
                        return super unless @copy.is_a?(Hash)
         | 
| 227 229 |  | 
| 228 230 | 
             
                        from = @copy[:from] if @copy.key?(:from)
         | 
| 229 231 | 
             
                        into = @copy[:into] if @copy.key?(:into)
         | 
| 230 232 | 
             
                        workspace = @copy[:workspace] if @copy.key?(:workspace)
         | 
| 231 233 | 
             
                        link = @copy[:link] if @copy.key?(:link)
         | 
| 232 | 
            -
                        force = @copy[:force] if @copy.key?(: | 
| 233 | 
            -
                         | 
| 234 | 
            -
                         | 
| 235 | 
            -
                         | 
| 236 | 
            -
                         | 
| 237 | 
            -
                         | 
| 238 | 
            -
                       | 
| 239 | 
            -
                         | 
| 240 | 
            -
                        exclude = kwargs[:exclude]
         | 
| 234 | 
            +
                        force = @copy[:force] if @copy.key?(:force)
         | 
| 235 | 
            +
                        scope = @copy[:scope] if @copy.key?(:scope)
         | 
| 236 | 
            +
                        also = @copy[:also] if @copy.key?(:also)
         | 
| 237 | 
            +
                        create = @copy[:create] if @copy.key?(:create)
         | 
| 238 | 
            +
                        glob = @copy[:include] if @copy.key?(:include)
         | 
| 239 | 
            +
                        pass = @copy[:exclude] if @copy.key?(:exclude)
         | 
| 240 | 
            +
                      elsif @copy == false
         | 
| 241 | 
            +
                        return
         | 
| 241 242 | 
             
                      end
         | 
| 242 243 | 
             
                      items = []
         | 
| 243 244 | 
             
                      items << @workspace.home if build? && path != @workspace.home && @workspace.home?
         | 
| @@ -256,8 +257,6 @@ module Squared | |
| 256 257 | 
             
                          dest = @workspace.find(name: dir)&.path
         | 
| 257 258 | 
             
                          log.warn message("copy project :#{dir}", hint: 'not found') unless dest
         | 
| 258 259 | 
             
                        when Hash
         | 
| 259 | 
            -
                          glob = dir[:include]
         | 
| 260 | 
            -
                          exclude = dir[:exclude]
         | 
| 261 260 | 
             
                          from = dir[:from] if dir.key?(:from)
         | 
| 262 261 | 
             
                          into = dir[:into] if dir.key?(:into)
         | 
| 263 262 | 
             
                          scope = dir[:scope] if dir.key?(:scope)
         | 
| @@ -266,11 +265,13 @@ module Squared | |
| 266 265 | 
             
                          dest = dir[:target]
         | 
| 267 266 | 
             
                          create = dir[:create]
         | 
| 268 267 | 
             
                          workspace = dir[:workspace]
         | 
| 268 | 
            +
                          glob = dir[:include]
         | 
| 269 | 
            +
                          pass = dir[:exclude]
         | 
| 269 270 | 
             
                          dest = items.first unless dest && dest != true
         | 
| 270 271 | 
             
                        when Project::Base
         | 
| 271 272 | 
             
                          dest = dir.path
         | 
| 272 273 | 
             
                        else
         | 
| 273 | 
            -
                          raise_error | 
| 274 | 
            +
                          raise_error "copy given: #{dir}"
         | 
| 274 275 | 
             
                        end
         | 
| 275 276 | 
             
                        next unless from && dest&.directory?
         | 
| 276 277 |  | 
| @@ -305,7 +306,7 @@ module Squared | |
| 305 306 | 
             
                        target.each do |src, to|
         | 
| 306 307 | 
             
                          glob.each { |val| log.info "cp #{from.join(val)} #{to}" }
         | 
| 307 308 | 
             
                          begin
         | 
| 308 | 
            -
                            copy_dir(src, to, glob, create: create, link: link, force: force, pass:  | 
| 309 | 
            +
                            copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbose)
         | 
| 309 310 | 
             
                          rescue StandardError => e
         | 
| 310 311 | 
             
                            log.error e
         | 
| 311 312 | 
             
                            ret = on(:error, :copy, e)
         | 
| @@ -320,6 +321,7 @@ module Squared | |
| 320 321 | 
             
                      if @depend && !flag
         | 
| 321 322 | 
             
                        super
         | 
| 322 323 | 
             
                      elsif outdated?
         | 
| 324 | 
            +
                        workspace.rev_clear name
         | 
| 323 325 | 
             
                        return update if !flag && env('NODE_UPDATE')
         | 
| 324 326 |  | 
| 325 327 | 
             
                        if (yarn = dependtype(:yarn)) > 0
         | 
| @@ -387,7 +389,7 @@ module Squared | |
| 387 389 | 
             
                          ret = on(:error, :outdated, e)
         | 
| 388 390 | 
             
                          raise if exception && ret != true
         | 
| 389 391 | 
             
                        end
         | 
| 390 | 
            -
                        warn log_message(Logger::WARN, e) if warning?
         | 
| 392 | 
            +
                        warn log_message(Logger::WARN, e, pass: true) if warning?
         | 
| 391 393 | 
             
                        return
         | 
| 392 394 | 
             
                      else
         | 
| 393 395 | 
             
                        dep1 = json['dependencies'] || {}
         | 
| @@ -405,7 +407,7 @@ module Squared | |
| 405 407 |  | 
| 406 408 | 
             
                          latest = val['latest']
         | 
| 407 409 | 
             
                          ch = file[0]
         | 
| 408 | 
            -
                          if ch | 
| 410 | 
            +
                          if ch.match?(/[~^]/)
         | 
| 409 411 | 
             
                            file = file[1..-1]
         | 
| 410 412 | 
             
                          elsif inter && rev == :major
         | 
| 411 413 | 
             
                            major = true
         | 
| @@ -414,7 +416,7 @@ module Squared | |
| 414 416 | 
             
                            next
         | 
| 415 417 | 
             
                          end
         | 
| 416 418 | 
             
                          current = val['current'] || file
         | 
| 417 | 
            -
                          want = rev == :major &&  | 
| 419 | 
            +
                          want = rev == :major && !latest[SEM_VER, 6] ? latest : val['wanted']
         | 
| 418 420 | 
             
                          next unless (current != want || file != want) && (want.match?(SEM_VER) || !file.match?(SEM_VER))
         | 
| 419 421 |  | 
| 420 422 | 
             
                          f = semscan(file)
         | 
| @@ -540,7 +542,9 @@ module Squared | |
| 540 542 |  | 
| 541 543 | 
             
                    def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, dryrun: nil, **)
         | 
| 542 544 | 
             
                      if read_packagemanager(:private)
         | 
| 543 | 
            -
                         | 
| 545 | 
            +
                        if warning?
         | 
| 546 | 
            +
                          warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: 'private', pass: true)
         | 
| 547 | 
            +
                        end
         | 
| 544 548 | 
             
                        return
         | 
| 545 549 | 
             
                      end
         | 
| 546 550 | 
             
                      return unless version
         | 
| @@ -564,7 +568,7 @@ module Squared | |
| 564 568 | 
             
                            banner = format_banner(cmd.to_s)
         | 
| 565 569 | 
             
                            Open3.popen2e(cmd.done) do |_, out|
         | 
| 566 570 | 
             
                              write_lines(out, banner: banner, sub: npmnotice + [
         | 
| 567 | 
            -
                                { pat: /^(.+)(Tarball .+)$/, styles: :blue, index: 2 }
         | 
| 571 | 
            +
                                { pat: /^(.+)(Tarball .+)$/, styles: color(:blue), index: 2 }
         | 
| 568 572 | 
             
                              ])
         | 
| 569 573 | 
             
                            end
         | 
| 570 574 | 
             
                          end
         | 
| @@ -676,7 +680,7 @@ module Squared | |
| 676 680 | 
             
                          end
         | 
| 677 681 | 
             
                          on :last, :bump unless dryrun?
         | 
| 678 682 | 
             
                        else
         | 
| 679 | 
            -
                          raise_error('not found', hint:  | 
| 683 | 
            +
                          raise_error('version not found', hint: dependfile)
         | 
| 680 684 | 
             
                        end
         | 
| 681 685 | 
             
                      rescue StandardError => e
         | 
| 682 686 | 
             
                        log.debug e
         | 
| @@ -699,26 +703,26 @@ module Squared | |
| 699 703 | 
             
                      run(from: :pack)
         | 
| 700 704 | 
             
                    end
         | 
| 701 705 |  | 
| 702 | 
            -
                    def compose( | 
| 703 | 
            -
                      return unless  | 
| 706 | 
            +
                    def compose(target, opts = nil, script: false, args: nil, from: :run, **)
         | 
| 707 | 
            +
                      return unless target
         | 
| 704 708 |  | 
| 705 709 | 
             
                      if script
         | 
| 706 710 | 
             
                        ret = session dependbin, 'run'
         | 
| 707 | 
            -
                        raise_error("#{dependbin} run | 
| 708 | 
            -
                        append_any  | 
| 711 | 
            +
                        raise_error("#{dependbin} run: given #{target}", hint: from) unless append_any(target, build: true)
         | 
| 712 | 
            +
                        append_any opts if opts
         | 
| 709 713 | 
             
                        append_loglevel
         | 
| 710 714 | 
             
                        append_any(args, delim: true) if args
         | 
| 711 715 | 
             
                        ret
         | 
| 712 716 | 
             
                      else
         | 
| 713 | 
            -
                        case  | 
| 717 | 
            +
                        case target
         | 
| 714 718 | 
             
                        when String
         | 
| 715 | 
            -
                           | 
| 719 | 
            +
                          target
         | 
| 716 720 | 
             
                        when Hash
         | 
| 717 | 
            -
                          append_hash( | 
| 721 | 
            +
                          append_hash(target).join(' ')
         | 
| 718 722 | 
             
                        when Enumerable
         | 
| 719 | 
            -
                           | 
| 723 | 
            +
                          target.to_a.join(' ')
         | 
| 720 724 | 
             
                        else
         | 
| 721 | 
            -
                          raise_error(" | 
| 725 | 
            +
                          raise_error("compose given: #{target}", hint: from)
         | 
| 722 726 | 
             
                        end
         | 
| 723 727 | 
             
                      end
         | 
| 724 728 | 
             
                    end
         | 
| @@ -727,10 +731,6 @@ module Squared | |
| 727 731 | 
             
                      @depend != false && (!@depend.nil? || outdated?)
         | 
| 728 732 | 
             
                    end
         | 
| 729 733 |  | 
| 730 | 
            -
                    def copy?
         | 
| 731 | 
            -
                      super || @copy.is_a?(Hash)
         | 
| 732 | 
            -
                    end
         | 
| 733 | 
            -
             | 
| 734 734 | 
             
                    def outdated?
         | 
| 735 735 | 
             
                      dependfile.exist?
         | 
| 736 736 | 
             
                    end
         | 
| @@ -740,8 +740,8 @@ module Squared | |
| 740 740 | 
             
                    end
         | 
| 741 741 |  | 
| 742 742 | 
             
                    def yarn?
         | 
| 743 | 
            -
                      (@pm[:yarn] ||= if  | 
| 744 | 
            -
                                        if (rc =  | 
| 743 | 
            +
                      (@pm[:yarn] ||= if rootpath('yarn.lock', ascend: dependext).exist?
         | 
| 744 | 
            +
                                        if (rc = rootpath('.yarnrc.yml', ascend: dependext)).exist?
         | 
| 745 745 | 
             
                                          begin
         | 
| 746 746 | 
             
                                            require 'yaml'
         | 
| 747 747 | 
             
                                            doc = YAML.load_file(rc)
         | 
| @@ -761,7 +761,7 @@ module Squared | |
| 761 761 | 
             
                    end
         | 
| 762 762 |  | 
| 763 763 | 
             
                    def pnpm?
         | 
| 764 | 
            -
                      (@pm[:pnpm] ||= if  | 
| 764 | 
            +
                      (@pm[:pnpm] ||= if rootpath('pnpm-lock.yaml', ascend: dependext).exist?
         | 
| 765 765 | 
             
                                        begin
         | 
| 766 766 | 
             
                                          require 'yaml'
         | 
| 767 767 | 
             
                                          doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependext))
         | 
| @@ -892,7 +892,7 @@ module Squared | |
| 892 892 | 
             
                      b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
         | 
| 893 893 | 
             
                      c, d = rev == 1 || lock ? ['y/N', 'N'] : ['Y/n', 'Y']
         | 
| 894 894 | 
             
                      e = lock ? " #{sub_style('(locked)', styles: color(:red))}" : ''
         | 
| 895 | 
            -
                       | 
| 895 | 
            +
                      confirm("Upgrade to #{a}? #{b + e} [#{c}] ", d, timeout: 60)
         | 
| 896 896 | 
             
                    end
         | 
| 897 897 |  | 
| 898 898 | 
             
                    def dryrun?(prefix = dependbin, **)
         | 
| @@ -913,9 +913,9 @@ module Squared | |
| 913 913 |  | 
| 914 914 | 
             
                    def npmnotice
         | 
| 915 915 | 
             
                      [
         | 
| 916 | 
            -
                        { pat: /^(npm error )(code|\d+)(.+)$/, styles: :cyan, index: 2 },
         | 
| 917 | 
            -
                        { pat: /^(npm )(error)(.*)$/, styles: :red, index: 2 },
         | 
| 918 | 
            -
                        { pat: /^(npm )(notice)(.*)$/, styles: :cyan, index: 2 },
         | 
| 916 | 
            +
                        { pat: /^(npm error )(code|\d+)(.+)$/, styles: color(:cyan), index: 2 },
         | 
| 917 | 
            +
                        { pat: /^(npm )(error)(.*)$/, styles: color(:red), index: 2 },
         | 
| 918 | 
            +
                        { pat: /^(npm )(notice)(.*)$/, styles: color(:cyan), index: 2 },
         | 
| 919 919 | 
             
                        { pat: /^(npm )(.+)$/, styles: :bold }
         | 
| 920 920 | 
             
                      ]
         | 
| 921 921 | 
             
                    end
         | 
| @@ -4,22 +4,39 @@ module Squared | |
| 4 4 | 
             
              module Workspace
         | 
| 5 5 | 
             
                module Project
         | 
| 6 6 | 
             
                  class Python < Git
         | 
| 7 | 
            -
                    REQUIREMENTS = %w[requirements.txt pyproject.toml].freeze
         | 
| 7 | 
            +
                    REQUIREMENTS = %w[requirements.txt pyproject.toml setup.cfg].freeze
         | 
| 8 8 | 
             
                    SETUPTOOLS = %w[setup.py pyproject.toml].freeze
         | 
| 9 9 | 
             
                    DIR_PYTHON = (REQUIREMENTS + SETUPTOOLS).freeze
         | 
| 10 | 
            +
                    OPT_PYTHON = {
         | 
| 11 | 
            +
                      common: %w[b B d E h i I O OO P q s S u v x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
         | 
| 12 | 
            +
                      build: %w[n|no-isolation s|sdist v|verbose w|wheel x|skip-dependency-check C|config-setting=q installer=b
         | 
| 13 | 
            +
                                o|outdir=p].freeze
         | 
| 14 | 
            +
                    }.freeze
         | 
| 10 15 | 
             
                    OPT_PIP = {
         | 
| 11 16 | 
             
                      common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input no-python-version-warning
         | 
| 12 17 | 
             
                                 q|quiet require-virtualenv v|verbose cache-dir=p cert=p client-cert=p exists-action=b log=p
         | 
| 13 | 
            -
                                 proxy=q python= | 
| 18 | 
            +
                                 proxy=q python=q retries=i timeout=i trusted-host=b use-deprecated=b use-feature=b].freeze,
         | 
| 14 19 | 
             
                      install: %w[break-system-packages check-build-dependencies compile dry-run force-reinstall I|ignore-installed
         | 
| 15 20 | 
             
                                  ignore-requires-python no-build-isolation no-clean no-compile no-deps no-index no-warn-conflicts
         | 
| 16 | 
            -
                                  no-warn-script-location pre prefer-binary require-hashes U|upgrade use-pep517 user abi= | 
| 21 | 
            +
                                  no-warn-script-location pre prefer-binary require-hashes U|upgrade use-pep517 user abi=b
         | 
| 17 22 | 
             
                                  config-settings=q c|constraint=p e|editable=b? extra-index-url=q f|find-links=q global-option=q
         | 
| 18 23 | 
             
                                  implementation=b i|index-url=q no-binary=q only-binary=q platform=q prefix=p progress-bar=b
         | 
| 19 | 
            -
                                  python-version=q report=p r|requirement=p root=p root-user-action= | 
| 24 | 
            +
                                  python-version=q report=p r|requirement=p root=p root-user-action=b src=p t|target=p
         | 
| 20 25 | 
             
                                  upgrade-strategy=b].freeze
         | 
| 21 26 | 
             
                    }.freeze
         | 
| 22 | 
            -
                     | 
| 27 | 
            +
                    OPT_HATCH = {
         | 
| 28 | 
            +
                      common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=e
         | 
| 29 | 
            +
                                 q|quiet v|verbose].freeze,
         | 
| 30 | 
            +
                      build: %w[clean-hooks-after ext hooks-only no-hooks c|clean t|target=b].freeze,
         | 
| 31 | 
            +
                      publish: %w[initialize-auth n|no-prompt y|yes a|auth=q ca-cert=p client-cert=p client-key=p o|option=q
         | 
| 32 | 
            +
                                  p|publisher=b r|repo=b u|user=q].freeze
         | 
| 33 | 
            +
                    }.freeze
         | 
| 34 | 
            +
                    OPT_TWINE = {
         | 
| 35 | 
            +
                      publish: %w[attestations disable-progress-bar non-interactive skip-existing verbose s|sign c|comment=q
         | 
| 36 | 
            +
                                  config-file=p cert=p client-cert=p i|identity=b p|password=q r|repository=b repository-url=q
         | 
| 37 | 
            +
                                  sign-with=b u|username=q].freeze
         | 
| 38 | 
            +
                    }.freeze
         | 
| 39 | 
            +
                    private_constant :REQUIREMENTS, :SETUPTOOLS, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_HATCH, :OPT_TWINE
         | 
| 23 40 |  | 
| 24 41 | 
             
                    class << self
         | 
| 25 42 | 
             
                      def populate(*); end
         | 
| @@ -47,7 +64,7 @@ module Squared | |
| 47 64 | 
             
                    def initialize(*, **kwargs)
         | 
| 48 65 | 
             
                      super
         | 
| 49 66 | 
             
                      if @pass.include?(Python.ref)
         | 
| 50 | 
            -
                        initialize_ref | 
| 67 | 
            +
                        initialize_ref Python.ref
         | 
| 51 68 | 
             
                        initialize_logger(**kwargs)
         | 
| 52 69 | 
             
                      else
         | 
| 53 70 | 
             
                        initialize_build(Python.ref, **kwargs)
         | 
| @@ -58,7 +75,9 @@ module Squared | |
| 58 75 | 
             
                    end
         | 
| 59 76 |  | 
| 60 77 | 
             
                    @@tasks[ref] = {
         | 
| 61 | 
            -
                      'install' => %i[user force upgrade target editable].freeze
         | 
| 78 | 
            +
                      'install' => %i[user force upgrade target editable].freeze,
         | 
| 79 | 
            +
                      'build' => %i[python hatch].freeze,
         | 
| 80 | 
            +
                      'publish' => %i[twine hatch].freeze
         | 
| 62 81 | 
             
                    }.freeze
         | 
| 63 82 |  | 
| 64 83 | 
             
                    def ref
         | 
| @@ -111,6 +130,16 @@ module Squared | |
| 111 130 | 
             
                                    depend flag, args.to_a
         | 
| 112 131 | 
             
                                  end
         | 
| 113 132 | 
             
                                end
         | 
| 133 | 
            +
                              when 'build'
         | 
| 134 | 
            +
                                format_desc(action, flag, 'opts*', after: flag == :hatch ? 'location?' : 'srcdir?')
         | 
| 135 | 
            +
                                task flag do |_, args|
         | 
| 136 | 
            +
                                  buildx flag, args.to_a
         | 
| 137 | 
            +
                                end
         | 
| 138 | 
            +
                              when 'publish'
         | 
| 139 | 
            +
                                format_desc(action, flag, 'opts*', after: flag == :hatch ? 'artifacts?' : 'dist?')
         | 
| 140 | 
            +
                                task flag do |_, args|
         | 
| 141 | 
            +
                                  publish flag, args.to_a
         | 
| 142 | 
            +
                                end
         | 
| 114 143 | 
             
                              end
         | 
| 115 144 | 
             
                            end
         | 
| 116 145 | 
             
                          end
         | 
| @@ -122,6 +151,7 @@ module Squared | |
| 122 151 | 
             
                      if @depend && !flag
         | 
| 123 152 | 
             
                        super
         | 
| 124 153 | 
             
                      elsif outdated?
         | 
| 154 | 
            +
                        workspace.rev_clear name
         | 
| 125 155 | 
             
                        cmd = pip_session 'install'
         | 
| 126 156 | 
             
                        case flag
         | 
| 127 157 | 
             
                        when :user
         | 
| @@ -143,21 +173,6 @@ module Squared | |
| 143 173 | 
             
                      end
         | 
| 144 174 | 
             
                    end
         | 
| 145 175 |  | 
| 146 | 
            -
                    def install(flag, opts, strategy: nil)
         | 
| 147 | 
            -
                      cmd = pip_session 'install'
         | 
| 148 | 
            -
                      out = append_pip(flag, opts, from: :install)
         | 
| 149 | 
            -
                      case flag
         | 
| 150 | 
            -
                      when :editable
         | 
| 151 | 
            -
                        cmd << '--editable' << (out.pop || '.')
         | 
| 152 | 
            -
                        option_clear out
         | 
| 153 | 
            -
                      when :upgrade
         | 
| 154 | 
            -
                        cmd << '--upgrade'
         | 
| 155 | 
            -
                        cmd << basic_option('upgrade-strategy', strategy) if strategy
         | 
| 156 | 
            -
                        append_value out
         | 
| 157 | 
            -
                      end
         | 
| 158 | 
            -
                      run(from: :install)
         | 
| 159 | 
            -
                    end
         | 
| 160 | 
            -
             | 
| 161 176 | 
             
                    def outdated(*, sync: invoked_sync?('outdated'))
         | 
| 162 177 | 
             
                      cmd = pip_session 'list', '--outdated'
         | 
| 163 178 | 
             
                      append_global
         | 
| @@ -173,7 +188,7 @@ module Squared | |
| 173 188 | 
             
                        buffer = []
         | 
| 174 189 | 
             
                        out = ->(val) { sync ? puts(val) : buffer << val }
         | 
| 175 190 | 
             
                        IO.popen(cmd).each do |line|
         | 
| 176 | 
            -
                          next if line | 
| 191 | 
            +
                          next if line.match?(/^[\s-]+$/)
         | 
| 177 192 |  | 
| 178 193 | 
             
                          if start > 0
         | 
| 179 194 | 
             
                            unless stdin?
         | 
| @@ -210,7 +225,7 @@ module Squared | |
| 210 225 | 
             
                            end
         | 
| 211 226 | 
             
                            out.("#{start.to_s.rjust(2)}. #{line}")
         | 
| 212 227 | 
             
                            start += 1
         | 
| 213 | 
            -
                          elsif line | 
| 228 | 
            +
                          elsif line.start_with?('Package')
         | 
| 214 229 | 
             
                            unless stdin?
         | 
| 215 230 | 
             
                              sub = { pat: /^(.*)(?<!\dm)(Package|Latest)(.+)$/, styles: theme[:header], index: 2 }
         | 
| 216 231 | 
             
                              out.(print_footer(" #  #{line.chomp}", reverse: true, sub: [sub, sub]))
         | 
| @@ -231,6 +246,82 @@ module Squared | |
| 231 246 | 
             
                      on :last, :outdated
         | 
| 232 247 | 
             
                    end
         | 
| 233 248 |  | 
| 249 | 
            +
                    def install(flag, opts = [], strategy: nil)
         | 
| 250 | 
            +
                      cmd = pip_session 'install'
         | 
| 251 | 
            +
                      out = append_pip(flag, opts, from: :install)
         | 
| 252 | 
            +
                      case flag
         | 
| 253 | 
            +
                      when :editable
         | 
| 254 | 
            +
                        cmd << '--editable' << (out.pop || '.')
         | 
| 255 | 
            +
                        option_clear out
         | 
| 256 | 
            +
                      when :upgrade
         | 
| 257 | 
            +
                        cmd << '--upgrade'
         | 
| 258 | 
            +
                        cmd << basic_option('upgrade-strategy', strategy) if strategy
         | 
| 259 | 
            +
                        append_value out
         | 
| 260 | 
            +
                      end
         | 
| 261 | 
            +
                      run(from: :install)
         | 
| 262 | 
            +
                    end
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                    def buildx(flag, opts = [])
         | 
| 265 | 
            +
                      cmd = session flag
         | 
| 266 | 
            +
                      out = []
         | 
| 267 | 
            +
                      srcdir = nil
         | 
| 268 | 
            +
                      case flag
         | 
| 269 | 
            +
                      when :python
         | 
| 270 | 
            +
                        cmd << shell_option('m', 'build')
         | 
| 271 | 
            +
                        list = OPT_PYTHON[:build] + OPT_PYTHON[:common]
         | 
| 272 | 
            +
                      when :hatch
         | 
| 273 | 
            +
                        cmd << 'build'
         | 
| 274 | 
            +
                        list = OPT_HATCH[:build] + OPT_HATCH[:common]
         | 
| 275 | 
            +
                      end
         | 
| 276 | 
            +
                      option_sanitize(opts, list).first.each do |opt|
         | 
| 277 | 
            +
                        if opt =~ /^(v+|q+)$/ || (flag == :python && opt =~ /^(b+)$/)
         | 
| 278 | 
            +
                          cmd << "-#{$1}"
         | 
| 279 | 
            +
                        elsif !srcdir && basepath(opt).exist? && projectpath?(opt)
         | 
| 280 | 
            +
                          srcdir = opt
         | 
| 281 | 
            +
                        else
         | 
| 282 | 
            +
                          out << opt
         | 
| 283 | 
            +
                        end
         | 
| 284 | 
            +
                      end
         | 
| 285 | 
            +
                      if flag == :hatch
         | 
| 286 | 
            +
                        if ENV['HATCH_BUILD_LOCATION']
         | 
| 287 | 
            +
                          srcdir = nil
         | 
| 288 | 
            +
                        else
         | 
| 289 | 
            +
                          srcdir ||= path
         | 
| 290 | 
            +
                        end
         | 
| 291 | 
            +
                        cmd << basic_option('p', project) unless ENV['HATCH_PROJECT'] || session_arg?('p', 'project')
         | 
| 292 | 
            +
                      end
         | 
| 293 | 
            +
                      cmd << shell_quote(basepath(srcdir)) if srcdir
         | 
| 294 | 
            +
                      option_clear out
         | 
| 295 | 
            +
                      run(from: :"#{flag}:build")
         | 
| 296 | 
            +
                    end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                    def publish(flag, opts = [])
         | 
| 299 | 
            +
                      cmd = session flag
         | 
| 300 | 
            +
                      out = []
         | 
| 301 | 
            +
                      case flag
         | 
| 302 | 
            +
                      when :twine
         | 
| 303 | 
            +
                        cmd << 'upload'
         | 
| 304 | 
            +
                        list = OPT_TWINE[:publish]
         | 
| 305 | 
            +
                      when :hatch
         | 
| 306 | 
            +
                        cmd << 'publish'
         | 
| 307 | 
            +
                        list = OPT_HATCH[:publish] + OPT_HATCH[:common]
         | 
| 308 | 
            +
                      end
         | 
| 309 | 
            +
                      option_sanitize(opts, list).first.each do |opt|
         | 
| 310 | 
            +
                        if flag == :hatch && opt =~ /^(v+|q+)$/
         | 
| 311 | 
            +
                          cmd << "-#{$1}"
         | 
| 312 | 
            +
                        else
         | 
| 313 | 
            +
                          out << opt
         | 
| 314 | 
            +
                        end
         | 
| 315 | 
            +
                      end
         | 
| 316 | 
            +
                      if out.empty?
         | 
| 317 | 
            +
                        dist = basepath.join('dist')
         | 
| 318 | 
            +
                        raise_error('no source files given', hint: dist) unless dist.directory? && !dist.empty?
         | 
| 319 | 
            +
                        out << "#{dist}/*"
         | 
| 320 | 
            +
                      end
         | 
| 321 | 
            +
                      append_value out
         | 
| 322 | 
            +
                      run(from: :"#{flag}:publish")
         | 
| 323 | 
            +
                    end
         | 
| 324 | 
            +
             | 
| 234 325 | 
             
                    def variable_set(key, *val, **)
         | 
| 235 326 | 
             
                      case key
         | 
| 236 327 | 
             
                      when :dependfile
         | 
| @@ -11,27 +11,27 @@ module Squared | |
| 11 11 | 
             
                      install: %w[frozen no-cache no-prune system path=p binstubs=p? standalone=q? target-rbconfig=p trust-policy=b
         | 
| 12 12 | 
             
                                  with=q without=q].freeze,
         | 
| 13 13 | 
             
                      install_base: %w[full-index quiet retry gemfile=p j|jobs=i].freeze,
         | 
| 14 | 
            -
                      update: %w[conservative local pre redownload ruby strict bundler= | 
| 14 | 
            +
                      update: %w[conservative local pre redownload ruby strict bundler=b? g|group=q source=b].freeze,
         | 
| 15 15 | 
             
                      outdated: %w[filter-major filter-minor filter-patch groups local parseable pre only-explicit strict
         | 
| 16 | 
            -
                                   update-strict g|group=q source= | 
| 16 | 
            +
                                   update-strict g|group=q source=b].freeze,
         | 
| 17 17 | 
             
                      exec: %w[gemfile=p].freeze,
         | 
| 18 18 | 
             
                      check: %w[dry-run gemfile=p].freeze
         | 
| 19 19 | 
             
                    }.freeze
         | 
| 20 20 | 
             
                    OPT_GEM = {
         | 
| 21 21 | 
             
                      common: %w[backtrace debug q|quiet no-verbose norc silent V|verbose config-file=p].freeze,
         | 
| 22 | 
            -
                      install: %w[version= | 
| 23 | 
            -
                      update: %w[system= | 
| 22 | 
            +
                      install: %w[version=b].freeze,
         | 
| 23 | 
            +
                      update: %w[system=b?].freeze,
         | 
| 24 24 | 
             
                      outdated: %w[b|both clear-sources l|local no-http-proxy r|remote B|bulk-threshold=i p|http-proxy=q?
         | 
| 25 25 | 
             
                                   platform=q source=q].freeze,
         | 
| 26 | 
            -
                      push: %w[no-http-proxy attestation=p host=q key= | 
| 26 | 
            +
                      push: %w[no-http-proxy attestation=p host=q key=b otp=b p|http-proxy=q?].freeze,
         | 
| 27 27 | 
             
                      build: %w[force strict o|output=p platform=q].freeze,
         | 
| 28 | 
            -
                      exec: %w[conservative prerelease no-prerelease g|gem=b version= | 
| 28 | 
            +
                      exec: %w[conservative prerelease no-prerelease g|gem=b version=b].freeze,
         | 
| 29 29 | 
             
                      pristine: %w[all env-shebang extensions no-env-shebang no-extensions only-executables only-missing-extensions
         | 
| 30 | 
            -
                                   only-plugins n|bindir=p i|install-dir=p skip= | 
| 30 | 
            +
                                   only-plugins n|bindir=p i|install-dir=p skip=b v|version=b].freeze,
         | 
| 31 31 | 
             
                      shared: %w[f b|both clear-sources conservative default development development-all E|explain
         | 
| 32 32 | 
             
                                 ignore-dependencies l|local N|no-document r|remote w|vendor n|bindir=p build-root=p
         | 
| 33 33 | 
             
                                 bulk-threshold=i document=b? g|file=p? p|http-proxy=q i|install-dir=p platform=q s|source=q
         | 
| 34 | 
            -
                                 target-rbconfig=p? P|trust-policy=b without= | 
| 34 | 
            +
                                 target-rbconfig=p? P|trust-policy=b without=b].freeze,
         | 
| 35 35 | 
             
                      shared_no: %w[env-shebang force format-executable http-proxy lock minimal-deps post-install-message
         | 
| 36 36 | 
             
                                    prerelease suggestions user-install wrappers].freeze
         | 
| 37 37 | 
             
                    }.freeze
         | 
| @@ -70,7 +70,7 @@ module Squared | |
| 70 70 | 
             
                    def initialize(*, autodetect: false, **kwargs)
         | 
| 71 71 | 
             
                      super
         | 
| 72 72 | 
             
                      if @pass.include?(Ruby.ref)
         | 
| 73 | 
            -
                        initialize_ref | 
| 73 | 
            +
                        initialize_ref Ruby.ref
         | 
| 74 74 | 
             
                        initialize_logger(**kwargs)
         | 
| 75 75 | 
             
                      else
         | 
| 76 76 | 
             
                        initialize_build(Ruby.ref, **kwargs)
         | 
| @@ -83,7 +83,7 @@ module Squared | |
| 83 83 |  | 
| 84 84 | 
             
                      begin
         | 
| 85 85 | 
             
                        File.foreach(file) do |line|
         | 
| 86 | 
            -
                          next unless line | 
| 86 | 
            +
                          next unless line.match?(%r{\brequire\s+(["'])bundler/gem_tasks\1})
         | 
| 87 87 |  | 
| 88 88 | 
             
                          cmd = bundle_output('exec', 'rake').to_s
         | 
| 89 89 | 
             
                          @output[0] = "#{cmd} build"
         | 
| @@ -178,6 +178,7 @@ module Squared | |
| 178 178 | 
             
                      if @depend
         | 
| 179 179 | 
             
                        super
         | 
| 180 180 | 
             
                      elsif outdated?
         | 
| 181 | 
            +
                        workspace.rev_clear name
         | 
| 181 182 | 
             
                        cmd = bundle_session 'install'
         | 
| 182 183 | 
             
                        if (n = option('jobs')).to_i > 0
         | 
| 183 184 | 
             
                          cmd << "-j#{n}"
         | 
| @@ -188,7 +189,7 @@ module Squared | |
| 188 189 |  | 
| 189 190 | 
             
                    def copy(from: 'lib', include: nil, exclude: nil, into: @gemdir, override: false)
         | 
| 190 191 | 
             
                      if @copy && !override
         | 
| 191 | 
            -
                        return super  | 
| 192 | 
            +
                        return super unless @copy.is_a?(Hash)
         | 
| 192 193 |  | 
| 193 194 | 
             
                        from = @copy[:from] if @copy.key?(:from)
         | 
| 194 195 | 
             
                        glob = @copy[:include] if @copy.key?(:include)
         | 
| @@ -301,7 +302,7 @@ module Squared | |
| 301 302 | 
             
                              end
         | 
| 302 303 | 
             
                            end
         | 
| 303 304 | 
             
                            out.("#{start.to_s.rjust(2)}. #{line}")
         | 
| 304 | 
            -
                          elsif line | 
| 305 | 
            +
                          elsif line.start_with?('Gem')
         | 
| 305 306 | 
             
                            unless stdin?
         | 
| 306 307 | 
             
                              sub = { pat: /^(.+)(?<!\dm)(Gem|Latest)(.+)$/, styles: theme[:header], index: 2 }
         | 
| 307 308 | 
             
                              out.(print_footer(" #  #{line.chomp}", reverse: true, sub: [sub, sub]))
         | 
| @@ -388,14 +389,14 @@ module Squared | |
| 388 389 | 
             
                        pwd_set(pass: !pwd.nil?, from: from) do
         | 
| 389 390 | 
             
                          items = [[%w[Gem Current Latest], nil]]
         | 
| 390 391 | 
             
                          IO.popen(cmd.done).each do |line|
         | 
| 391 | 
            -
                            if  | 
| 392 | 
            -
                              cur = semscan( | 
| 393 | 
            -
                              lat = semscan( | 
| 394 | 
            -
                              items << [ | 
| 395 | 
            -
             | 
| 396 | 
            -
             | 
| 397 | 
            -
             | 
| 398 | 
            -
             | 
| 392 | 
            +
                            if line =~ /^(\S+) \((\S+) < ([^)]+)\)$/
         | 
| 393 | 
            +
                              cur = semscan($2)
         | 
| 394 | 
            +
                              lat = semscan($3)
         | 
| 395 | 
            +
                              items << [$~.to_a.drop(1), if semmajor?(cur, lat)
         | 
| 396 | 
            +
                                                           %i[green bold]
         | 
| 397 | 
            +
                                                         else
         | 
| 398 | 
            +
                                                           cur[2] == lat[2] ? [:yellow] : [:green]
         | 
| 399 | 
            +
                                                         end]
         | 
| 399 400 | 
             
                            else
         | 
| 400 401 | 
             
                              puts line
         | 
| 401 402 | 
             
                            end
         | 
| @@ -427,7 +428,7 @@ module Squared | |
| 427 428 | 
             
                                  line = sub_style(line, pat: /^(.+)(?<!\dm)(#{a}|#{c})(.*)$/, styles: theme[:header], index: 2)
         | 
| 428 429 | 
             
                                end
         | 
| 429 430 | 
             
                                puts line
         | 
| 430 | 
            -
                                puts  | 
| 431 | 
            +
                                puts sub_style(ARG[:BORDER][1] * n, styles: borderstyle)
         | 
| 431 432 | 
             
                              else
         | 
| 432 433 | 
             
                                styles = item.last
         | 
| 433 434 | 
             
                                a = a.ljust(d)
         | 
| @@ -461,25 +462,23 @@ module Squared | |
| 461 462 | 
             
                      when :build, :push
         | 
| 462 463 | 
             
                        if !out.empty?
         | 
| 463 464 | 
             
                          if flag == :build && out.size == 1
         | 
| 464 | 
            -
                            cmd << basepath(out.first)
         | 
| 465 | 
            +
                            cmd << shell_quote(basepath(out.first))
         | 
| 465 466 | 
             
                          else
         | 
| 466 | 
            -
                            raise_error( | 
| 467 | 
            +
                            raise_error("unknown args: #{out.join(', ')}", hint: flag)
         | 
| 467 468 | 
             
                          end
         | 
| 468 469 | 
             
                        elsif flag == :build
         | 
| 469 470 | 
             
                          cmd << "#{project}.gemspec"
         | 
| 470 471 | 
             
                        end
         | 
| 471 472 | 
             
                      when :exec
         | 
| 472 | 
            -
                        raise_error(' | 
| 473 | 
            +
                        raise_error('no command given', hint: flag) if out.empty?
         | 
| 473 474 | 
             
                        cmd << out.join(' ')
         | 
| 474 475 | 
             
                      else
         | 
| 475 | 
            -
                        if out.empty? &&  | 
| 476 | 
            -
                          raise_error('gem', flag, hint: 'no gemname given')
         | 
| 477 | 
            -
                        end
         | 
| 476 | 
            +
                        raise_error('no gemname given', hint: flag) if out.empty? && !session_arg?('system')
         | 
| 478 477 | 
             
                        if flag == :pristine
         | 
| 479 478 | 
             
                          if session_arg?('all')
         | 
| 480 479 | 
             
                            append_repeat 'skip', out
         | 
| 481 480 | 
             
                            out.clear
         | 
| 482 | 
            -
                          elsif (n = out.first | 
| 481 | 
            +
                          elsif (n = out.first.index('@'))
         | 
| 483 482 | 
             
                            name = out.first
         | 
| 484 483 | 
             
                            if n == 0
         | 
| 485 484 | 
             
                              cmd << project
         | 
| @@ -504,7 +503,7 @@ module Squared | |
| 504 503 | 
             
                      when 'exec', 'check'
         | 
| 505 504 | 
             
                        args = option_sanitize(args, OPT_BUNDLE[flag.to_sym] + OPT_BUNDLE[:common]).first
         | 
| 506 505 | 
             
                      end
         | 
| 507 | 
            -
                      raise_error(' | 
| 506 | 
            +
                      raise_error('no command given', hint: flag) unless !args.empty? || flag == 'check'
         | 
| 508 507 | 
             
                      cmd.merge(args)
         | 
| 509 508 | 
             
                      run(from: :"bundle:#{flag}")
         | 
| 510 509 | 
             
                    end
         | 
| @@ -568,7 +567,7 @@ module Squared | |
| 568 567 | 
             
                        end
         | 
| 569 568 | 
             
                        pwd_set { parse.(`#{bundle_output('show', project)}`) } unless @gemdir
         | 
| 570 569 | 
             
                      end
         | 
| 571 | 
            -
                      raise_error('failed | 
| 570 | 
            +
                      raise_error('parse failed', hint: @version || 'path') unless @gemdir
         | 
| 572 571 | 
             
                    rescue StandardError => e
         | 
| 573 572 | 
             
                      log.error e
         | 
| 574 573 | 
             
                      @version = nil
         | 
| @@ -601,7 +600,7 @@ module Squared | |
| 601 600 |  | 
| 602 601 | 
             
                    def bundle_session(*cmd, **kwargs)
         | 
| 603 602 | 
             
                      ret = session('bundle', *cmd, **kwargs)
         | 
| 604 | 
            -
                      append_nocolor | 
| 603 | 
            +
                      append_nocolor
         | 
| 605 604 | 
             
                      ret
         | 
| 606 605 | 
             
                    end
         | 
| 607 606 |  | 
| @@ -647,7 +646,7 @@ module Squared | |
| 647 646 | 
             
                    def rakefile
         | 
| 648 647 | 
             
                      return unless (file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? })
         | 
| 649 648 |  | 
| 650 | 
            -
                      basepath | 
| 649 | 
            +
                      basepath file
         | 
| 651 650 | 
             
                    end
         | 
| 652 651 |  | 
| 653 652 | 
             
                    def rakeapp
         | 
| @@ -657,13 +656,13 @@ module Squared | |
| 657 656 | 
             
                    def rakepwd
         | 
| 658 657 | 
             
                      return unless Rake::VERSION >= '13.0.4'
         | 
| 659 658 |  | 
| 660 | 
            -
                      quote_option | 
| 659 | 
            +
                      quote_option 'C', path
         | 
| 661 660 | 
             
                    end
         | 
| 662 661 |  | 
| 663 662 | 
             
                    def gempwd
         | 
| 664 663 | 
             
                      return unless Gem::VERSION >= '3.4.2'
         | 
| 665 664 |  | 
| 666 | 
            -
                      quote_option | 
| 665 | 
            +
                      quote_option 'C', path
         | 
| 667 666 | 
             
                    end
         | 
| 668 667 |  | 
| 669 668 | 
             
                    def gempath(val = @version)
         |