]> git.immae.eu Git - github/fretlink/pronto-hlint.git/commitdiff
Welcom pronto-hlint! This is a whole rewrite of pronto-eslint_npm.
authorPaul Bonaud <paul.bonaud@fretlink.com>
Sat, 13 Apr 2019 14:38:04 +0000 (16:38 +0200)
committerPaul Bonaud <paul.bonaud@fretlink.com>
Sat, 13 Apr 2019 14:38:04 +0000 (16:38 +0200)
Forking the pronto-eslint_npm repository to build a runner for hlint
haskell linter.

89 files changed:
.gitignore
.ruby-version
.travis.yml
LICENSE
README.md
gems.locked [new file with mode: 0644]
gems.rb [moved from Gemfile with 100% similarity]
lib/pronto/eslint_npm.rb [deleted file]
lib/pronto/eslint_npm/version.rb [deleted file]
lib/pronto/hlint.rb [new file with mode: 0644]
lib/pronto/hlint/runner.rb [new file with mode: 0644]
lib/pronto/hlint/version.rb [new file with mode: 0644]
pronto-hlint.gemspec [moved from pronto-eslint_npm.gemspec with 62% similarity]
spec/fixtures/eslintignore.git/.eslintignore [deleted file]
spec/fixtures/eslintignore.git/.eslintrc [deleted file]
spec/fixtures/eslintignore.git/git/HEAD [deleted file]
spec/fixtures/eslintignore.git/git/config [deleted file]
spec/fixtures/eslintignore.git/git/index [deleted file]
spec/fixtures/eslintignore.git/git/logs/HEAD [deleted file]
spec/fixtures/eslintignore.git/git/logs/refs/heads/eslintignore [deleted file]
spec/fixtures/eslintignore.git/git/logs/refs/heads/master [deleted file]
spec/fixtures/eslintignore.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7 [deleted file]
spec/fixtures/eslintignore.git/git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 [deleted file]
spec/fixtures/eslintignore.git/git/objects/5f/fc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53 [deleted file]
spec/fixtures/eslintignore.git/git/objects/69/7ffd3c693fce9abcb871b9b47e2d116e6241d3 [deleted file]
spec/fixtures/eslintignore.git/git/objects/d4/3de0396c81608113f99f7afd00f7f363e1cae8 [deleted file]
spec/fixtures/eslintignore.git/git/objects/d8/5195b5ff74cc05d121b758f00da43018f53b6f [deleted file]
spec/fixtures/eslintignore.git/git/objects/ec/7b4537cbd327a580ee44b74ff02fffc74feb46 [deleted file]
spec/fixtures/eslintignore.git/git/refs/heads/eslintignore [deleted file]
spec/fixtures/eslintignore.git/git/refs/heads/master [deleted file]
spec/fixtures/eslintignore.git/ignored/ignored.js [deleted file]
spec/fixtures/eslintignore.git/ignored/not_ignored.js [deleted file]
spec/fixtures/test.git/.eslintrc [deleted file]
spec/fixtures/test.git/custom_eslint.sh [deleted file]
spec/fixtures/test.git/custom_hlint.sh [new file with mode: 0755]
spec/fixtures/test.git/git/COMMIT_EDITMSG [new file with mode: 0644]
spec/fixtures/test.git/git/HEAD
spec/fixtures/test.git/git/config
spec/fixtures/test.git/git/description [new file with mode: 0644]
spec/fixtures/test.git/git/hooks/applypatch-msg.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/commit-msg.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/fsmonitor-watchman.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/post-update.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/pre-applypatch.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/pre-commit.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/pre-push.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/pre-rebase.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/pre-receive.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/prepare-commit-msg.sample [new file with mode: 0755]
spec/fixtures/test.git/git/hooks/update.sample [new file with mode: 0755]
spec/fixtures/test.git/git/index
spec/fixtures/test.git/git/info/exclude [new file with mode: 0644]
spec/fixtures/test.git/git/logs/HEAD
spec/fixtures/test.git/git/logs/refs/heads/curly [deleted file]
spec/fixtures/test.git/git/logs/refs/heads/hlint [new file with mode: 0644]
spec/fixtures/test.git/git/logs/refs/heads/master
spec/fixtures/test.git/git/objects/01/d6dc2234bda69a289104ffdf9667363a2414bd [deleted file]
spec/fixtures/test.git/git/objects/06/745b4cc11f505bdd1ecc84a744c3802729f92d [deleted file]
spec/fixtures/test.git/git/objects/08/cc1f13f1d655a7353040edb359c7f3ab7f8bd4 [new file with mode: 0644]
spec/fixtures/test.git/git/objects/22/2c064befc5a4f3192526863ce449c81bb74924 [deleted file]
spec/fixtures/test.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7 [deleted file]
spec/fixtures/test.git/git/objects/37/018e429ad00f0ec961bd218e3dfa6a6e8cc05b [deleted file]
spec/fixtures/test.git/git/objects/3a/6237c5feacca9a37c36bec5110a1eeb9da703b [deleted file]
spec/fixtures/test.git/git/objects/3a/efa89bfb08a4697dc441eed97005eb304364d8 [deleted file]
spec/fixtures/test.git/git/objects/45/2143142df8628483f4a2fd4a4bbff9e89ea7a6 [deleted file]
spec/fixtures/test.git/git/objects/55/3b8ba14bc0100f71f0bbe45c7ad29a088f7c15 [new file with mode: 0644]
spec/fixtures/test.git/git/objects/76/0a0807c483b0f2b949acc9cc2ba8e37d4a7ff8 [deleted file]
spec/fixtures/test.git/git/objects/77/b5c76d003b18b78c41b86e36884ce49f40c259 [deleted file]
spec/fixtures/test.git/git/objects/85/e04b1eb1a721d42db51d49e49dfeb8255a5741 [deleted file]
spec/fixtures/test.git/git/objects/92/35e9c88c2051d6949febe22fc942365a0b2546 [deleted file]
spec/fixtures/test.git/git/objects/93/1004157205727e6a47586feaed0473c6ddbd66 [deleted file]
spec/fixtures/test.git/git/objects/9f/c2abdd0895100b5876bc346dad6bbfb39e9324 [deleted file]
spec/fixtures/test.git/git/objects/c8/0c26814ee76057a8493b791e6e1a623f693e97 [new file with mode: 0644]
spec/fixtures/test.git/git/objects/cf/e8bc15022f8b4d3cea89bc20abb13f985feeb0 [deleted file]
spec/fixtures/test.git/git/objects/d0/80b4f440e8a87be90677df855a139a36bd2dc3 [deleted file]
spec/fixtures/test.git/git/objects/dd/e5c6b931572a74d0824ad8268e826ba18647b4 [new file with mode: 0644]
spec/fixtures/test.git/git/objects/e4/38134aac40ce86789d552f1bdada6582a987f6 [deleted file]
spec/fixtures/test.git/git/objects/f3/7efccc1cef20309de28bfbdd16d0c4afb9d550 [deleted file]
spec/fixtures/test.git/git/objects/f6/e267486c6b9d0f50a690c894df5e981e31c1b0 [new file with mode: 0644]
spec/fixtures/test.git/git/objects/f7/eb73cae47464f2d235a1d014c4617ad2aa0cb0 [deleted file]
spec/fixtures/test.git/git/refs/heads/curly [deleted file]
spec/fixtures/test.git/git/refs/heads/hlint [new file with mode: 0644]
spec/fixtures/test.git/git/refs/heads/master
spec/fixtures/test.git/hello.js [deleted file]
spec/fixtures/test.git/pronto.hs [new file with mode: 0644]
spec/fixtures/test.git/world.es6 [deleted file]
spec/pronto/eslint_spec.rb [deleted file]
spec/pronto/hlint_spec.rb [new file with mode: 0644]
spec/spec_helper.rb

