From 0ec3a446ba685c08d913afb92cec09a24b7a8f57 Mon Sep 17 00:00:00 2001 From: "Kenneth M. Elf Sternberg" Date: Thu, 22 Sep 2016 15:25:08 -0700 Subject: [PATCH] The file strategies have all been settled on, including the ability to detect when a repository is un-lint-able (due to merge conflicts in the current tree munging up source files). 250 lines of hand- written Hy, and I haven't even gotten to the main part of the project, actually running the linters. --- git_lint_src/git-lint.hy | 1 + git_lint_src/git_lint.hy | 224 ++++++++++++------ git_lint_src/git_lint_options.hy | 6 +- git_lint_src/load-config.hy | 47 ++-- git_lint_src/n1 | 385 +++++++++++++++++++++++++++++++ 5 files changed, 568 insertions(+), 95 deletions(-) create mode 100644 git_lint_src/n1 diff --git a/git_lint_src/git-lint.hy b/git_lint_src/git-lint.hy index d6c1afd..4c596d3 100644 --- a/git_lint_src/git-lint.hy +++ b/git_lint_src/git-lint.hy @@ -284,3 +284,4 @@ (let [[empty-repository-hash "4b825dc642cb6eb9a060e54bf8d69288fbee4904"] [(, out err returncode) (get-git-response ["rev-parse" "--verify HEAD"])]] (if err empty-repository-hash "HEAD"))) + diff --git a/git_lint_src/git_lint.hy b/git_lint_src/git_lint.hy index ff1536a..0a139cb 100644 --- a/git_lint_src/git_lint.hy +++ b/git_lint_src/git_lint.hy @@ -8,7 +8,6 @@ (def *version* "0.0.2") (defn tap [a] (print "TAP:" a) a) - ; short-name long-name takes-args description precludes (def optlist [["o" "only" true (_ "A comma-separated list of only those linters to run") ["exclude"]] ["x" "exclude" true (_ "A comma-separated list of linters to skip") []] @@ -60,56 +59,13 @@ (get-git-response-raw ["rev-parse" "--show-toplevel"])]] (if (not (= returncode 0)) None (.rstrip out)))) -(defn get-all-from-cwd [] - (split-git-response ["ls-tree" "--name-only" "-r" "HEAD"])) - -(defn get-all-from-base [] - (split-git-response ["ls-tree" "--name-only" "-r" "--full-tree" "HEAD"])) - - ; Any of these indicate the tree is in a merge - ; conflict state and the user has bigger problems. -(def *merge-conflict-pairs* (set ["DD" "DU" "AU" "AA" "UD" "UA" "UU"])) -(defn get-changed-from-source [trackings] - (let [[conflicts (filter (fn [t] (t[0:2] in *merge-conflict-pairs*)) trackings)]] - (if (len conflicts) - (sys.exit (_ "Current repository contains merge conflicts. Linters will not be run.")) - trackings))) - -(defn get-porcelain-status [cmd] - (let [[stream (.split (get-git-response cmd) "\0")] - [parse-stream (fn [acc stream] - (if (= 0 (len stream)) - acc - (let [[temp (.pop stream 0)] - [index (.pop temp 0)] - [workspace (.pop temp 0)] - [filename (slice temp 1)]] - (if (= index "R") - (.pop stream 0)) - (parse-stream (.append acc (, index workspace filename)) stream))))]] - (parse-stream [] stream))) - -(defn modified-in-workspace [s] (s[0] in ["M" "A" "?"])) -(defn modified-in-staging [s] (s[1] in ["M" "A" "?"])) -(defn get-name [s] (s[2])) - - ;(defn get-changed-from-cwd [] - ; (->> (get-changed-from_source (split-git-response ["status" "--porcelain" "--untracked-files=all"])) - ; (filter (fn [s] (s[0] in - ; - ; (map (fn [s] - ; (filter (fn [s] ( - ; - -(defn get-changed-from-base [] - (get-changed-from_source (split-git-response ["status" "--porcelain" "--untracked-files=all" git-base]))) - -(defn get-staged-from-cwd [] - ()) - -(defn gen-staged-from-base [] - ()) - +; That mystery number is the precise hash code for a repository for has been initialized, +; but for which nothing has ever been added or committed. An empty repository has no refs +; at all so you can't use HEAD in this one very rare case. +(def git-head + (let [[empty-repository-hash "4b825dc642cb6eb9a060e54bf8d69288fbee4904"] + [(, out err returncode) (get-git-response-raw ["rev-parse" "--verify HEAD"])]] + (if (not err) "HEAD" empty-repository-hash))) (defn make-match-filter-matcher [extensions] (->> (map (fn [s] (.split s ",")) extensions) @@ -125,7 +81,13 @@ (defn make-match-filter [config] (let [[matcher (make-match-filter-matcher (map (fn [v] (.get v "match" "" )) (.itervalues config)))]] - (fn [path] (.search matcher path)))) + (fn [path] (print matcher.pattern) (.search matcher path)))) + +; _ _ _ _ _ _ _ _ +;| | (_)_ _| |_ ___ _ _ _____ _____ __ _ _| |_ __ _| |__| |___ __| |_ __ _| |_ _ _ ___ +;| |__| | ' \ _/ -_) '_| / -_) \ / -_) _| || | _/ _` | '_ \ / -_) (_-< _/ _` | _| || (_-< +;|____|_|_||_\__\___|_| \___/_\_\___\__|\_,_|\__\__,_|_.__/_\___| /__/\__\__,_|\__|\_,_/__/ +; (defn executable-exists [script label] (if (not (len script)) @@ -149,27 +111,141 @@ (print (.format "{:<14} {}" linter (_ "(WARNING: executable not found)"))) (print (.format "{:<14} {}" linter (.get items "comment" "")))))) -(defn git-lint-main [options] - (print git-base) - (print (os.path.abspath __file__)) - (let [[config (get-config-file options git-base)]] - (print options) - (print config) - (print (make-match-filter config)))) +; ___ _ _ _ _ __ _ _ _ +;| __(_) |___ _ __ __ _| |_| |_ / _(_) | |_ ___ _ _ ___ +;| _|| | / -_) | '_ \/ _` | _| ' \ | _| | | _/ -_) '_(_-< +;|_| |_|_\___| | .__/\__,_|\__|_||_| |_| |_|_|\__\___|_| /__/ +; |_| + +(defn remove-submodules [files] + (let [[split-out-paths (fn [s] (get (.split s " ") 2))] + [fixer-re (re.compile "^(\.\.\/)+")] + [fixer-to-base (fn [s] (.sub fixer-re "" s))] + [submodule-entries (split-git-response ["submodule" "status"])] + [submodule-names (map (fn [s] (fixer-to-base (split-out-paths s))) submodule-entries)]] + (filter (fn [s] (not (in s submodule-names))) files))) + +(defn base-file-filter [files] + (map (fn [f] (os.path.join git-base f)) files)) + +(defn cwd-file-filter [files] + (let [[gitcwd (os.path.join (os.path.relpath (os.getcwd) git-base) "")]] + (base-file-filter (filter (fn [f] (.startswith f gitcwd)) files)))) + +(defn base-file-cleaner [files] + (map (fn [f] (.replace f git-base 1)) files)) + +; ___ __ _ _ _ _ _ _ +;| _ \__ ___ __ __ / _(_) |___ | (_)__| |_ __ _ ___ _ _ ___ _ _ __ _| |_ ___ _ _ ___ +;| / _` \ V V / | _| | / -_) | | (_-< _| / _` / -_) ' \/ -_) '_/ _` | _/ _ \ '_(_-< +;|_|_\__,_|\_/\_/ |_| |_|_\___| |_|_/__/\__| \__, \___|_||_\___|_| \__,_|\__\___/_| /__/ +; |___/ + +(def *merge-conflict-pairs* (set ["DD" "DU" "AU" "AA" "UD" "UA" "UU"])) +(defn check-for-conflicts [files] + (let [[status-pairs (map (fn [(, index workspace filename)] (+ "" index workspace)) files)] + [conflicts (& (set *merge-conflict-pairs*) (set status-pairs))]] + (if (len conflicts) + (sys.exit (_ "Current repository contains merge conflicts. Linters will not be run.")) + files))) + +(defn get-porcelain-status [] + (let [[cmd ["status" "-z" "--porcelain" "--untracked-files=all" "--ignore-submodules=all"]] + [nonnull (fn [s] (> (len s) 0))] + [stream (list (filter nonnull (.split (get-git-response cmd) "\0")))] + [parse-stream (fn [acc stream] + (if (= 0 (len stream)) + acc + (let [[temp (.pop stream 0)] + [index (get temp 0)] + [workspace (get temp 1)] + [filename (slice temp 3)]] + (if (= index "R") + (.pop stream 0)) + (parse-stream (+ acc [(, index workspace filename)]) stream))))]] + (check-for-conflicts (parse-stream [] stream)))) + +(defn staging-list [] + (map (fn [(, index workspace filename)] filename) + (filter (fn [(, index workspace filename)] (in index ["A" "M"])) (get-porcelain-status)))) + +(defn working-list [] + (map (fn [(, index workspace filename)] filename) + (filter (fn [(, index workspace filename)] (in workspace ["A" "M" "?"])) (get-porcelain-status)))) + +(defn all-list [] + (let [[cmd ["ls-tree" "--name-only" "--full-tree" "-r" "-z" git-head]]] + (filter (fn [s] (> (len s) 0)) (.split (get-git-response cmd) "\0")))) + +; _ _ _ __ _ _ _ _ _ _ +; /_\ ______ ___ _ __ | |__| |___ / _(_) |___ | (_)__| |_ __ _ ___ _ _ ___ _ _ __ _| |_ ___ _ _ +; / _ \ (_-<_-" - "0.0.4")] - [options opts.options] - [config (get-config options git-base)]] - (cond [(.has_key options "help") (opts.print-help)] - [(.has_key options "version") (opts.print-version)] - [(.has_key options "linters") (print-linters config)] - [true (git-lint-main options)])) - (catch [err getopt.GetoptError] - (print (str err)) - (print-help))))) + (let [[opts (hyopt optlist args "git lint" + "Copyright (c) 2008, 2016 Kenneth M. \"Elf\" Sternberg " + "0.0.4")]] + (if (= git-base None) + (sys.exit (_ "Not currently in a git repository.")) + (try + (let [[options (.get_options opts)] + [config (get-config options git-base)]] + (cond [(.has_key options "help") (opts.print-help)] + [(.has_key options "version") (opts.print-version)] + [(.has_key options "linters") (print-linters config)] + [true (run-gitlint options config opts.filenames)])) + (catch [err getopt.GetoptError] + (do + (opts.print-help))))))) diff --git a/git_lint_src/git_lint_options.hy b/git_lint_src/git_lint_options.hy index 0954fa6..876c316 100644 --- a/git_lint_src/git_lint_options.hy +++ b/git_lint_src/git_lint_options.hy @@ -55,12 +55,14 @@ (setv self.optlist optlist) (setv self.options newoptions) (setv self.excluded excluded) - (setv self.filesames arg) + (setv self.filenames arg) (setv self.name (if name name (get-script-name))) (setv self.version version) (setv self.copyright copyright)) None)] - + + [get-options (fn [self] self.options)] + [get-keys (fn [self] (set (.keys self.options)))] [print-help (fn [self] (print (.format (_ "Usage: {} [options] [filenames]") self.name)) (for [item self.optlist] (print (.format " -{:<1} --{:<12} {}" (get item 0) (get item 1) (get item 3)))) diff --git a/git_lint_src/load-config.hy b/git_lint_src/load-config.hy index 098bb14..78f3d6e 100644 --- a/git_lint_src/load-config.hy +++ b/git_lint_src/load-config.hy @@ -13,14 +13,16 @@ (def optlist [["o" "only" true (_ "A comma-separated list of only those linters to run") ["exclude"]] ["x" "exclude" true (_ "A comma-separated list of linters to skip") []] ["l" "linters" false (_ "Show the list of configured linters")] - ["b" "base" false (_ "Check all changed files in the repository, not just those in the current directory.") []] - ["a" "all" false (_ "Scan all files in the repository, not just those that have changed.")] + ["b" "base" false (_ "Scan from the base directory rather than the current working") []] + ["a" "all" false (_ "Scan all files in the repository, not just those that have changed")] ["e" "every" false (_ "Short for -b -a: scan everything")] ["w" "workspace" false (_ "Scan the workspace") ["staging"]] - ["s" "staging" false (_ "Scan the staging area (useful for pre-commit).") ["base" "all" "every"]] + ["s" "staging" false (_ "Scan the staging area (useful for pre-commit).") ["base" "all" "every" "workspace"]] ["g" "changes" false (_ "Report lint failures only for diff'd sections") ["complete"]] - ["p" "complete" false (_ "Report lint failures for all files") []] + ["p" "complete" false (_ "Report lint failures over whole files") []] ["c" "config" true (_ "Path to config file") []] + ["d" "dryrun" false (_ "Report what git-lint would do, but don't actually do anything.") []] + ["q" "quiet" false (_ "Produce a short report of files that failed to pass.") []] ["h" "help" false (_ "This help message") []] ["v" "version" false (_"Version information") []]]) @@ -162,19 +164,26 @@ (print (make-match-filter config)) (print (get-porcelain-status)))) + (defmain [&rest args] - (if (= git-base None) - (sys.exit (_ "Not currently in a git repository.")) - (try - (let [[opts (hyopt optlist args "git lint" - "Copyright (c) 2008, 2016 Kenneth M. \"Elf\" Sternberg " - "0.0.4")] - [options opts.options] - [config (get-config options git-base)]] - (cond [(.has_key options "help") (opts.print-help)] - [(.has_key options "version") (opts.print-version)] - [(.has_key options "linters") (print-linters config)] - [true (git-lint-main options)])) - (catch [err getopt.GetoptError] - (print (str err)) - (print-help))))) + (for [option optlist] + (print (.format "``-{}`` ``--{}``\n {}" (get option 0) (get option 1) (get option 3))))) + + +;(defmain [&rest args] +; (if (= git-base None) +; (sys.exit (_ "Not currently in a git repository.")) +; (try +; (let [[opts (hyopt optlist args "git lint" +; "Copyright (c) 2008, 2016 Kenneth M. \"Elf\" Sternberg " +; "0.0.4")] +; [options opts.options] +; [config (get-config options git-base)]] +; (cond [(.has_key options "help") (opts.print-help)] +; [(.has_key options "version") (opts.print-version)] +; [(.has_key options "linters") (print-linters config)] +; [true (git-lint-main options)])) +; (catch [err getopt.GetoptError] +; (print (str err)) +; (print-help))))) +; diff --git a/git_lint_src/n1 b/git_lint_src/n1 new file mode 100644 index 0000000..ca5898a --- /dev/null +++ b/git_lint_src/n1 @@ -0,0 +1,385 @@ +from hy.core.language import filter, is_integer, map, reduce +import ConfigParser +import os +import subprocess +import operator +import re +import gettext +import sys +import getopt +sys.path.append(u'Users/ksternberg/build/git-lint/git_lint_src') +from git_lint_options import hyopt +from git_lint_config import get_config +_ = gettext.gettext +VERSION = u'0.0.2' + +def tap(a): + print(u'TAP:', a) + return a +optlist = [[u'o', u'only', True, _(u'A comma-separated list of only those linters to run'), [u'exclude']], [u'x', u'exclude', True, _(u'A comma-separated list of linters to skip'), []], [u'l', u'linters', False, _(u'Show the list of configured linters')], [u'b', u'base', False, _(u'Check all changed files in the repository, not just those in the current directory.'), []], [u'a', u'all', False, _(u'Scan all files in the repository, not just those that have changed.')], [u'e', u'every', False, _(u'Short for -b -a: scan everything')], [u'w', u'workspace', False, _(u'Scan the workspace'), [u'staging']], [u's', u'staging', False, _(u'Scan the staging area (useful for pre-commit).'), []], [u'g', u'changes', False, _(u"Report lint failures only for diff'd sections"), [u'complete']], [u'p', u'complete', False, _(u'Report lint failures for all files'), []], [u'c', u'config', True, _(u'Path to config file'), []], [u'h', u'help', False, _(u'This help message'), []], [u'v', u'version', False, _(u'Version information'), []]] + +def get_git_response_raw(cmd): + + def _hy_anon_fn_2(): + fullcmd = ([u'git'] + cmd) + process = subprocess.Popen(fullcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (out, err) = process.communicate() + (out, err) + return (out, err, process.returncode) + return _hy_anon_fn_2() + +def get_git_response(cmd): + + def _hy_anon_fn_4(): + (out, error, returncode) = get_git_response_raw(cmd) + (out, error, returncode) + return out + return _hy_anon_fn_4() + +def split_git_response(cmd): + + def _hy_anon_fn_6(): + (out, error, returncode) = get_git_response_raw(cmd) + (out, error, returncode) + return out.splitlines() + return _hy_anon_fn_6() + +def split_git_response(cmd): + + def _hy_anon_fn_8(): + (out, error, returncode) = get_git_response_raw(cmd) + (out, error, returncode) + return out.splitlines() + return _hy_anon_fn_8() + +def run_git_command(cmd): + + def _hy_anon_fn_10(): + fullcmd = ([u'git'] + cmd) + return subprocess.call(fullcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return _hy_anon_fn_10() + +def get_shell_response(fullcmd): + + def _hy_anon_fn_12(): + process = subprocess.Popen(fullcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + (out, err) = process.communicate() + (out, err) + return (out, err, process.returncode) + return _hy_anon_fn_12() + +def _hy_anon_fn_14(): + (out, error, returncode) = get_git_response_raw([u'rev-parse', u'--show-toplevel']) + (out, error, returncode) + return (None if (not (returncode == 0L)) else out.rstrip()) +git_base = _hy_anon_fn_14() + +def get_all_from_cwd(): + return split_git_response([u'ls-tree', u'--name-only', u'-r', u'HEAD']) + +def get_all_from_base(): + return split_git_response([u'ls-tree', u'--name-only', u'-r', u'--full-tree', u'HEAD']) +MERGE_CONFLICT_PAIRS = set([u'DD', u'DU', u'AU', u'AA', u'UD', u'UA', u'UU']) + +def get_changed_from_source(trackings): + + def _hy_anon_fn_18(): + + def _hy_anon_fn_17(t): + return t([0:2], in, MERGE_CONFLICT_PAIRS) + conflicts = filter(_hy_anon_fn_17, trackings) + return (sys.exit(_(u'Current repository contains merge conflicts. Linters will not be run.')) if len(conflicts) else trackings) + return _hy_anon_fn_18() + +def get_porcelain_status(cmd): + + def _hy_anon_fn_22(): + stream = get_git_response(cmd).split(u'\x00') + + def parse_stream(acc, stream): + if (0L == len(stream)): + _hy_anon_var_1 = acc + else: + + def _hy_anon_fn_20(): + temp = stream.pop(0L) + index = temp.pop(0L) + workspace = temp.pop(0L) + filename = temp[1L:] + (stream.pop(0L) if (index == u'R') else None) + return parse_stream(acc.append((index, workspace, filename)), stream) + _hy_anon_var_1 = _hy_anon_fn_20() + return _hy_anon_var_1 + return parse_stream([], stream) + return _hy_anon_fn_22() + +def modified_in_workspace(s): + return s([0L], in, [u'M', u'A', u'?']) + +def modified_in_staging(s): + return s([1L], in, [u'M', u'A', u'?']) + +def get_name(s): + return s([2L]) + +def get_changed_from_base(): + return get_changed_from_source(split_git_response([u'status', u'--porcelain', u'--untracked-files=all', git_base])) + +def get_staged_from_cwd(): + return [] + +def gen_staged_from_base(): + return [] + +def make_match_filter_matcher(extensions): + + def _hy_anon_fn_30(s): + return re.compile(s, re.I) + + def _hy_anon_fn_31(s): + return ((u'\\.(' + s) + u')$') + + def _hy_anon_fn_32(s): + return re.sub(u'^\\.', u'', s) + + def _hy_anon_fn_33(s): + return (not (0L == len(s))) + + def _hy_anon_fn_34(s): + return s.strip() + + def _hy_anon_fn_35(s): + return s.split(u',') + return _hy_anon_fn_30(_hy_anon_fn_31(u'|'.join(map(_hy_anon_fn_32, filter(_hy_anon_fn_33, set(map(_hy_anon_fn_34, reduce(operator.add, map(_hy_anon_fn_35, extensions))))))))) + +def make_match_filter(config): + + def _hy_anon_fn_39(): + + def _hy_anon_fn_37(v): + return v.get(u'match', u'') + matcher = make_match_filter_matcher(map(_hy_anon_fn_37, config.itervalues())) + + def _hy_anon_fn_38(path): + return matcher.search(path) + return _hy_anon_fn_38 + return _hy_anon_fn_39() + +def executable_exists(script, label): + if (not len(script)): + _hy_anon_var_4 = sys.exit(_(u'Syntax error in command configuration for {} ').format(label)) + else: + + def _hy_anon_fn_44(): + scriptname = script.split(u' ')[0L] + paths = os.environ.get(u'PATH').split(u':') + + def isexecutable(p): + return (os.path.exists(p) and os.access(p, os.X_OK)) + if (not len(scriptname)): + _hy_anon_var_3 = sys.exit(_(u'Syntax error in command configuration for {} ').format(label)) + else: + if (scriptname[0L] == u'/'): + _hy_anon_var_2 = (scriptname if isexecutable(scriptname) else None) + else: + + def _hy_anon_fn_43(): + + def _hy_anon_fn_42(path): + return isexecutable(os.path.join(path, scriptname)) + possibles = list(filter(_hy_anon_fn_42, paths)) + return (possibles[0L] if len(possibles) else None) + _hy_anon_var_2 = _hy_anon_fn_43() + _hy_anon_var_3 = _hy_anon_var_2 + return _hy_anon_var_3 + _hy_anon_var_4 = _hy_anon_fn_44() + return _hy_anon_var_4 + +def print_linters(config): + print(_(u'Currently supported linters:')) + for (linter, items) in config.iteritems(): + (print(u'{:<14} {}'.format(linter, _(u'(WARNING: executable not found)'))) if (not executable_exists(items.get(u'command', u''), linter)) else print(u'{:<14} {}'.format(linter, items.get(u'comment', u'')))) + +def get_porcelain_status(): + + def _hy_anon_fn_50(): + cmd = [u'status', u'-z', u'--porcelain', u'--untracked-files=all', u'--ignore-submodules=all'] + + def nonnull(s): + return (len(s) > 0L) + stream = tap(list(filter(nonnull, get_git_response(cmd).split(u'\x00')))) + + def parse_stream(acc, stream): + if (0L == len(stream)): + _hy_anon_var_5 = acc + else: + + def _hy_anon_fn_48(): + temp = stream.pop(0L) + index = temp[0L] + workspace = temp[1L] + filename = tap(temp[3L:]) + (stream.pop(0L) if (index == u'R') else None) + return parse_stream((acc + [(index, workspace, filename)]), stream) + _hy_anon_var_5 = _hy_anon_fn_48() + return _hy_anon_var_5 + return parse_stream([], stream) + return _hy_anon_fn_50() + +def staging_wrapper(files, run_linters): + + def _hy_anon_fn_55(): + + def time_gather(f): + + def _hy_anon_fn_52(): + stats = os.stat(f) + return (f, (stats.atime, stats.mtime)) + return _hy_anon_fn_52() + times = list(map(time_gather, files)) + run_git_command([u'stash', u'--keep-index']) + + def _hy_anon_fn_54(): + results = run_linters(files) + run_git_command([u'reset', u'--hard']) + run_git_command([u'stash', u'pop', u'--quiet', u'--index']) + for (filename, timepair) in times: + os.utime(filename, timepair) + return results + return _hy_anon_fn_54() + return _hy_anon_fn_55() + +def workspace_wrapper(files, run_linters): + return run_linters(files) + +def remove_submodules(files): + + def _hy_anon_fn_62(): + + def split_out_paths(s): + return s.split(u' ')[2L] + fixer_re = re.compile(u'^(\\.\\.\\/)+') + + def fixer_to_base(s): + return fixer_re.sub(u'', s) + submodule_entries = split_git_response([u'submodule', u'status']) + + def _hy_anon_fn_60(s): + return fixer_to_base(split_out_paths(s)) + submodule_names = map(_hy_anon_fn_60, submodule_entries) + + def _hy_anon_fn_61(s): + return (not (s in submodule_names)) + return filter(_hy_anon_fn_61, submodule_names) + return _hy_anon_fn_62() + +def base_file_filter(files): + + def _hy_anon_fn_64(f): + return os.path.join(git_base, f) + return map(_hy_anon_fn_64, files) + +def cwd_file_filter(files): + + def _hy_anon_fn_67(): + gitcwd = os.path.join(os.path.relpath(os.getcwd(), git_base), u'') + + def _hy_anon_fn_66(f): + return f.startswith(gitcwd) + return base_file_filter(filter(_hy_anon_fn_66, files)) + return _hy_anon_fn_67() + +def base_file_cleaner(files): + + def _hy_anon_fn_69(f): + return f.replace(git_base, 1L) + return map(_hy_anon_fn_69, files) + +def staging_list(): + + def _hy_anon_fn_71(_hy_anon_var_6): + (index, workspace, filename) = _hy_anon_var_6 + (index, workspace, filename) + return filename + + def _hy_anon_fn_72(_hy_anon_var_7): + (index, workspace, filename) = _hy_anon_var_7 + (index, workspace, filename) + return (index in [u'A', u'M']) + return map(_hy_anon_fn_71, filter(_hy_anon_fn_72, get_porcelain_status)) + +def working_list(): + + def _hy_anon_fn_74(_hy_anon_var_8): + (index, workspace, filename) = _hy_anon_var_8 + (index, workspace, filename) + return filename + + def _hy_anon_fn_75(_hy_anon_var_9): + (index, workspace, filename) = _hy_anon_var_9 + (index, workspace, filename) + return (working in [u'A', u'M', u'?']) + return map(_hy_anon_fn_74, filter(_hy_anon_fn_75, get_porcelain_status)) + +def all_list(): + + def _hy_anon_fn_78(): + cmd = [u'ls-tree', u'--name-only', u'--full-tree', u'-r', git_head] + + def _hy_anon_fn_77(s): + return (len(s) > 0L) + return filter(_hy_anon_fn_77, get_git_response(cmd).split(u'\x00')) + return _hy_anon_fn_78() + +def pick_filelist_strategy(options): + + def _hy_anon_fn_81(): + keys = options.keys() + working_directory_trans = (base_file_filter if len((set(keys) & set([u'b', u'e']))) else cwd_file_filter) + file_list_generator = (staging_list if (u's' in keys) else (all_list if (u'a' in keys) else (working_list if True else None))) + + def _hy_anon_fn_80(): + return working_directory_trans(remove_submodules(file_list_generator())) + return _hy_anon_fn_80 + return _hy_anon_fn_81() + +def pick_runner(options): + + def _hy_anon_fn_83(): + keys = options.keys() + return (staging_wrapper if (u's' in keys) else workspace_wrapper) + return _hy_anon_fn_83() + +def run_gitlint(options, config, extras): + + def _hy_anon_fn_85(): + file_lister = pick_filelist_strategy(options) + runner = pick_runner(options) + return print(file_lister()) + return _hy_anon_fn_85() + +def main(*args): + + def _hy_anon_fn_88(): + opts = hyopt(optlist, args, u'git lint', u'Copyright (c) 2008, 2016 Kenneth M. "Elf" Sternberg ', u'0.0.4') + if (git_base == None): + _hy_anon_var_11 = sys.exit(_(u'Not currently in a git repository.')) + else: + try: + + def _hy_anon_fn_87(): + options = opts.get_options() + config = get_config(options, git_base) + return (opts.print_help() if options.has_key(u'help') else (opts.print_version() if options.has_key(u'version') else (print_linters(config) if options.has_key(u'linters') else (run_gitlint(options, config, opts.filenames) if True else None)))) + _hy_anon_var_10 = _hy_anon_fn_87() + except getopt.GetoptError as err: + _hy_anon_var_10 = opts.print_help() + _hy_anon_var_11 = _hy_anon_var_10 + return _hy_anon_var_11 + return _hy_anon_fn_88() +if (__name__ == u'__main__'): + import sys + :G_1235 = main(*sys.argv) + _hy_anon_var_12 = (sys.exit(:G_1235) if is_integer(:G_1235) else None) +else: + _hy_anon_var_12 = None