github.com/jingweno/gh@v2.1.1-0.20221007190738-04a7985fa9a1+incompatible/Rakefile (about)

     1  require "fileutils"
     2  
     3  #
     4  # Release
     5  #
     6  
     7  class VersionedFile
     8    def initialize(file, regex)
     9      @file = file
    10      @regex = regex
    11    end
    12  
    13    def current_version!
    14      @current_version ||= matched_data![1]
    15    end
    16  
    17    def bump_version!(type)
    18      position = case type
    19                 when :major
    20                   0
    21                 when :minor
    22                   1
    23                 when :patch
    24                   2
    25                 end
    26      @current_version = current_version!.split(".").tap do |v|
    27        v[position] = v[position].to_i + 1
    28        # Reset consequent numbers
    29        ((position + 1)..2).each { |p| v[p] = 0 }
    30      end.join(".")
    31    end
    32  
    33    def save!
    34      text = File.read(@file)
    35      new_line = matched_data![0].gsub(matched_data![1], @current_version)
    36      text.gsub!(matched_data![0], new_line)
    37  
    38      File.open(@file, "w") { |f| f.puts text }
    39    end
    40  
    41    private
    42  
    43    def matched_data!
    44      @matched_data ||= begin
    45                          m = @regex.match File.read(@file)
    46                          raise "No version #{@regex} matched in #{@file}" unless m
    47                          m
    48                        end
    49    end
    50  end
    51  
    52  def fullpath(file)
    53    File.expand_path(file, File.dirname(__FILE__))
    54  end
    55  
    56  VERSION_FILES = {
    57    fullpath("README.md")           => /v(\d+.\d+.\d+)/,
    58    fullpath("commands/version.go") => /^const Version = "(\d+.\d+.\d+)"$/,
    59    fullpath(".goxc.json")          => /"PackageVersion": "(\d+.\d+.\d+)"/,
    60    fullpath("homebrew-gh/gh.rb")   => /VERSION = "(\d+.\d+.\d+)"/
    61  }
    62  
    63  class Git
    64    class << self
    65      def dirty?
    66        !`git status -s`.empty?
    67      end
    68  
    69      def checkout
    70        `git checkout .`
    71      end
    72  
    73      def commit_all(msg)
    74        `git commit -am "#{msg}"`
    75      end
    76  
    77      def create_tag(tag, msg)
    78        `git tag -a #{tag} -m "#{msg}"`
    79      end
    80    end
    81  end
    82  
    83  namespace :release do
    84    desc "Current released version"
    85    task :current do
    86      vf = VersionedFile.new(*VERSION_FILES.first)
    87      puts vf.current_version!
    88    end
    89  
    90    [:major, :minor, :patch].each do |type|
    91      desc "Release #{type} version"
    92      task type do
    93        if Git.dirty?
    94          puts "Please commit all changes first"
    95          exit 1
    96        end
    97  
    98        new_versions = VERSION_FILES.map do |file, regex|
    99          begin
   100            vf = VersionedFile.new(file, regex)
   101            current_version = vf.current_version!
   102            vf.bump_version!(type)
   103            vf.save!
   104            puts "Successfully bump #{file} from #{current_version} to #{vf.current_version!}"
   105            vf.current_version!
   106          rescue => e
   107            Git.checkout
   108            raise e
   109          end
   110        end
   111  
   112        require "set"
   113        new_versions = new_versions.to_set
   114        if new_versions.size != 1
   115          raise "More than one version found among #{VERSION_FILES}"
   116        end
   117  
   118        new_version = "v#{new_versions.first}"
   119        msg = "Bump version to #{new_version}"
   120        Git.commit_all(msg)
   121        Git.create_tag(new_version, msg)
   122      end
   123    end
   124  end
   125  
   126  #
   127  # Build (deprecated, prefer gh_task.go)
   128  #
   129  
   130  module OS
   131    class << self
   132      def type
   133        if darwin?
   134          "darwin"
   135        elsif linux?
   136          "linux"
   137        elsif windows?
   138          "windows"
   139        else
   140          raise "Unknown OS type #{RUBY_PLATFORM}"
   141        end
   142      end
   143  
   144      def dropbox_dir
   145        if darwin? || linux?
   146          File.join ENV["HOME"], "Dropbox"
   147        elsif windows?
   148          File.join ENV["DROPBOX_DIR"]
   149        else
   150          raise "Unknown OS type #{RUBY_PLATFORM}"
   151        end
   152      end
   153  
   154      def windows?
   155        (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
   156      end
   157  
   158      def darwin?
   159        (/darwin/ =~ RUBY_PLATFORM) != nil
   160      end
   161  
   162      def linux?
   163        (/linux/ =~ RUBY_PLATFORM) != nil
   164      end
   165    end
   166  end
   167  
   168  namespace :build do
   169    desc "Build for current operating system"
   170    task :current => [:update_goxc, :remove_build_target, :build_gh, :move_to_dropbox]
   171  
   172    task :update_goxc do
   173      puts "Updating goxc..."
   174      result = system "go get -u github.com/laher/goxc"
   175      raise "Fail to update goxc" unless result
   176    end
   177  
   178    task :remove_build_target do
   179      FileUtils.rm_rf fullpath("target")
   180    end
   181  
   182    task :build_gh do
   183      puts "Building for #{OS.type}..."
   184      puts `goxc -wd=. -os=#{OS.type} -c=#{OS.type}`
   185    end
   186  
   187    task :move_to_dropbox do
   188      vf = VersionedFile.new(*VERSION_FILES.first)
   189      build_dir = fullpath("target/#{vf.current_version!}-snapshot")
   190      dropbox_dir = File.join(OS.dropbox_dir, "Public", "gh")
   191  
   192      FileUtils.cp_r build_dir, dropbox_dir, :verbose => true
   193    end
   194  end
   195  
   196  #
   197  # Tests
   198  #
   199  
   200  task :default => [:features]
   201  
   202  desc "Run cucumber feature tests from Hub"
   203  task :features do
   204    features = ENV.fetch("FEATURE", "features")
   205    profile = ENV.fetch("PROFILE", "default")
   206    sh "cucumber -p #{profile} -t ~@wip #{features}"
   207  end
   208  
   209  #
   210  # Manual
   211  #
   212  
   213  desc "Show man page"
   214  task :man => "man:build" do
   215    exec "man man/gh.1"
   216  end
   217  
   218  desc "Build man pages"
   219  task "man:build" => ["man/gh.1", "man/gh.1.html"]
   220  
   221  extract_examples = lambda { |readme_file|
   222    # split readme in sections
   223    examples = File.read(readme_file).split(/^-{4,}$/)[6].strip
   224    examples.sub!(/^.+?(###)/m, '\1')  # strip intro paragraph
   225    examples.sub!(/\n+.+\Z/, '')       # remove last line
   226    examples
   227  }
   228  
   229  # inject examples from README file to .ronn source
   230  source_with_examples = lambda { |source, readme|
   231    examples = extract_examples.call(readme)
   232    compiled = File.read(source)
   233    compiled.sub!('{{README}}', examples)
   234    compiled
   235  }
   236  
   237  # generate man page with ronn
   238  compile_ronn = lambda { |destination, type, contents|
   239    File.popen("ronn --pipe --#{type} --organization=GITHUB --manual='gh Manual'", 'w+') { |io|
   240      io.write contents
   241      io.close_write
   242      File.open(destination, 'w') { |f| f << io.read }
   243    }
   244    abort "ronn --#{type} conversion failed" unless $?.success?
   245  }
   246  
   247  file "man/gh.1" => ["man/gh.1.ronn", "README.md"] do |task|
   248    contents = source_with_examples.call(*task.prerequisites)
   249    compile_ronn.call(task.name, 'roff', contents)
   250    compile_ronn.call("#{task.name}.html", 'html', contents)
   251  end
   252  
   253  file "man/gh.1.html" => ["man/gh.1.ronn", "README.md"] do |task|
   254    Rake::Task["man/gh.1"].invoke
   255  end