index f78388581e367be0ce4b863d6c6cbb66e05aa58d..743adc56d2238e606879ff19b696a69e428aa631 100644 (file)
@@ -1,6 +1,4 @@
 pkg/*
 *.gem
 .bundle
-.DS_Store
-Gemfile.lock
-.byebug_history
+gems.lock
index 6a6a3d8e35c7a98eaeb47d4212cc13d1d8938003..097a15a2af39df14efb57a9212fc648b52746783 100644 (file)
@@ -1 +1 @@
-2.6.1
+2.6.2
index dab13ac6019763260694337191051c4502024ac7..74e9f59cfc829f86e4602f20e3e77c7b93fcaff9 100644 (file)
@@ -1,13 +1,8 @@
 ---
-sudo: required
-dist: xenial
-language: ruby
-before_install:
-  - gem update --system
+language: nix
 before_script:
-  - npm install -g eslint
-rvm:
-  - 2.3.8
-  - 2.4.4
-  - 2.5.3
-  - 2.6.1
+  - nix-env -iA nixpkgs.hlint nixpkgs.ruby_2_6
+  - gem install bundler
+script:
+  - bundle install
+  - bundle exec rake spec
diff --git a/LICENSE b/LICENSE
index baecb1558a763ad075b024775129fd7fb9434a93..91bb5a8d11e4ca95e8e8090a11e383400fd99e92 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License
 
-Copyright (c) 2016 Mindaugas Mozūras
+Copyright (c) 2019 Fretlink
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
index 508080ba720f20329ca05eacec31cb14b48b9ecb..7cec7d60a9bc762943feff8b474462233994ef39 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,46 +1,39 @@
-# Pronto runner for ESLint (using eslint from npm)
+# Pronto runner for Hlint
 
-[![Code Climate](https://codeclimate.com/github/doits/pronto-eslint_npm.svg)](https://codeclimate.com/github/doits/pronto-eslint_npm)
-[![Build Status](https://travis-ci.org/doits/pronto-eslint_npm.svg?branch=master)](https://travis-ci.org/doits/pronto-eslint_npm)
-[![Gem Version](https://badge.fury.io/rb/pronto-eslint_npm.svg)](http://badge.fury.io/rb/pronto-eslint_npm)
+[![Build Status](https://travis-ci.org/fretlink/pronto-hlint.svg?branch=master)](https://travis-ci.org/fretlink/pronto-hlint)
+[![Gem Version](https://badge.fury.io/rb/pronto-hlint.svg)](http://badge.fury.io/rb/pronto-hlint)
 
-Pronto runner for [ESlint](http://eslint.org), pluggable linting utility for JavaScript and JSX. [What is Pronto?](https://github.com/mmozuras/pronto)
-
-Uses official eslint executable installed by `npm` in contrast to [pronto-eslint][pronto-eslint].
-
-[pronto-eslint]: https://github.com/mmozuras/pronto-eslint
+Pronto runner for [Hlint](https://hackage.haskell.org/package/hlint), pluggable linting utility for Haskell. [What is Pronto?](https://github.com/mmozuras/pronto)
 
 ## Prerequisites
 
-You'll need to install [eslint by yourself with npm][eslint-install]. If `eslint` is in your `PATH`, everything will simply work, otherwise you have to provide pronto-eslint-npm your custom executable path (see [below](#configuration-of-eslintnpm)).
-
-[eslint-install]: http://eslint.org/docs/user-guide/getting-started
+You'll need to install [hlint by yourself with cabal or stack][hlint-install]. If `hlint` is in your `PATH`, everything will simply work, otherwise you have to provide pronto-hlint your custom executable path (see [below](#configuration-of-hlint)).
 
-## Configuration of ESLint
+[hlint-install]: https://github.com/ndmitchell/hlint#installing-and-running-hlint
 
-Configuring ESLint via [.eslintrc and consorts][eslintrc] and excludes via [.eslintignore][eslintignore] will work just fine with pronto-eslint-npm.
+## Configuration of Hlint
 
-[eslintrc]: http://eslint.org/docs/user-guide/configuring#configuration-file-formats
+Configuring Hlint via [.hlint.yaml][.hlint.yaml] will work just fine with pronto-hlint.
 
-[eslintignore]: http://eslint.org/docs/user-guide/configuring#ignoring-files-and-directories
+[.hlint.yaml]: https://github.com/ndmitchell/hlint#customizing-the-hints
 
-## Configuration of ESLintNPM
+## Configuration of Pronto-Hlint
 
-pronto-eslint-npm can be configured by placing a `.pronto_eslint_npm.yml` inside the directory where pronto is run.
+pronto-hlint can be configured by placing a `.pronto_hlint.yml` inside the directory where pronto will run.
 
 Following options are available:
 
 | Option            | Meaning                                                                                  | Default                             |
 | ----------------- | ---------------------------------------------------------------------------------------- | ----------------------------------- |
-| eslint_executable | ESLint executable to call.                                                               | `eslint` (calls `eslint` in `PATH`) |
-| files_to_lint     | What files to lint. Absolute path of offending file will be matched against this Regexp. | `(\.js|\.es6)$`                     |
-| cmd_line_opts     | Command line options to pass to eslint when running                                      | ''                                  |
+| hlint_executable  | Hlint executable to call.                                                                | `hlint` (calls `hlint` in `PATH`)   |
+| files_to_lint     | What files to lint. Absolute path of offending file will be matched against this Regexp. | `(\.hs)$`                           |
+| cmd_line_opts     | Command line options to pass to hlint when running                                       | ``                                  |
 
-Example configuration to call custom eslint executable and only lint files ending with `.my_custom_extension`:
+Example configuration to call custom hlint executable and only lint files ending with `.my_custom_extension`:
 
 ```yaml
-# .pronto_eslint_npm.yml
-eslint_executable: '/my/custom/node/path/.bin/eslint'
+# .pronto_hlint.yml
+hlint_executable: '/my/custom/path/.bin/hlint'
 files_to_lint: '\.my_custom_extension$'
-cmd_line_opts: '--ext .html,.js,.es6'
+cmd_line_opts: '-j $(nproc) --typecheck'
 ```
diff --git a/gems.locked b/gems.locked
new file mode 100644 (file)
index 0000000..9a5d599
--- /dev/null
@@ -0,0 +1,71 @@
+PATH
+  remote: .
+  specs:
+    pronto-hlint (0.1.0)
+      pronto (~> 0.10.0)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    addressable (2.5.2)
+      public_suffix (>= 2.0.2, < 4.0)
+    byebug (11.0.1)
+    diff-lcs (1.3)
+    faraday (0.15.4)
+      multipart-post (>= 1.2, < 3)
+    gitlab (4.10.0)
+      httparty (~> 0.14, >= 0.14.0)
+      terminal-table (~> 1.5, >= 1.5.1)
+    httparty (0.16.4)
+      mime-types (~> 3.0)
+      multi_xml (>= 0.5.2)
+    mime-types (3.2.2)
+      mime-types-data (~> 3.2015)
+    mime-types-data (3.2019.0331)
+    multi_xml (0.6.0)
+    multipart-post (2.0.0)
+    octokit (4.14.0)
+      sawyer (~> 0.8.0, >= 0.5.3)
+    pronto (0.10.0)
+      gitlab (~> 4.0, >= 4.0.0)
+      httparty (>= 0.13.7)
+      octokit (~> 4.7, >= 4.7.0)
+      rainbow (>= 2.2, < 4.0)
+      rugged (~> 0.24, >= 0.23.0)
+      thor (~> 0.20.0)
+    public_suffix (3.0.3)
+    rainbow (3.0.0)
+    rake (12.3.2)
+    rspec (3.8.0)
+      rspec-core (~> 3.8.0)
+      rspec-expectations (~> 3.8.0)
+      rspec-mocks (~> 3.8.0)
+    rspec-core (3.8.0)
+      rspec-support (~> 3.8.0)
+    rspec-expectations (3.8.2)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.8.0)
+    rspec-mocks (3.8.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.8.0)
+    rspec-support (3.8.0)
+    rugged (0.28.1)
+    sawyer (0.8.1)
+      addressable (>= 2.3.5, < 2.6)
+      faraday (~> 0.8, < 1.0)
+    terminal-table (1.8.0)
+      unicode-display_width (~> 1.1, >= 1.1.1)
+    thor (0.20.3)
+    unicode-display_width (1.5.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  byebug (>= 9)
+  pronto-hlint!
+  rake (>= 11.0, < 13)
+  rspec (~> 3.4)
+
+BUNDLED WITH
+   2.0.1
diff --git a/Gemfile b/gems.rb
similarity index 100%
rename from Gemfile
rename to gems.rb
diff --git a/lib/pronto/eslint_npm.rb b/lib/pronto/eslint_npm.rb
deleted file mode 100644 (file)
index 6a9c00c..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-# frozen_string_literal: true
-
-require 'pronto'
-require 'shellwords'
-
-module Pronto
-  class ESLintNpm < Runner
-    CONFIG_FILE = '.pronto_eslint_npm.yml'.freeze
-    CONFIG_KEYS = %w[eslint_executable files_to_lint cmd_line_opts].freeze
-
-    attr_writer :eslint_executable, :cmd_line_opts
-
-    def eslint_executable
-      @eslint_executable || 'eslint'
-    end
-
-    def files_to_lint
-      @files_to_lint || /(\.js|\.es6)$/
-    end
-
-    def cmd_line_opts
-      @cmd_line_opts || ''
-    end
-
-    def files_to_lint=(regexp)
-      @files_to_lint = regexp.is_a?(Regexp) && regexp || Regexp.new(regexp)
-    end
-
-    def config_options
-      @config_options ||=
-        begin
-          config_file = File.join(repo_path, CONFIG_FILE)
-          File.exist?(config_file) && YAML.load_file(config_file) || {}
-        end
-    end
-
-    def read_config
-      config_options.each do |key, val|
-        next unless CONFIG_KEYS.include?(key.to_s)
-        send("#{key}=", val)
-      end
-    end
-
-    def run
-      return [] if !@patches || @patches.count.zero?
-
-      read_config
-
-      @patches
-        .select { |patch| patch.additions > 0 }
-        .select { |patch| js_file?(patch.new_file_full_path) }
-        .map { |patch| inspect(patch) }
-        .flatten.compact
-    end
-
-    private
-
-    def repo_path
-      @repo_path ||= @patches.first.repo.path
-    end
-
-    def inspect(patch)
-      offences = run_eslint(patch)
-      clean_up_eslint_output(offences)
-        .map do |offence|
-          patch
-            .added_lines
-            .select { |line| line.new_lineno == offence['line'] }
-            .map { |line| new_message(offence, line) }
-        end
-    end
-
-    def new_message(offence, line)
-      path  = line.patch.delta.new_file[:path]
-      level = :warning
-
-      Message.new(path, line, level, offence['message'], nil, self.class)
-    end
-
-    def js_file?(path)
-      files_to_lint =~ path.to_s
-    end
-
-    def run_eslint(patch)
-      Dir.chdir(repo_path) do
-        JSON.parse `#{eslint_command_line(patch.new_file_full_path.to_s)}`
-      end
-    end
-
-    def eslint_command_line(path)
-      "#{eslint_executable} #{cmd_line_opts} #{Shellwords.escape(path)} -f json"
-    end
-
-    def clean_up_eslint_output(output)
-      # 1. Filter out offences without a warning or error
-      # 2. Get the messages for that file
-      # 3. Ignore errors without a line number for now
-      output
-        .select { |offence| offence['errorCount'] + offence['warningCount'] > 0 }
-        .map { |offence| offence['messages'] }
-        .flatten.select { |offence| offence['line'] }
-    end
-  end
-end
diff --git a/lib/pronto/eslint_npm/version.rb b/lib/pronto/eslint_npm/version.rb
deleted file mode 100644 (file)
index e3683f4..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-module Pronto
-  module ESLintNpmVersion
-    VERSION = '0.10.0'.freeze
-  end
-end
diff --git a/lib/pronto/hlint.rb b/lib/pronto/hlint.rb
new file mode 100644 (file)
index 0000000..daf1029
--- /dev/null
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require 'pronto/hlint/runner'
+
+module Pronto
+  module Hlint
+  end
+end
diff --git a/lib/pronto/hlint/runner.rb b/lib/pronto/hlint/runner.rb
new file mode 100644 (file)
index 0000000..e334860
--- /dev/null
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require 'pronto'
+require 'shellwords'
+
+module Pronto
+  module Hlint
+    class Runner < Pronto::Runner
+      CONFIG_FILE = '.pronto_hlint.yml'.freeze
+      CONFIG_KEYS = %w[hlint_executable files_to_lint cmd_line_opts].freeze
+
+      attr_writer :hlint_executable, :cmd_line_opts
+
+      def hlint_executable
+        @hlint_executable || 'hlint'
+      end
+
+      def files_to_lint
+        @files_to_lint || /(\.hs)$/
+      end
+
+      def cmd_line_opts
+        @cmd_line_opts || ''
+      end
+
+      def files_to_lint=(regexp)
+        @files_to_lint = regexp.is_a?(Regexp) && regexp || Regexp.new(regexp)
+      end
+
+      def config_options
+        @config_options ||=
+          begin
+            config_file = File.join(repo_path, CONFIG_FILE)
+            File.exist?(config_file) && YAML.load_file(config_file) || {}
+          end
+      end
+
+      def read_config
+        config_options.each do |key, val|
+          next unless CONFIG_KEYS.include?(key.to_s)
+          send("#{key}=", val)
+        end
+      end
+
+      def run
+        return [] if !@patches || @patches.count.zero?
+
+        read_config
+
+        @patches
+          .select { |patch| patch.additions > 0 }
+          .select { |patch| hs_file?(patch.new_file_full_path) }
+          .map { |patch| inspect(patch) }
+          .flatten.compact
+      end
+
+      private
+
+      def repo_path
+        @repo_path ||= @patches.first.repo.path
+      end
+
+      def inspect(patch)
+        offences = run_hlint(patch)
+        offences
+          .map do |offence|
+          patch
+            .added_lines
+            .select { |line| (offence['startLine']..offence['endLine']).include?(line.new_lineno) }
+            .map { |line| new_message(offence, line) }
+        end
+      end
+
+      def new_message(offence, line)
+        path  = line.patch.delta.new_file[:path]
+        level = hlint_severity_to_pronto_level(offence['severity']) || :warning
+
+        text = <<~EOF
+        #{offence['severity']} offence detected by Hlint. Hint is: `#{offence['hint']}`.
+
+        Consider changing the code from
+        ```
+        #{offence['from']}
+        ```
+        to
+        ```
+        #{offence['to']}
+        ```
+      EOF
+
+        Message.new(path, line, level, text, nil, self.class)
+      end
+
+      def hlint_severity_to_pronto_level(severity)
+        case severity
+        when "Error"
+          :error
+        when "Warning"
+          :warning
+        when "Suggestion"
+          :info
+        end
+      end
+
+      def hs_file?(path)
+        files_to_lint =~ path.to_s
+      end
+
+      def run_hlint(patch)
+        Dir.chdir(repo_path) do
+          JSON.parse `#{hlint_command_line(patch.new_file_full_path.to_s)}`
+        end
+      end
+
+      def hlint_command_line(path)
+        "#{hlint_executable} #{cmd_line_opts} #{Shellwords.escape(path)} --json"
+      end
+    end
+  end
+end
diff --git a/lib/pronto/hlint/version.rb b/lib/pronto/hlint/version.rb
new file mode 100644 (file)
index 0000000..0b9bd5a
--- /dev/null
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Pronto
+  module Hlint
+    VERSION = '0.1.0'.freeze
+  end
+end
similarity index 62%
rename from pronto-eslint_npm.gemspec
rename to pronto-hlint.gemspec
index 2a70f2fc16e727b846d1731ffa85329af3e25684..2d5679207788f21662ecf27b143271552327a127 100644 (file)
@@ -1,17 +1,17 @@
 # frozen_string_literal: true
 
 $LOAD_PATH.push File.expand_path('lib', __dir__)
-require 'pronto/eslint_npm/version'
+require 'pronto/hlint/version'
 
 Gem::Specification.new do |s|
-  s.name     = 'pronto-eslint_npm'
-  s.version  = Pronto::ESLintNpmVersion::VERSION
+  s.name     = 'pronto-hlint'
+  s.version  = Pronto::Hlint::VERSION
   s.platform = Gem::Platform::RUBY
-  s.authors  = ['Markus Doits', 'Mindaugas Mozūras']
-  s.email    = 'markus.doits@gmail.com'
-  s.homepage = 'https://github.com/doits/pronto-eslint_npm'
+  s.authors  = ['Paul Bonaud']
+  s.email    = 'paul.bonaud@fretlink.com'
+  s.homepage = 'https://github.com/fretlink/pronto-hlint'
   s.summary  = <<-EOF
-    Pronto runner for ESLint, pluggable linting utility for JavaScript and JSX
+    Pronto runner for Hlint, pluggable linting utility for Haskell
   EOF
 
   s.licenses              = ['MIT']
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
   s.files            = `git ls-files -z`.split("\x0").select { |f| f.match(%r{^(lib/|(LICENSE|README.md)$)}) }
   s.extra_rdoc_files = ['LICENSE', 'README.md']
   s.require_paths    = ['lib']
-  s.requirements << 'eslint (in PATH)'
+  s.requirements << 'hlint (in PATH)'
 
   s.add_dependency('pronto', '~> 0.10.0')
   s.add_development_dependency('byebug', '>= 9')
diff --git a/spec/fixtures/eslintignore.git/.eslintignore b/spec/fixtures/eslintignore.git/.eslintignore
deleted file mode 100644 (file)
index d85195b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-ignored/**/*.js
-!ignored/not_ignored.js
diff --git a/spec/fixtures/eslintignore.git/.eslintrc b/spec/fixtures/eslintignore.git/.eslintrc
deleted file mode 100644 (file)
index f94ba96..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "env": {
-        "browser": true,
-        "es6": true
-    },
-    "extends": "eslint:recommended"
-}
diff --git a/spec/fixtures/eslintignore.git/git/HEAD b/spec/fixtures/eslintignore.git/git/HEAD
deleted file mode 100644 (file)
index fac958f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-ref: refs/heads/eslintignore
diff --git a/spec/fixtures/eslintignore.git/git/config b/spec/fixtures/eslintignore.git/git/config
deleted file mode 100644 (file)
index 6c9406b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[core]
-       repositoryformatversion = 0
-       filemode = true
-       bare = false
-       logallrefupdates = true
-       ignorecase = true
-       precomposeunicode = true
diff --git a/spec/fixtures/eslintignore.git/git/index b/spec/fixtures/eslintignore.git/git/index
deleted file mode 100644 (file)
index 8c5575c..0000000
Binary files a/spec/fixtures/eslintignore.git/git/index and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/logs/HEAD b/spec/fixtures/eslintignore.git/git/logs/HEAD
deleted file mode 100644 (file)
index 8750baa..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-0000000000000000000000000000000000000000 d43de0396c81608113f99f7afd00f7f363e1cae8 Markus Doits <markus.doits@stellenticket.de> 1469450052 +0200        commit (initial): empty init commit
-d43de0396c81608113f99f7afd00f7f363e1cae8 d43de0396c81608113f99f7afd00f7f363e1cae8 Markus Doits <markus.doits@stellenticket.de> 1469450062 +0200        checkout: moving from master to eslintignore
-d43de0396c81608113f99f7afd00f7f363e1cae8 5ffc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53 Markus Doits <markus.doits@stellenticket.de> 1469450067 +0200        commit: add .eslintignore and files with errors
diff --git a/spec/fixtures/eslintignore.git/git/logs/refs/heads/eslintignore b/spec/fixtures/eslintignore.git/git/logs/refs/heads/eslintignore
deleted file mode 100644 (file)
index 3467ecc..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-0000000000000000000000000000000000000000 d43de0396c81608113f99f7afd00f7f363e1cae8 Markus Doits <markus.doits@stellenticket.de> 1469450062 +0200        branch: Created from HEAD
-d43de0396c81608113f99f7afd00f7f363e1cae8 5ffc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53 Markus Doits <markus.doits@stellenticket.de> 1469450067 +0200        commit: add .eslintignore and files with errors
diff --git a/spec/fixtures/eslintignore.git/git/logs/refs/heads/master b/spec/fixtures/eslintignore.git/git/logs/refs/heads/master
deleted file mode 100644 (file)
index 8105749..0000000
+++ /dev/null
@@ -1 +0,0 @@
-0000000000000000000000000000000000000000 d43de0396c81608113f99f7afd00f7f363e1cae8 Markus Doits <markus.doits@stellenticket.de> 1469450052 +0200        commit (initial): empty init commit
diff --git a/spec/fixtures/eslintignore.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7 b/spec/fixtures/eslintignore.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7
deleted file mode 100644 (file)
index f5fbdc5..0000000
Binary files a/spec/fixtures/eslintignore.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7 and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/spec/fixtures/eslintignore.git/git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
deleted file mode 100644 (file)
index adf6411..0000000
Binary files a/spec/fixtures/eslintignore.git/git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/objects/5f/fc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53 b/spec/fixtures/eslintignore.git/git/objects/5f/fc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53
deleted file mode 100644 (file)
index 832698f..0000000
Binary files a/spec/fixtures/eslintignore.git/git/objects/5f/fc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53 and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/objects/69/7ffd3c693fce9abcb871b9b47e2d116e6241d3 b/spec/fixtures/eslintignore.git/git/objects/69/7ffd3c693fce9abcb871b9b47e2d116e6241d3
deleted file mode 100644 (file)
index c23a96f..0000000
Binary files a/spec/fixtures/eslintignore.git/git/objects/69/7ffd3c693fce9abcb871b9b47e2d116e6241d3 and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/objects/d4/3de0396c81608113f99f7afd00f7f363e1cae8 b/spec/fixtures/eslintignore.git/git/objects/d4/3de0396c81608113f99f7afd00f7f363e1cae8
deleted file mode 100644 (file)
index e3c829c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-x\ 1¥\8fK
-Â0\10@]ç\14³\17Ê\18&!\ 1\11\17n=D>S\fmZI¦\vo¯Ö#¸|\9b÷xi­µ\b\aiÌ@Ñi\93\93%\9d¢åè\ 3ZdCqtÙzíÜ\18\99É#©°Écmp\ fmÚ:ÜÖ"\1dÎu§!\7féÚ\85ç\99\17)ib\192_àDÖ\93A4\1a\8e¨\11UÚëÂÿz\14ק¼ ,\9f\95\9f\ 1\85ïEµ
\ No newline at end of file
diff --git a/spec/fixtures/eslintignore.git/git/objects/d8/5195b5ff74cc05d121b758f00da43018f53b6f b/spec/fixtures/eslintignore.git/git/objects/d8/5195b5ff74cc05d121b758f00da43018f53b6f
deleted file mode 100644 (file)
index ee9657e..0000000
Binary files a/spec/fixtures/eslintignore.git/git/objects/d8/5195b5ff74cc05d121b758f00da43018f53b6f and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/objects/ec/7b4537cbd327a580ee44b74ff02fffc74feb46 b/spec/fixtures/eslintignore.git/git/objects/ec/7b4537cbd327a580ee44b74ff02fffc74feb46
deleted file mode 100644 (file)
index 9a642e0..0000000
Binary files a/spec/fixtures/eslintignore.git/git/objects/ec/7b4537cbd327a580ee44b74ff02fffc74feb46 and /dev/null differ
diff --git a/spec/fixtures/eslintignore.git/git/refs/heads/eslintignore b/spec/fixtures/eslintignore.git/git/refs/heads/eslintignore
deleted file mode 100644 (file)
index d02562a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5ffc9b3c7f8e8d8f2e8c91cb69c9698405d1ca53
diff --git a/spec/fixtures/eslintignore.git/git/refs/heads/master b/spec/fixtures/eslintignore.git/git/refs/heads/master
deleted file mode 100644 (file)
index 5dcf161..0000000
+++ /dev/null
@@ -1 +0,0 @@
-d43de0396c81608113f99f7afd00f7f363e1cae8
diff --git a/spec/fixtures/eslintignore.git/ignored/ignored.js b/spec/fixtures/eslintignore.git/ignored/ignored.js
deleted file mode 100644 (file)
index 2d1b996..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-function HelloWorld(name)
-{
-    if (foo) foo++;
-    alert(name);
-}
diff --git a/spec/fixtures/eslintignore.git/ignored/not_ignored.js b/spec/fixtures/eslintignore.git/ignored/not_ignored.js
deleted file mode 100644 (file)
index 2d1b996..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-function HelloWorld(name)
-{
-    if (foo) foo++;
-    alert(name);
-}
diff --git a/spec/fixtures/test.git/.eslintrc b/spec/fixtures/test.git/.eslintrc
deleted file mode 100644 (file)
index f94ba96..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "env": {
-        "browser": true,
-        "es6": true
-    },
-    "extends": "eslint:recommended"
-}
diff --git a/spec/fixtures/test.git/custom_eslint.sh b/spec/fixtures/test.git/custom_eslint.sh
deleted file mode 100755 (executable)
index 54fafdc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-printf 'custom eslint called'
diff --git a/spec/fixtures/test.git/custom_hlint.sh b/spec/fixtures/test.git/custom_hlint.sh
new file mode 100755 (executable)
index 0000000..c80c268
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+echo "hlint called!"
diff --git a/spec/fixtures/test.git/git/COMMIT_EDITMSG b/spec/fixtures/test.git/git/COMMIT_EDITMSG
new file mode 100644 (file)
index 0000000..d788b46
--- /dev/null
@@ -0,0 +1 @@
+Add hs files with hlint errors
index c15524d15ab58ec1a13ad432591ae0d6c73108e2..feb5fdb960472478f62f63294ac14906ed5d36d1 100644 (file)
@@ -1 +1 @@
-ref: refs/heads/curly
+ref: refs/heads/hlint
index 6c9406b7d9320db083eca69b3f8bee9a6c7b50d4..515f4836297fdf7567c066983c16e5eff598f7bd 100644 (file)
@@ -3,5 +3,3 @@
        filemode = true
        bare = false
        logallrefupdates = true
