|
45 | 45 | ^File [lib]
|
46 | 46 | (jio/file (:gitlibs/dir @config/CONFIG) "libs" (namespace lib) (name lib)))
|
47 | 47 |
|
| 48 | +(def ^:private git-url-regex |
| 49 | + #"([a-z0-9+.-]+):\/\/(?:(?:(?:[^@]+?)@)?([^/]+?)(?::[0-9]*)?)?(/[^:]+)") |
| 50 | + |
| 51 | +(def ^:private git-scp-regex |
| 52 | + #"(?:(?:[^@]+?)@)?(.+?):([^:]+)") |
| 53 | + |
48 | 54 | (defn- clean-url
|
49 |
| - "Chop leading protocol, trailing .git, replace :'s with /" |
| 55 | + "Convert url into a safe relative path (this is not a reversible transformation) |
| 56 | + based on scheme, host, and path (drop user and port). |
| 57 | +
|
| 58 | + Examples: |
| 59 | + ssh://[email protected]:3333/org/repo.git => ssh/gitlab.com/org/repo |
| 60 | + [email protected]:dotted.org/dotted.repo.git => ssh/github.com/dotted.org/dotted.repo |
| 61 | + file://../foo => file/REL/_DOTDOT_/foo |
| 62 | + file:///Users/user/foo.git => file/Users/user/foo |
| 63 | + ../foo => file/REL/_DOTDOT_/foo |
| 64 | + ~user/foo.git => file/REL/_TILDE_user/foo |
| 65 | +
|
| 66 | + * https://git-scm.com/docs/git-clone#_git_urls |
| 67 | + * https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols |
| 68 | + " |
50 | 69 | [url]
|
51 |
| - (-> url |
52 |
| - (str/split #"://") |
53 |
| - last |
54 |
| - (str/replace #"\.git$" "") |
55 |
| - (str/replace #":" "/"))) |
| 70 | + (let [[scheme host path] (cond |
| 71 | + (str/starts-with? url "file://") ["file" nil (-> url (subs 7) (str/replace #"^([^/])" "REL/$1"))] |
| 72 | + (str/includes? url "://") (let [[_ s h p] (re-matches git-url-regex url)] [s h p]) |
| 73 | + (str/includes? url ":") (let [[_ h p] (re-matches git-scp-regex url)] ["ssh" h p]) |
| 74 | + :local-repo ["file" nil (str/replace url #"^([^/])" "REL/$1")]) |
| 75 | + clean-path (-> path |
| 76 | + (str/replace #"\.git/?$" "") ;; remove trailing .git or .git/ |
| 77 | + (str/replace #"~" "_TILDE_")) ;; replace ~ with _TILDE_ |
| 78 | + dir-parts (->> (concat [scheme host] (str/split clean-path #"/")) ;; split on / |
| 79 | + (remove str/blank?) ;; remove any missing path segments |
| 80 | + (map #(-> % ({"." "_DOT_", ".." "_DOTDOT_"} %))))] ;; replace . or .. segments |
| 81 | + (str/join "/" dir-parts))) |
56 | 82 |
|
57 | 83 | (defn git-dir
|
58 | 84 | ^File [url]
|
|
0 commit comments