-       ignorecase = true
-       precomposeunicode = true
diff --git a/spec/fixtures/test.git/git/description b/spec/fixtures/test.git/git/description
new file mode 100644 (file)
index 0000000..498b267
--- /dev/null
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/spec/fixtures/test.git/git/hooks/applypatch-msg.sample b/spec/fixtures/test.git/git/hooks/applypatch-msg.sample
new file mode 100755 (executable)
index 0000000..a5d7b84
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
+test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
+:
diff --git a/spec/fixtures/test.git/git/hooks/commit-msg.sample b/spec/fixtures/test.git/git/hooks/commit-msg.sample
new file mode 100755 (executable)
index 0000000..b58d118
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+        sort | uniq -c | sed -e '/^[   ]*1[    ]/d')" || {
+       echo >&2 Duplicate Signed-off-by lines.
+       exit 1
+}
diff --git a/spec/fixtures/test.git/git/hooks/fsmonitor-watchman.sample b/spec/fixtures/test.git/git/hooks/fsmonitor-watchman.sample
new file mode 100755 (executable)
index 0000000..e673bb3
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use IPC::Open2;
+
+# An example hook script to integrate Watchman
+# (https://facebook.github.io/watchman/) with git to speed up detecting
+# new and modified files.
+#
+# The hook is passed a version (currently 1) and a time in nanoseconds
+# formatted as a string and outputs to stdout all files that have been
+# modified since the given time. Paths must be relative to the root of
+# the working tree and separated by a single NUL.
+#
+# To enable this hook, rename this file to "query-watchman" and set
+# 'git config core.fsmonitor .git/hooks/query-watchman'
+#
+my ($version, $time) = @ARGV;
+
+# Check the hook interface version
+
+if ($version == 1) {
+       # convert nanoseconds to seconds
+       $time = int $time / 1000000000;
+} else {
+       die "Unsupported query-fsmonitor hook version '$version'.\n" .
+           "Falling back to scanning...\n";
+}
+
+my $git_work_tree;
+if ($^O =~ 'msys' || $^O =~ 'cygwin') {
+       $git_work_tree = Win32::GetCwd();
+       $git_work_tree =~ tr/\\/\//;
+} else {
+       require Cwd;
+       $git_work_tree = Cwd::cwd();
+}
+
+my $retry = 1;
+
+launch_watchman();
+
+sub launch_watchman {
+
+       my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
+           or die "open2() failed: $!\n" .
+           "Falling back to scanning...\n";
+
+       # In the query expression below we're asking for names of files that
+       # changed since $time but were not transient (ie created after
+       # $time but no longer exist).
+       #
+       # To accomplish this, we're using the "since" generator to use the
+       # recency index to select candidate nodes and "fields" to limit the
+       # output to file names only. Then we're using the "expression" term to
+       # further constrain the results.
+       #
+       # The category of transient files that we want to ignore will have a
+       # creation clock (cclock) newer than $time_t value and will also not
+       # currently exist.
+
+       my $query = <<" END";
+               ["query", "$git_work_tree", {
+                       "since": $time,
+                       "fields": ["name"],
+                       "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
+               }]
+       END
+
+       print CHLD_IN $query;
+       close CHLD_IN;
+       my $response = do {local $/; <CHLD_OUT>};
+
+       die "Watchman: command returned no output.\n" .
+           "Falling back to scanning...\n" if $response eq "";
+       die "Watchman: command returned invalid output: $response\n" .
+           "Falling back to scanning...\n" unless $response =~ /^\{/;
+
+       my $json_pkg;
+       eval {
+               require JSON::XS;
+               $json_pkg = "JSON::XS";
+               1;
+       } or do {
+               require JSON::PP;
+               $json_pkg = "JSON::PP";
+       };
+
+       my $o = $json_pkg->new->utf8->decode($response);
+
+       if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
+               print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
+               $retry--;
+               qx/watchman watch "$git_work_tree"/;
+               die "Failed to make watchman watch '$git_work_tree'.\n" .
+                   "Falling back to scanning...\n" if $? != 0;
+
+               # Watchman will always return all files on the first query so
+               # return the fast "everything is dirty" flag to git and do the
+               # Watchman query just to get it over with now so we won't pay
+               # the cost in git to look up each individual file.
+               print "/\0";
+               eval { launch_watchman() };
+               exit 0;
+       }
+
+       die "Watchman: $o->{error}.\n" .
+           "Falling back to scanning...\n" if $o->{error};
+
+       binmode STDOUT, ":utf8";
+       local $, = "\0";
+       print @{$o->{files}};
+}
diff --git a/spec/fixtures/test.git/git/hooks/post-update.sample b/spec/fixtures/test.git/git/hooks/post-update.sample
new file mode 100755 (executable)
index 0000000..ec17ec1
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
diff --git a/spec/fixtures/test.git/git/hooks/pre-applypatch.sample b/spec/fixtures/test.git/git/hooks/pre-applypatch.sample
new file mode 100755 (executable)
index 0000000..4142082
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+precommit="$(git rev-parse --git-path hooks/pre-commit)"
+test -x "$precommit" && exec "$precommit" ${1+"$@"}
+:
diff --git a/spec/fixtures/test.git/git/hooks/pre-commit.sample b/spec/fixtures/test.git/git/hooks/pre-commit.sample
new file mode 100755 (executable)
index 0000000..6a75641
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+       against=HEAD
+else
+       # Initial commit: diff against an empty tree object
+       against=$(git hash-object -t tree /dev/null)
+fi
+
+# If you want to allow non-ASCII filenames set this variable to true.
+allownonascii=$(git config --bool hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ASCII filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+       # Note that the use of brackets around a tr range is ok here, (it's
+       # even required, for portability to Solaris 10's /usr/bin/tr), since
+       # the square bracket bytes happen to fall in the designated range.
+       test $(git diff --cached --name-only --diff-filter=A -z $against |
+         LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+       cat <<\EOF
+Error: Attempt to add a non-ASCII file name.
+
+This can cause problems if you want to work with people on other platforms.
+
+To be portable it is advisable to rename the file.
+
+If you know what you are doing you can disable this check using:
+
+  git config hooks.allownonascii true
+EOF
+       exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
diff --git a/spec/fixtures/test.git/git/hooks/pre-push.sample b/spec/fixtures/test.git/git/hooks/pre-push.sample
new file mode 100755 (executable)
index 0000000..6187dbf
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# An example hook script to verify what is about to be pushed.  Called by "git
+# push" after it has checked the remote status, but before anything has been
+# pushed.  If this script exits with a non-zero status nothing will be pushed.
+#
+# This hook is called with the following parameters:
+#
+# $1 -- Name of the remote to which the push is being done
+# $2 -- URL to which the push is being done
+#
+# If pushing without using a named remote those arguments will be equal.
+#
+# Information about the commits which are being pushed is supplied as lines to
+# the standard input in the form:
+#
+#   <local ref> <local sha1> <remote ref> <remote sha1>
+#
+# This sample shows how to prevent push of commits where the log message starts
+# with "WIP" (work in progress).
+
+remote="$1"
+url="$2"
+
+z40=0000000000000000000000000000000000000000
+
+while read local_ref local_sha remote_ref remote_sha
+do
+       if [ "$local_sha" = $z40 ]
+       then
+               # Handle delete
+               :
+       else
+               if [ "$remote_sha" = $z40 ]
+               then
+                       # New branch, examine all commits
+                       range="$local_sha"
+               else
+                       # Update to existing branch, examine new commits
+                       range="$remote_sha..$local_sha"
+               fi
+
+               # Check for WIP commit
+               commit=`git rev-list -n 1 --grep '^WIP' "$range"`
+               if [ -n "$commit" ]
+               then
+                       echo >&2 "Found WIP commit in $local_ref, not pushing"
+                       exit 1
+               fi
+       fi
+done
+
+exit 0
diff --git a/spec/fixtures/test.git/git/hooks/pre-rebase.sample b/spec/fixtures/test.git/git/hooks/pre-rebase.sample
new file mode 100755 (executable)
index 0000000..6cbef5c
--- /dev/null
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+       topic="refs/heads/$2"
+else
+       topic=`git symbolic-ref HEAD` ||
+       exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+       ;;
+*)
+       exit 0 ;# we do not interrupt others.
+       ;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+       echo >&2 "No such branch $topic"
+       exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+       echo >&2 "$topic is fully merged to master; better remove it."
+       exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+       not_in_topic=`git rev-list "^$topic" master`
+       if test -z "$not_in_topic"
+       then
+               echo >&2 "$topic is already up to date with master"
+               exit 1 ;# we could allow it, but there is no point.
+       else
+               exit 0
+       fi
+else
+       not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+       /usr/bin/perl -e '
+               my $topic = $ARGV[0];
+               my $msg = "* $topic has commits already merged to public branch:\n";
+               my (%not_in_next) = map {
+                       /^([0-9a-f]+) /;
+                       ($1 => 1);
+               } split(/\n/, $ARGV[1]);
+               for my $elem (map {
+                               /^([0-9a-f]+) (.*)$/;
+                               [$1 => $2];
+                       } split(/\n/, $ARGV[2])) {
+                       if (!exists $not_in_next{$elem->[0]}) {
+                               if ($msg) {
+                                       print STDERR $msg;
+                                       undef $msg;
+                               }
+                               print STDERR " $elem->[1]\n";
+                       }
+               }
+       ' "$topic" "$not_in_next" "$not_in_master"
+       exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+                  o---o---o---o---o---o---o---o---o---o "next"
+                 /       /           /           /
+                /   a---a---b A     /           /
+               /   /               /           /
+              /   /   c---c---c---c B         /
+             /   /   /             \         /
+            /   /   /   b---b C     \       /
+           /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+       git rev-list ^master ^topic next
+       git rev-list ^master        next
+
+       if these match, topic has not merged in next at all.
+
+To compute (2):
+
+       git rev-list master..topic
+
+       if this is empty, it is fully merged to "master".
+
+DOC_END
diff --git a/spec/fixtures/test.git/git/hooks/pre-receive.sample b/spec/fixtures/test.git/git/hooks/pre-receive.sample
new file mode 100755 (executable)
index 0000000..a1fd29e
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to make use of push options.
+# The example simply echoes all push options that start with 'echoback='
+# and rejects all pushes when the "reject" push option is used.
+#
+# To enable this hook, rename this file to "pre-receive".
+
+if test -n "$GIT_PUSH_OPTION_COUNT"
+then
+       i=0
+       while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
+       do
+               eval "value=\$GIT_PUSH_OPTION_$i"
+               case "$value" in
+               echoback=*)
+                       echo "echo from the pre-receive-hook: ${value#*=}" >&2
+                       ;;
+               reject)
+                       exit 1
+               esac
+               i=$((i + 1))
+       done
+fi
diff --git a/spec/fixtures/test.git/git/hooks/prepare-commit-msg.sample b/spec/fixtures/test.git/git/hooks/prepare-commit-msg.sample
new file mode 100755 (executable)
index 0000000..10fa14c
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples. The first one removes the
+# "# Please enter the commit message..." help message.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+COMMIT_MSG_FILE=$1
+COMMIT_SOURCE=$2
+SHA1=$3
+
+/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
+
+# case "$COMMIT_SOURCE,$SHA1" in
+#  ,|template,)
+#    /usr/bin/perl -i.bak -pe '
+#       print "\n" . `git diff --cached --name-status -r`
+#       if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
+#  *) ;;
+# esac
+
+# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
+# if test -z "$COMMIT_SOURCE"
+# then
+#   /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
+# fi
diff --git a/spec/fixtures/test.git/git/hooks/update.sample b/spec/fixtures/test.git/git/hooks/update.sample
new file mode 100755 (executable)
index 0000000..80ba941
--- /dev/null
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to block unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+       echo "Don't run this script from the command line." >&2
+       echo " (if you want, you could supply GIT_DIR then run" >&2
+       echo "  $0 <ref> <oldrev> <newrev>)" >&2
+       exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+       echo "usage: $0 <ref> <oldrev> <newrev>" >&2
+       exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+       echo "*** Project description file hasn't been set" >&2
+       exit 1
+       ;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+       newrev_type=delete
+else
+       newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+       refs/tags/*,commit)
+               # un-annotated tag
+               short_refname=${refname##refs/tags/}
+               if [ "$allowunannotated" != "true" ]; then
+                       echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+                       echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+                       exit 1
+               fi
+               ;;
+       refs/tags/*,delete)
+               # delete tag
+               if [ "$allowdeletetag" != "true" ]; then
+                       echo "*** Deleting a tag is not allowed in this repository" >&2
+                       exit 1
+               fi
+               ;;
+       refs/tags/*,tag)
+               # annotated tag
+               if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+               then
+                       echo "*** Tag '$refname' already exists." >&2
+                       echo "*** Modifying a tag is not allowed in this repository." >&2
+                       exit 1
+               fi
+               ;;
+       refs/heads/*,commit)
+               # branch
+               if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+                       echo "*** Creating a branch is not allowed in this repository" >&2
+                       exit 1
+               fi
+               ;;
+       refs/heads/*,delete)
+               # delete branch
+               if [ "$allowdeletebranch" != "true" ]; then
+                       echo "*** Deleting a branch is not allowed in this repository" >&2
+                       exit 1
+               fi
+               ;;
+       refs/remotes/*,commit)
+               # tracking branch
+               ;;
+       refs/remotes/*,delete)
+               # delete tracking branch
+               if [ "$allowdeletebranch" != "true" ]; then
+                       echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+                       exit 1
+               fi
+               ;;
+       *)
+               # Anything else (is there anything else?)
+               echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+               exit 1
+               ;;
+esac
+
+# --- Finished
+exit 0
index 0b50aa9dba5e1558b06b0be6111dfb76abf9adc6..7117c7cf68fe6fc8a6921eaf8d391a01f1c81a6f 100644 (file)
Binary files a/spec/fixtures/test.git/git/index and b/spec/fixtures/test.git/git/index differ
diff --git a/spec/fixtures/test.git/git/info/exclude b/spec/fixtures/test.git/git/info/exclude
new file mode 100644 (file)
index 0000000..a5196d1
--- /dev/null
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
index a4f13f80294260ff6a0b2e94923b272d2e049e01..27f5b748e9a188921094af84126aa618444b4114 100644 (file)
@@ -1,14 +1,3 @@
-0000000000000000000000000000000000000000 f37efccc1cef20309de28bfbdd16d0c4afb9d550 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1433058807 +0300    commit (initial): Initial commit
-f37efccc1cef20309de28bfbdd16d0c4afb9d550 f37efccc1cef20309de28bfbdd16d0c4afb9d550 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1433058814 +0300    checkout: moving from master to semicolon
-f37efccc1cef20309de28bfbdd16d0c4afb9d550 f7eb73cae47464f2d235a1d014c4617ad2aa0cb0 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1433058820 +0300    commit: Remove semicolon
-f7eb73cae47464f2d235a1d014c4617ad2aa0cb0 f37efccc1cef20309de28bfbdd16d0c4afb9d550 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673968 +0200    checkout: moving from semicolon to master
-f37efccc1cef20309de28bfbdd16d0c4afb9d550 85e04b1eb1a721d42db51d49e49dfeb8255a5741 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673985 +0200    commit (amend): Initial commit
-85e04b1eb1a721d42db51d49e49dfeb8255a5741 f7eb73cae47464f2d235a1d014c4617ad2aa0cb0 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673990 +0200    checkout: moving from master to semicolon
-f7eb73cae47464f2d235a1d014c4617ad2aa0cb0 85e04b1eb1a721d42db51d49e49dfeb8255a5741 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673992 +0200    rebase: checkout master
-85e04b1eb1a721d42db51d49e49dfeb8255a5741 e438134aac40ce86789d552f1bdada6582a987f6 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673992 +0200    rebase: Remove semicolon
-e438134aac40ce86789d552f1bdada6582a987f6 e438134aac40ce86789d552f1bdada6582a987f6 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673992 +0200    rebase finished: returning to refs/heads/semicolon
-e438134aac40ce86789d552f1bdada6582a987f6 85e04b1eb1a721d42db51d49e49dfeb8255a5741 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674159 +0200    checkout: moving from semicolon to master
-85e04b1eb1a721d42db51d49e49dfeb8255a5741 931004157205727e6a47586feaed0473c6ddbd66 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674164 +0200    commit (amend): Initial commit
-931004157205727e6a47586feaed0473c6ddbd66 931004157205727e6a47586feaed0473c6ddbd66 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674177 +0200    checkout: moving from master to curly
-931004157205727e6a47586feaed0473c6ddbd66 3a6237c5feacca9a37c36bec5110a1eeb9da703b Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674189 +0200    commit: Add a line of code that does not have the correct curlies (eslint)
-3a6237c5feacca9a37c36bec5110a1eeb9da703b 37018e429ad00f0ec961bd218e3dfa6a6e8cc05b Markus Doits <markus.doits@stellenticket.de> 1460316876 +0200        commit: add es6 file
+0000000000000000000000000000000000000000 08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 Paul Bonaud <paul.bonaud@fretlink.com> 1555165913 +0200      commit (initial): Initial commit
+08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 Paul Bonaud <paul.bonaud@fretlink.com> 1555165937 +0200      checkout: moving from master to hlint
+08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 553b8ba14bc0100f71f0bbe45c7ad29a088f7c15 Paul Bonaud <paul.bonaud@fretlink.com> 1555165977 +0200      commit: Add hs files with hlint errors
diff --git a/spec/fixtures/test.git/git/logs/refs/heads/curly b/spec/fixtures/test.git/git/logs/refs/heads/curly
deleted file mode 100644 (file)
index 11582e5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-0000000000000000000000000000000000000000 931004157205727e6a47586feaed0473c6ddbd66 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674177 +0200    branch: Created from HEAD
-931004157205727e6a47586feaed0473c6ddbd66 3a6237c5feacca9a37c36bec5110a1eeb9da703b Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674189 +0200    commit: Add a line of code that does not have the correct curlies (eslint)
-3a6237c5feacca9a37c36bec5110a1eeb9da703b 37018e429ad00f0ec961bd218e3dfa6a6e8cc05b Markus Doits <markus.doits@stellenticket.de> 1460316876 +0200        commit: add es6 file
diff --git a/spec/fixtures/test.git/git/logs/refs/heads/hlint b/spec/fixtures/test.git/git/logs/refs/heads/hlint
new file mode 100644 (file)
index 0000000..8ed043d
--- /dev/null
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 Paul Bonaud <paul.bonaud@fretlink.com> 1555165928 +0200      branch: Created from master
+08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 553b8ba14bc0100f71f0bbe45c7ad29a088f7c15 Paul Bonaud <paul.bonaud@fretlink.com> 1555165977 +0200      commit: Add hs files with hlint errors
index 752c737eecb22b78a545212033e4826909bf3517..4bcbe1d1f7d202f8e99fab3fdb648333b446f057 100644 (file)
@@ -1,3 +1 @@
-0000000000000000000000000000000000000000 f37efccc1cef20309de28bfbdd16d0c4afb9d550 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1433058807 +0300    commit (initial): Initial commit
-f37efccc1cef20309de28bfbdd16d0c4afb9d550 85e04b1eb1a721d42db51d49e49dfeb8255a5741 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456673985 +0200    commit (amend): Initial commit
-85e04b1eb1a721d42db51d49e49dfeb8255a5741 931004157205727e6a47586feaed0473c6ddbd66 Mindaugas Mozūras <mindaugas.mozuras@gmail.com> 1456674164 +0200    commit (amend): Initial commit
+0000000000000000000000000000000000000000 08cc1f13f1d655a7353040edb359c7f3ab7f8bd4 Paul Bonaud <paul.bonaud@fretlink.com> 1555165913 +0200      commit (initial): Initial commit
diff --git a/spec/fixtures/test.git/git/objects/01/d6dc2234bda69a289104ffdf9667363a2414bd b/spec/fixtures/test.git/git/objects/01/d6dc2234bda69a289104ffdf9667363a2414bd
deleted file mode 100644 (file)
index b4fe9ea..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-x\ 1¥\8eA
-Â0\10E]ç\14³\17d\92Ø\98\82\88\v·\1eb2\99`°µÒLÑã[½\82»ÿ>\9fÇçi\1c«\82\vv£³\bp\91\98Øvè\\89i\9f=\vÅ>±CJÉúÒÇ®\88$4O\9aå¡à)8\7fàµ$fêiÍ>$áÎZ$».ûL\aôÉТ·i\86+Í÷¥ÁeªÚà8þh\97¿tn*ð:+ßEwYN`÷\ 1½\r]\f°E\87hø÷Vå_\8f¡\9c¡ÔAàUõ\ 6Ò\ 2´¥\94ú6\1f1CW\10
\ No newline at end of file
diff --git a/spec/fixtures/test.git/git/objects/06/745b4cc11f505bdd1ecc84a744c3802729f92d b/spec/fixtures/test.git/git/objects/06/745b4cc11f505bdd1ecc84a744c3802729f92d
deleted file mode 100644 (file)
index d0554e9..0000000
Binary files a/spec/fixtures/test.git/git/objects/06/745b4cc11f505bdd1ecc84a744c3802729f92d and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/08/cc1f13f1d655a7353040edb359c7f3ab7f8bd4 b/spec/fixtures/test.git/git/objects/08/cc1f13f1d655a7353040edb359c7f3ab7f8bd4
new file mode 100644 (file)
index 0000000..597935d
Binary files /dev/null and b/spec/fixtures/test.git/git/objects/08/cc1f13f1d655a7353040edb359c7f3ab7f8bd4 differ
diff --git a/spec/fixtures/test.git/git/objects/22/2c064befc5a4f3192526863ce449c81bb74924 b/spec/fixtures/test.git/git/objects/22/2c064befc5a4f3192526863ce449c81bb74924
deleted file mode 100644 (file)
index 6fcbf2f..0000000
Binary files a/spec/fixtures/test.git/git/objects/22/2c064befc5a4f3192526863ce449c81bb74924 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7 b/spec/fixtures/test.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7
deleted file mode 100644 (file)
index f5fbdc5..0000000
Binary files a/spec/fixtures/test.git/git/objects/2d/1b9966feb19d665a9e5bb6a5bde410203a68f7 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/37/018e429ad00f0ec961bd218e3dfa6a6e8cc05b b/spec/fixtures/test.git/git/objects/37/018e429ad00f0ec961bd218e3dfa6a6e8cc05b
deleted file mode 100644 (file)
index 1d5c313..0000000
+++ /dev/null
@@ -1 +0,0 @@
-x\ 1¥ÎA\ e \10\85\9cbö&\r\14\18 1Æ\85[\ f1\fÓØØZSèý­½\82»÷o¾<^æylлtj«\b\84\90=\a,ZÛlb\ e\91\9dÉ\11Åb\8c\8eÅ¥Áiî}R\1fZåÝÀ\12ö6°\1f\84\98)Ѿ-fao\8c&#\92S¡°[\8a¶ö\VxÐúÚ*Ü\97±U¸ÌGuåW·Úd\9avsä\97´®È\15\8cCm\rÆ\80pÖ½Ö\8a\8f·Mþu\14\95\ 2R\11\86q\12õ\ 5Õ\97
\ No newline at end of file
diff --git a/spec/fixtures/test.git/git/objects/3a/6237c5feacca9a37c36bec5110a1eeb9da703b b/spec/fixtures/test.git/git/objects/3a/6237c5feacca9a37c36bec5110a1eeb9da703b
deleted file mode 100644 (file)
index a1399be..0000000
Binary files a/spec/fixtures/test.git/git/objects/3a/6237c5feacca9a37c36bec5110a1eeb9da703b and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/3a/efa89bfb08a4697dc441eed97005eb304364d8 b/spec/fixtures/test.git/git/objects/3a/efa89bfb08a4697dc441eed97005eb304364d8
deleted file mode 100644 (file)
index c8a6c16..0000000
Binary files a/spec/fixtures/test.git/git/objects/3a/efa89bfb08a4697dc441eed97005eb304364d8 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/45/2143142df8628483f4a2fd4a4bbff9e89ea7a6 b/spec/fixtures/test.git/git/objects/45/2143142df8628483f4a2fd4a4bbff9e89ea7a6
deleted file mode 100644 (file)
index 8a65f33..0000000
Binary files a/spec/fixtures/test.git/git/objects/45/2143142df8628483f4a2fd4a4bbff9e89ea7a6 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/55/3b8ba14bc0100f71f0bbe45c7ad29a088f7c15 b/spec/fixtures/test.git/git/objects/55/3b8ba14bc0100f71f0bbe45c7ad29a088f7c15
new file mode 100644 (file)
index 0000000..e5eac74
--- /dev/null
@@ -0,0 +1 @@
+x\ 1\9d\8eK\8aÃ0\10\ 5g­Sô>\10Z\96[\1f\bÃ$'È\15ôéÆfl+È2sý19B\96õ\16õ*×u\9d;\fD_½1\83X\1e¬\e½Í6\85\82B\18mÀìÃX\848xÍFg\9dP½bã­\ 3ú\9cµh#ºX¢è\f\19\1c\91K2\14²\13\13\93\13\9fʨâѧÚà\19\8f\ 5\1eu\8bG\81Ûë\84kzÃ\8f4î˼ý^s]¿A\13\91\14\9c\83\v\ e\88ê\ÏÎÎ\9f\eÔ½\14\98v\90\1dþæ>Át\1evàÖjÛÕ?îØR4
\ No newline at end of file
diff --git a/spec/fixtures/test.git/git/objects/76/0a0807c483b0f2b949acc9cc2ba8e37d4a7ff8 b/spec/fixtures/test.git/git/objects/76/0a0807c483b0f2b949acc9cc2ba8e37d4a7ff8
deleted file mode 100644 (file)
index 5175450..0000000
Binary files a/spec/fixtures/test.git/git/objects/76/0a0807c483b0f2b949acc9cc2ba8e37d4a7ff8 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/77/b5c76d003b18b78c41b86e36884ce49f40c259 b/spec/fixtures/test.git/git/objects/77/b5c76d003b18b78c41b86e36884ce49f40c259
deleted file mode 100644 (file)
index db2600a..0000000
Binary files a/spec/fixtures/test.git/git/objects/77/b5c76d003b18b78c41b86e36884ce49f40c259 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/85/e04b1eb1a721d42db51d49e49dfeb8255a5741 b/spec/fixtures/test.git/git/objects/85/e04b1eb1a721d42db51d49e49dfeb8255a5741
deleted file mode 100644 (file)
index 153bd31..0000000
Binary files a/spec/fixtures/test.git/git/objects/85/e04b1eb1a721d42db51d49e49dfeb8255a5741 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/92/35e9c88c2051d6949febe22fc942365a0b2546 b/spec/fixtures/test.git/git/objects/92/35e9c88c2051d6949febe22fc942365a0b2546
deleted file mode 100644 (file)
index 797ab27..0000000
Binary files a/spec/fixtures/test.git/git/objects/92/35e9c88c2051d6949febe22fc942365a0b2546 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/93/1004157205727e6a47586feaed0473c6ddbd66 b/spec/fixtures/test.git/git/objects/93/1004157205727e6a47586feaed0473c6ddbd66
deleted file mode 100644 (file)
index f017b1a..0000000
Binary files a/spec/fixtures/test.git/git/objects/93/1004157205727e6a47586feaed0473c6ddbd66 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/9f/c2abdd0895100b5876bc346dad6bbfb39e9324 b/spec/fixtures/test.git/git/objects/9f/c2abdd0895100b5876bc346dad6bbfb39e9324
deleted file mode 100644 (file)
index d5f9ef5..0000000
Binary files a/spec/fixtures/test.git/git/objects/9f/c2abdd0895100b5876bc346dad6bbfb39e9324 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/c8/0c26814ee76057a8493b791e6e1a623f693e97 b/spec/fixtures/test.git/git/objects/c8/0c26814ee76057a8493b791e6e1a623f693e97
new file mode 100644 (file)
index 0000000..fb02b57
Binary files /dev/null and b/spec/fixtures/test.git/git/objects/c8/0c26814ee76057a8493b791e6e1a623f693e97 differ
diff --git a/spec/fixtures/test.git/git/objects/cf/e8bc15022f8b4d3cea89bc20abb13f985feeb0 b/spec/fixtures/test.git/git/objects/cf/e8bc15022f8b4d3cea89bc20abb13f985feeb0
deleted file mode 100644 (file)
index b0bc9b3..0000000
Binary files a/spec/fixtures/test.git/git/objects/cf/e8bc15022f8b4d3cea89bc20abb13f985feeb0 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/d0/80b4f440e8a87be90677df855a139a36bd2dc3 b/spec/fixtures/test.git/git/objects/d0/80b4f440e8a87be90677df855a139a36bd2dc3
deleted file mode 100644 (file)
index 9d54c76..0000000
Binary files a/spec/fixtures/test.git/git/objects/d0/80b4f440e8a87be90677df855a139a36bd2dc3 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/objects/dd/e5c6b931572a74d0824ad8268e826ba18647b4 b/spec/fixtures/test.git/git/objects/dd/e5c6b931572a74d0824ad8268e826ba18647b4
new file mode 100644 (file)
index 0000000..0bff00b
Binary files /dev/null and b/spec/fixtures/test.git/git/objects/dd/e5c6b931572a74d0824ad8268e826ba18647b4 differ
diff --git a/spec/fixtures/test.git/git/objects/e4/38134aac40ce86789d552f1bdada6582a987f6 b/spec/fixtures/test.git/git/objects/e4/38134aac40ce86789d552f1bdada6582a987f6
deleted file mode 100644 (file)
index 37b8c14..0000000
+++ /dev/null
@@ -1 +0,0 @@
-x\ 1\9d\8eÍi\ 31\10FsV\15º\e\8c4\9aÑjÀ\187àK:ÐÏØY°VfWë\83[J\1dé+º¤\81Ü>\1e¼Ç\97[­s×àíG_E4\83\1cB\ 6C¶xF¾I\12\80[f\ 4ç)\9a\ 4\84^=ã*K×\81Ä`²\92l\9cÀ\16\84\92\86\86,Èe\88\ 1\88"MhUÜûW[õu^JÜïqÓ×öþù^Ç8Õ?v¬í½\ ft¹×8?\8e¹Õ³¶è\9c¡\10Àè\83qƨAÇã.ÿj\91÷\93c\86Ñ\82ÑR\9fRÛKô&uÎíÑ\16õ\vß)V\9f
\ No newline at end of file
diff --git a/spec/fixtures/test.git/git/objects/f3/7efccc1cef20309de28bfbdd16d0c4afb9d550 b/spec/fixtures/test.git/git/objects/f3/7efccc1cef20309de28bfbdd16d0c4afb9d550
deleted file mode 100644 (file)
index 1b07d10..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-x\ 1­ÎK
-Â0\14\85aÇYÅ\9d\vå&iÒ\ 4D\9c:è"n\1e­\81¦\81\9aNº%×á¾\f\88;pvø\ 6\97\9cS\ 5Áù©n1\82\9d¼ \17\ 2\1a«8¢SfÐÎË^\a
-Ú¹ÉI\e­\14=£½>Ê\ 6cZ\ 3í3=a,ÇûµµqÉ?ër9öF·9SZ:_ò\15x/%*cp\803JDÖ´=¨ñ\1f-v_SM´À7Ê>»CHò
\ No newline at end of file
diff --git a/spec/fixtures/test.git/git/objects/f6/e267486c6b9d0f50a690c894df5e981e31c1b0 b/spec/fixtures/test.git/git/objects/f6/e267486c6b9d0f50a690c894df5e981e31c1b0
new file mode 100644 (file)
index 0000000..8d9a177
Binary files /dev/null and b/spec/fixtures/test.git/git/objects/f6/e267486c6b9d0f50a690c894df5e981e31c1b0 differ
diff --git a/spec/fixtures/test.git/git/objects/f7/eb73cae47464f2d235a1d014c4617ad2aa0cb0 b/spec/fixtures/test.git/git/objects/f7/eb73cae47464f2d235a1d014c4617ad2aa0cb0
deleted file mode 100644 (file)
index 7fa950f..0000000
Binary files a/spec/fixtures/test.git/git/objects/f7/eb73cae47464f2d235a1d014c4617ad2aa0cb0 and /dev/null differ
diff --git a/spec/fixtures/test.git/git/refs/heads/curly b/spec/fixtures/test.git/git/refs/heads/curly
deleted file mode 100644 (file)
index 21919cd..0000000
+++ /dev/null
@@ -1 +0,0 @@
-37018e429ad00f0ec961bd218e3dfa6a6e8cc05b
diff --git a/spec/fixtures/test.git/git/refs/heads/hlint b/spec/fixtures/test.git/git/refs/heads/hlint
new file mode 100644 (file)
index 0000000..a27bfd1
--- /dev/null
@@ -0,0 +1 @@
+553b8ba14bc0100f71f0bbe45c7ad29a088f7c15
index 0cccce0127cc2d75b53d4d81276fc65bad3a39cc..5a8fedf642bd4ad6c1e28fd243ef13cb88e48cc5 100644 (file)
@@ -1 +1 @@
-931004157205727e6a47586feaed0473c6ddbd66
+08cc1f13f1d655a7353040edb359c7f3ab7f8bd4
diff --git a/spec/fixtures/test.git/hello.js b/spec/fixtures/test.git/hello.js
deleted file mode 100644 (file)
index 6ad633d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-function HelloWorld(name)
-{
-    if (foo) foo++;
-    alert(name);
-}
-
-function Empty() {}
diff --git a/spec/fixtures/test.git/pronto.hs b/spec/fixtures/test.git/pronto.hs
new file mode 100644 (file)
index 0000000..dde5c6b
--- /dev/null
@@ -0,0 +1,11 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Pronto
+  (
+    sayHello
+  ) where
+
+import           Data.Text (Text)
+
+sayHello :: Text -> String
+sayHello text = show $ text
diff --git a/spec/fixtures/test.git/world.es6 b/spec/fixtures/test.git/world.es6
deleted file mode 100644 (file)
index 2d1b996..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-function HelloWorld(name)
-{
-    if (foo) foo++;
-    alert(name);
-}
diff --git a/spec/pronto/eslint_spec.rb b/spec/pronto/eslint_spec.rb
deleted file mode 100644 (file)
index 0924f30..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-module Pronto
-  describe ESLintNpm do
-    let(:eslint) { ESLintNpm.new(patches) }
-    let(:patches) { [] }
-
-    describe '#run' do
-      subject(:run) { eslint.run }
-
-      context 'patches are nil' do
-        let(:patches) { nil }
-
-        it 'returns an empty array' do
-          expect(run).to eql([])
-        end
-      end
-
-      context 'no patches' do
-        let(:patches) { [] }
-
-        it 'returns an empty array' do
-          expect(run).to eql([])
-        end
-      end
-
-      context 'patches with a one and a four warnings' do
-        include_context 'test repo'
-
-        let(:patches) { repo.diff('master') }
-
-        it 'returns correct number of errors' do
-          expect(run.count).to eql(5)
-        end
-
-        it 'has correct first message' do
-          expect(run.first.msg).to eql("'foo' is not defined.")
-        end
-
-        context(
-          'with files to lint config that never matches',
-          config: { 'files_to_lint' => 'will never match' }
-        ) do
-          it 'returns zero errors' do
-            expect(run.count).to eql(0)
-          end
-        end
-
-        context(
-          'with files to lint config that matches only .js',
-          config: { 'files_to_lint' => '\.js$' }
-        ) do
-          it 'returns correct amount of errors' do
-            expect(run.count).to eql(2)
-          end
-        end
-
-        context(
-          'with cmd_line_opts to include .html',
-          config: { 'cmd_line_opts' => '--ext .html' }
-        ) do
-          it 'returns correct number of errors' do
-            expect(run.count).to eql 5
-          end
-        end
-
-        context(
-          'with different eslint executable',
-          config: { 'eslint_executable' => './custom_eslint.sh' }
-        ) do
-          it 'calls the custom eslint eslint_executable' do
-            expect { run }.to raise_error(JSON::ParserError, /custom eslint called/)
-          end
-        end
-      end
-
-      context 'repo with ignored and not ignored file, each with three warnings' do
-        include_context 'eslintignore repo'
-
-        let(:patches) { repo.diff('master') }
-
-        it 'returns correct number of errors' do
-          expect(run.count).to eql(3)
-        end
-
-        it 'has correct first message' do
-          expect(run.first.msg).to eql("'HelloWorld' is defined but never used.")
-        end
-      end
-    end
-
-    describe '#files_to_lint' do
-      subject(:files_to_lint) { eslint.files_to_lint }
-
-      it 'matches .js by default' do
-        expect(files_to_lint).to match('my_js.js')
-      end
-
-      it 'matches .es6 by default' do
-        expect(files_to_lint).to match('my_js.es6')
-      end
-    end
-
-    describe '#eslint_executable' do
-      subject(:eslint_executable) { eslint.eslint_executable }
-
-      it 'is `eslint` by default' do
-        expect(eslint_executable).to eql('eslint')
-      end
-
-      context(
-        'with different eslint executable config',
-        config: { 'eslint_executable' => 'custom_eslint' }
-      ) do
-        it 'is correct' do
-          eslint.read_config
-          expect(eslint_executable).to eql('custom_eslint')
-        end
-      end
-    end
-
-    describe '#eslint_command_line' do
-      subject(:eslint_command_line) { eslint.send(:eslint_command_line, path) }
-      let(:path) { '/some/path.rb' }
-
-      it 'adds json output flag' do
-        expect(eslint_command_line).to include('-f json')
-      end
-
-      it 'adds path' do
-        expect(eslint_command_line).to include(path)
-      end
-
-      it 'starts with eslint executable' do
-        expect(eslint_command_line).to start_with(eslint.eslint_executable)
-      end
-
-      context 'with path that should be escaped' do
-        let(:path) { '/must be/$escaped' }
-
-        it 'escapes the path correctly' do
-          expect(eslint_command_line).to include('/must\\ be/\\$escaped')
-        end
-
-        it 'does not include unescaped path' do
-          expect(eslint_command_line).not_to include(path)
-        end
-      end
-      
-      context(
-        'with some command line options',
-        config: { 'cmd_line_opts' => '--my command --line opts' }
-      ) do
-        it 'includes the custom command line options' do
-          eslint.read_config
-          expect(eslint_command_line).to include('--my command --line opts')
-        end
-      end
-    end
-  end
-end
diff --git a/spec/pronto/hlint_spec.rb b/spec/pronto/hlint_spec.rb
new file mode 100644 (file)
index 0000000..fdabab5
--- /dev/null
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+module Pronto
+  module Hlint
+    describe Runner do
+      let(:hlint) { Hlint::Runner.new(patches) }
+      let(:patches) { [] }
+
+      describe '#run' do
+        subject(:run) { hlint.run }
+
+        context 'patches are nil' do
+          let(:patches) { nil }
+
+          it 'returns an empty array' do
+            expect(run).to eql([])
+          end
+        end
+
+        context 'no patches' do
+          let(:patches) { [] }
+
+          it 'returns an empty array' do
+            expect(run).to eql([])
+          end
+        end
+
+        context 'patches with a one and a four warnings' do
+          include_context 'test repo'
+
+          let(:patches) { repo.diff('master') }
+
+          it 'returns correct number of errors' do
+            expect(run.count).to eql(3)
+          end
+
+          it 'has correct first message' do
+            expect(run.first.msg).to match("Unused LANGUAGE pragma")
+          end
+
+          context(
+            'with files to lint config that never matches',
+            config: { 'files_to_lint' => 'will never match' }
+          ) do
+            it 'returns zero errors' do
+              expect(run.count).to eql(0)
+            end
+          end
+
+          context(
+            'with files to lint config that matches only .lhs',
+            config: { 'files_to_lint' => '\.lhs$' }
+          ) do
+            it 'returns correct amount of errors' do
+              expect(run.count).to eql(0)
+            end
+          end
+
+          context(
+            'with different hlint executable',
+            config: { 'hlint_executable' => './custom_hlint.sh' }
+          ) do
+            it 'calls the custom hlint hlint_executable' do
+              expect { run }.to raise_error(JSON::ParserError, /hlint called!/)
+            end
+          end
+        end
+      end
+
+      describe '#files_to_lint' do
+        subject(:files_to_lint) { hlint.files_to_lint }
+
+        it 'matches .he by default' do
+          expect(files_to_lint).to match('Types.hs')
+        end
+      end
+
+      describe '#hlint_executable' do
+        subject(:hlint_executable) { hlint.hlint_executable }
+
+        it 'is `hlint` by default' do
+          expect(hlint_executable).to eql('hlint')
+        end
+
+        context(
+          'with different hlint executable config',
+          config: { 'hlint_executable' => 'custom_hlint' }
+        ) do
+          it 'is correct' do
+            hlint.read_config
+            expect(hlint_executable).to eql('custom_hlint')
+          end
+        end
+      end
+
+      describe '#hlint_command_line' do
+        subject(:hlint_command_line) { hlint.send(:hlint_command_line, path) }
+        let(:path) { '/some/path.rb' }
+
+        it 'adds json output flag' do
+          expect(hlint_command_line).to include('--json')
+        end
+
+        it 'adds path' do
+          expect(hlint_command_line).to include(path)
+        end
+
+        it 'starts with hlint executable' do
+          expect(hlint_command_line).to start_with(hlint.hlint_executable)
+        end
+
+        context 'with path that should be escaped' do
+          let(:path) { '/must be/$escaped' }
+
+          it 'escapes the path correctly' do
+            expect(hlint_command_line).to include('/must\\ be/\\$escaped')
+          end
+
+          it 'does not include unescaped path' do
+            expect(hlint_command_line).not_to include(path)
+          end
+        end
+
+        context(
+          'with some command line options',
+          config: { 'cmd_line_opts' => '--my command --line opts' }
+        ) do
+          it 'includes the custom command line options' do
+            hlint.read_config
+            expect(hlint_command_line).to include('--my command --line opts')
+          end
+        end
+      end
+    end
+  end
+end
index e147ea7386a56cf01c27046f97c93ec40fae1bff..656e1167a2dc46543554afe8b50fb644dd118b32 100644 (file)
@@ -1,11 +1,10 @@
 # frozen_string_literal: true
 
 require 'fileutils'
-require 'byebug'
 require 'rspec'
-require 'pronto/eslint_npm'
+require 'pronto/hlint'
 
-%w[test eslintignore].each do |repo_name|
+%w[test].each do |repo_name|
   RSpec.shared_context "#{repo_name} repo" do
     let(:git) { "spec/fixtures/#{repo_name}.git/git" }
     let(:dot_git) { "spec/fixtures/#{repo_name}.git/.git" }
@@ -20,9 +19,9 @@ RSpec.shared_context 'with config', config: true do
   requested_config = metadata[:config]
 
   before(:each) do
-    allow_any_instance_of(Pronto::ESLintNpm).to receive(:config_options).and_return(requested_config)
+    allow_any_instance_of(Pronto::Hlint::Runner).to receive(:config_options).and_return(requested_config)
 
     # make sure the config is actually read in the example
-    expect_any_instance_of(Pronto::ESLintNpm).to receive(:read_config).and_call_original
+    expect_any_instance_of(Pronto::Hlint::Runner).to receive(:read_config).and_call_original
   end
 end