mirror of
https://github.com/penpot/penpot.git
synced 2025-01-09 08:20:45 -05:00
Fix naming consistency on storages module.
This commit is contained in:
parent
aa4c39395f
commit
5fc7dd95f7
6 changed files with 61 additions and 48 deletions
|
@ -1,8 +1,8 @@
|
||||||
(ns storages.tests
|
(ns storages.tests
|
||||||
(:require [clojure.test :as t]
|
(:require [clojure.test :as t]
|
||||||
[storages.core :as st]
|
[storages.core :as st]
|
||||||
[storages.fs.local :as fs]
|
[storages.backend.local :as local]
|
||||||
[storages.fs.misc :as misc])
|
[storages.backend.misc :as misc])
|
||||||
(:import java.io.File
|
(:import java.io.File
|
||||||
org.apache.commons.io.FileUtils))
|
org.apache.commons.io.FileUtils))
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
;; --- Tests: FileSystemStorage
|
;; --- Tests: FileSystemStorage
|
||||||
|
|
||||||
(t/deftest test-localfs-store-and-lookup
|
(t/deftest test-localfs-store-and-lookup
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
rpath @(st/save storage "test.txt" "my content")
|
rpath @(st/save storage "test.txt" "my content")
|
||||||
fpath @(st/lookup storage rpath)
|
fpath @(st/lookup storage rpath)
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
(t/is (= "my content" fdata))))
|
(t/is (= "my content" fdata))))
|
||||||
|
|
||||||
(t/deftest test-localfs-store-and-get-public-url
|
(t/deftest test-localfs-store-and-get-public-url
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
rpath @(st/save storage "test.txt" "my content")
|
rpath @(st/save storage "test.txt" "my content")
|
||||||
ruri (st/public-url storage rpath)]
|
ruri (st/public-url storage rpath)]
|
||||||
(t/is (= (str ruri) "http://localhost:5050/test.txt"))))
|
(t/is (= (str ruri) "http://localhost:5050/test.txt"))))
|
||||||
|
|
||||||
(t/deftest test-localfs-store-and-lookup-with-subdirs
|
(t/deftest test-localfs-store-and-lookup-with-subdirs
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
rpath @(st/save storage "somepath/test.txt" "my content")
|
rpath @(st/save storage "somepath/test.txt" "my content")
|
||||||
fpath @(st/lookup storage rpath)
|
fpath @(st/lookup storage rpath)
|
||||||
|
@ -46,21 +46,21 @@
|
||||||
(t/is (= "my content" fdata))))
|
(t/is (= "my content" fdata))))
|
||||||
|
|
||||||
(t/deftest test-localfs-store-and-delete-and-check
|
(t/deftest test-localfs-store-and-delete-and-check
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
rpath @(st/save storage "test.txt" "my content")]
|
rpath @(st/save storage "test.txt" "my content")]
|
||||||
(t/is @(st/delete storage rpath))
|
(t/is @(st/delete storage rpath))
|
||||||
(t/is (not @(st/exists? storage rpath)))))
|
(t/is (not @(st/exists? storage rpath)))))
|
||||||
|
|
||||||
(t/deftest test-localfs-store-duplicate-file-raises-exception
|
(t/deftest test-localfs-store-duplicate-file-raises-exception
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})]
|
:baseuri "http://localhost:5050/"})]
|
||||||
(t/is @(st/save storage "test.txt" "my content"))
|
(t/is @(st/save storage "test.txt" "my content"))
|
||||||
(t/is (thrown? java.util.concurrent.ExecutionException
|
(t/is (thrown? java.util.concurrent.ExecutionException
|
||||||
@(st/save storage "test.txt" "my content")))))
|
@(st/save storage "test.txt" "my content")))))
|
||||||
|
|
||||||
(t/deftest test-localfs-access-unauthorized-path
|
(t/deftest test-localfs-access-unauthorized-path
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})]
|
:baseuri "http://localhost:5050/"})]
|
||||||
(t/is (thrown? java.util.concurrent.ExecutionException
|
(t/is (thrown? java.util.concurrent.ExecutionException
|
||||||
@(st/lookup storage "../test.txt")))
|
@(st/lookup storage "../test.txt")))
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
;; --- Tests: ScopedPathStorage
|
;; --- Tests: ScopedPathStorage
|
||||||
|
|
||||||
(t/deftest test-localfs-scoped-store-and-lookup
|
(t/deftest test-localfs-scoped-store-and-lookup
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
storage (misc/scoped storage "some/prefix")
|
storage (misc/scoped storage "some/prefix")
|
||||||
rpath @(st/save storage "test.txt" "my content")
|
rpath @(st/save storage "test.txt" "my content")
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
(t/is (= "my content" fdata))))
|
(t/is (= "my content" fdata))))
|
||||||
|
|
||||||
(t/deftest test-localfs-scoped-store-and-delete-and-check
|
(t/deftest test-localfs-scoped-store-and-delete-and-check
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
storage (misc/scoped storage "some/prefix")
|
storage (misc/scoped storage "some/prefix")
|
||||||
rpath @(st/save storage "test.txt" "my content")]
|
rpath @(st/save storage "test.txt" "my content")]
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
(t/is (not @(st/exists? storage rpath)))))
|
(t/is (not @(st/exists? storage rpath)))))
|
||||||
|
|
||||||
(t/deftest test-localfs-scoped-store-duplicate-file-raises-exception
|
(t/deftest test-localfs-scoped-store-duplicate-file-raises-exception
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
storage (misc/scoped storage "some/prefix")]
|
storage (misc/scoped storage "some/prefix")]
|
||||||
(t/is @(st/save storage "test.txt" "my content"))
|
(t/is @(st/save storage "test.txt" "my content"))
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
@(st/save storage "test.txt" "my content")))))
|
@(st/save storage "test.txt" "my content")))))
|
||||||
|
|
||||||
(t/deftest test-localfs-scoped-access-unauthorized-path
|
(t/deftest test-localfs-scoped-access-unauthorized-path
|
||||||
(let [storage (fs/filesystem {:basedir "/tmp/catacumba/test"
|
(let [storage (local/localfs {:basedir "/tmp/catacumba/test"
|
||||||
:baseuri "http://localhost:5050/"})
|
:baseuri "http://localhost:5050/"})
|
||||||
storage (misc/scoped storage "some/prefix")]
|
storage (misc/scoped storage "some/prefix")]
|
||||||
(t/is (thrown? java.util.concurrent.ExecutionException
|
(t/is (thrown? java.util.concurrent.ExecutionException
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns storages.fs.local
|
(ns storages.backend.local
|
||||||
"A local filesystem storage implementation."
|
"A local filesystem storage implementation."
|
||||||
(:require [promesa.core :as p]
|
(:require [promesa.core :as p]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[executors.core :as exec]
|
[executors.core :as exec]
|
||||||
[storages.proto :as pt]
|
[storages.proto :as pt]
|
||||||
[storages.impl :as impl]
|
[storages.impl :as impl]
|
||||||
[storages.util :as util])
|
[storages.fs :as fs])
|
||||||
(:import java.io.InputStream
|
(:import java.io.InputStream
|
||||||
java.io.OutputStream
|
java.io.OutputStream
|
||||||
java.net.URI
|
java.net.URI
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
(defn normalize-path
|
(defn normalize-path
|
||||||
[^Path base ^Path path]
|
[^Path base ^Path path]
|
||||||
(if (util/absolute? path)
|
(if (fs/absolute? path)
|
||||||
(throw (ex-info "Suspicios operation: absolute path not allowed."
|
(throw (ex-info "Suspicios operation: absolute path not allowed."
|
||||||
{:path (str path)}))
|
{:path (str path)}))
|
||||||
(let [^Path fullpath (.resolve base path)
|
(let [^Path fullpath (.resolve base path)
|
||||||
|
@ -34,11 +34,11 @@
|
||||||
[base path content]
|
[base path content]
|
||||||
(let [^Path path (pt/-path path)
|
(let [^Path path (pt/-path path)
|
||||||
^Path fullpath (normalize-path base path)]
|
^Path fullpath (normalize-path base path)]
|
||||||
(when-not (util/exists? (.getParent fullpath))
|
(when-not (fs/exists? (.getParent fullpath))
|
||||||
(util/create-dir! (.getParent fullpath)))
|
(fs/create-dir! (.getParent fullpath)))
|
||||||
(with-open [^InputStream source (pt/-input-stream content)
|
(with-open [^InputStream source (pt/-input-stream content)
|
||||||
^OutputStream dest (Files/newOutputStream
|
^OutputStream dest (Files/newOutputStream
|
||||||
fullpath util/write-open-opts)]
|
fullpath fs/write-open-opts)]
|
||||||
(io/copy source dest)
|
(io/copy source dest)
|
||||||
path)))
|
path)))
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
(normalize-path base))]
|
(normalize-path base))]
|
||||||
(Files/deleteIfExists ^Path path)))
|
(Files/deleteIfExists ^Path path)))
|
||||||
|
|
||||||
(defrecord FileSystemStorage [^Path base ^URI baseuri]
|
(defrecord LocalFileSystemBackend [^Path base ^URI baseuri]
|
||||||
pt/IPublicStorage
|
pt/IPublicStorage
|
||||||
(-public-uri [_ path]
|
(-public-uri [_ path]
|
||||||
(.resolve baseuri (str path)))
|
(.resolve baseuri (str path)))
|
||||||
|
@ -65,14 +65,14 @@
|
||||||
(p/resolved
|
(p/resolved
|
||||||
(let [path (->> (pt/-path path)
|
(let [path (->> (pt/-path path)
|
||||||
(normalize-path base))]
|
(normalize-path base))]
|
||||||
(util/exists? path)))
|
(fs/exists? path)))
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(p/rejected e))))
|
(p/rejected e))))
|
||||||
|
|
||||||
pt/IClearableStorage
|
pt/IClearableStorage
|
||||||
(-clear [_]
|
(-clear [_]
|
||||||
(util/delete-dir! base)
|
(fs/delete-dir! base)
|
||||||
(util/create-dir! base))
|
(fs/create-dir! base))
|
||||||
|
|
||||||
pt/ILocalStorage
|
pt/ILocalStorage
|
||||||
(-lookup [_ path']
|
(-lookup [_ path']
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(p/rejected e)))))
|
(p/rejected e)))))
|
||||||
|
|
||||||
(defn filesystem
|
(defn localfs
|
||||||
"Create an instance of local FileSystem storage providing an
|
"Create an instance of local FileSystem storage providing an
|
||||||
absolute base path.
|
absolute base path.
|
||||||
|
|
||||||
|
@ -93,12 +93,12 @@
|
||||||
[{:keys [basedir baseuri] :as keys}]
|
[{:keys [basedir baseuri] :as keys}]
|
||||||
(let [^Path basepath (pt/-path basedir)
|
(let [^Path basepath (pt/-path basedir)
|
||||||
^URI baseuri (pt/-uri baseuri)]
|
^URI baseuri (pt/-uri baseuri)]
|
||||||
(when (and (util/exists? basepath)
|
(when (and (fs/exists? basepath)
|
||||||
(not (util/directory? basepath)))
|
(not (fs/directory? basepath)))
|
||||||
(throw (ex-info "File already exists." {})))
|
(throw (ex-info "File already exists." {})))
|
||||||
|
|
||||||
(when-not (util/exists? basepath)
|
(when-not (fs/exists? basepath)
|
||||||
(util/create-dir! basepath))
|
(fs/create-dir! basepath))
|
||||||
|
|
||||||
(->FileSystemStorage basepath baseuri)))
|
(->LocalFileSystemBackend basepath baseuri)))
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns storages.fs.misc
|
(ns storages.backend.misc
|
||||||
"A local filesystem storage implementation."
|
"A local filesystem storage implementation."
|
||||||
(:require [promesa.core :as p]
|
(:require [promesa.core :as p]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
[buddy.core.hash :as hash]
|
[buddy.core.hash :as hash]
|
||||||
[storages.proto :as pt]
|
[storages.proto :as pt]
|
||||||
[storages.impl :as impl]
|
[storages.impl :as impl]
|
||||||
[storages.fs.local :as localfs])
|
[storages.backend.local :as local])
|
||||||
(:import java.io.InputStream
|
(:import java.io.InputStream
|
||||||
java.io.OutputStream
|
java.io.OutputStream
|
||||||
java.nio.file.Path
|
java.nio.file.Path
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
;; --- Scoped Storage
|
;; --- Scoped Storage
|
||||||
|
|
||||||
(defrecord ScopedPathStorage [storage ^Path prefix]
|
(defrecord ScopedBackend [storage ^Path prefix]
|
||||||
pt/IPublicStorage
|
pt/IPublicStorage
|
||||||
(-public-uri [_ path]
|
(-public-uri [_ path]
|
||||||
(let [^Path path (pt/-path [prefix path])]
|
(let [^Path path (pt/-path [prefix path])]
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
(p/map (fn [^Path base]
|
(p/map (fn [^Path base]
|
||||||
(let [base (pt/-path [base prefix])]
|
(let [base (pt/-path [base prefix])]
|
||||||
(->> (pt/-path path)
|
(->> (pt/-path path)
|
||||||
(localfs/normalize-path base))))))))
|
(local/normalize-path base))))))))
|
||||||
|
|
||||||
(defn scoped
|
(defn scoped
|
||||||
"Create a composed storage instance that automatically prefixes
|
"Create a composed storage instance that automatically prefixes
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
uploads."
|
uploads."
|
||||||
[storage prefix]
|
[storage prefix]
|
||||||
(let [prefix (pt/-path prefix)]
|
(let [prefix (pt/-path prefix)]
|
||||||
(->ScopedPathStorage storage prefix)))
|
(->ScopedBackend storage prefix)))
|
||||||
|
|
||||||
;; --- Hashed Storage
|
;; --- Hashed Storage
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
frest (apply str rest-tokens)]
|
frest (apply str rest-tokens)]
|
||||||
(pt/-path (list path frest name))))
|
(pt/-path (list path frest name))))
|
||||||
|
|
||||||
(defrecord HashedStorage [storage]
|
(defrecord HashedBackend [storage]
|
||||||
pt/IPublicStorage
|
pt/IPublicStorage
|
||||||
(-public-uri [_ path]
|
(-public-uri [_ path]
|
||||||
(pt/-public-uri storage path))
|
(pt/-public-uri storage path))
|
||||||
|
@ -107,5 +107,5 @@
|
||||||
This is usefull when you want to store files with
|
This is usefull when you want to store files with
|
||||||
not predictable uris."
|
not predictable uris."
|
||||||
[storage]
|
[storage]
|
||||||
(->HashedStorage storage))
|
(->HashedBackend storage))
|
||||||
|
|
7
backend/vendor/storages/core.clj
vendored
7
backend/vendor/storages/core.clj
vendored
|
@ -42,13 +42,6 @@
|
||||||
[storage]
|
[storage]
|
||||||
(pt/-clear storage))
|
(pt/-clear storage))
|
||||||
|
|
||||||
(defn path
|
|
||||||
"Create path from string or more than one string."
|
|
||||||
([fst]
|
|
||||||
(pt/-path fst))
|
|
||||||
([fst & more]
|
|
||||||
(pt/-path (cons fst more))))
|
|
||||||
|
|
||||||
(defn public-url
|
(defn public-url
|
||||||
[storage path]
|
[storage path]
|
||||||
(pt/-public-uri storage path))
|
(pt/-public-uri storage path))
|
||||||
|
|
|
@ -4,15 +4,17 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns storages.util
|
(ns storages.fs
|
||||||
"FileSystem related utils."
|
"File System helpers."
|
||||||
(:refer-clojure :exclude [name resolve])
|
(:refer-clojure :exclude [name resolve])
|
||||||
(:require [storages.proto :as pt])
|
(:require [storages.proto :as pt])
|
||||||
(:import java.nio.file.Path
|
(:import java.nio.file.Path
|
||||||
java.nio.file.Files
|
java.nio.file.Files
|
||||||
java.nio.file.LinkOption
|
java.nio.file.LinkOption
|
||||||
java.nio.file.OpenOption
|
java.nio.file.OpenOption
|
||||||
|
java.nio.file.CopyOption
|
||||||
java.nio.file.StandardOpenOption
|
java.nio.file.StandardOpenOption
|
||||||
|
java.nio.file.StandardCopyOption
|
||||||
java.nio.file.SimpleFileVisitor
|
java.nio.file.SimpleFileVisitor
|
||||||
java.nio.file.FileVisitResult
|
java.nio.file.FileVisitResult
|
||||||
java.nio.file.attribute.FileAttribute
|
java.nio.file.attribute.FileAttribute
|
||||||
|
@ -22,7 +24,7 @@
|
||||||
;; --- Constants
|
;; --- Constants
|
||||||
|
|
||||||
(def write-open-opts
|
(def write-open-opts
|
||||||
(->> [#_StandardOpenOption/CREATE_NEW
|
(->> [StandardOpenOption/TRUNCATE_EXISTING
|
||||||
StandardOpenOption/CREATE
|
StandardOpenOption/CREATE
|
||||||
StandardOpenOption/WRITE]
|
StandardOpenOption/WRITE]
|
||||||
(into-array OpenOption)))
|
(into-array OpenOption)))
|
||||||
|
@ -31,6 +33,11 @@
|
||||||
(->> [StandardOpenOption/READ]
|
(->> [StandardOpenOption/READ]
|
||||||
(into-array OpenOption)))
|
(into-array OpenOption)))
|
||||||
|
|
||||||
|
(def move-opts
|
||||||
|
(->> [StandardCopyOption/ATOMIC_MOVE
|
||||||
|
StandardCopyOption/REPLACE_EXISTING]
|
||||||
|
(into-array CopyOption)))
|
||||||
|
|
||||||
(def follow-link-opts
|
(def follow-link-opts
|
||||||
(into-array LinkOption [LinkOption/NOFOLLOW_LINKS]))
|
(into-array LinkOption [LinkOption/NOFOLLOW_LINKS]))
|
||||||
|
|
||||||
|
@ -128,6 +135,13 @@
|
||||||
|
|
||||||
;; --- Side-Effectfull Operations
|
;; --- Side-Effectfull Operations
|
||||||
|
|
||||||
|
(defn create-dir!
|
||||||
|
"Create a new directory."
|
||||||
|
[path]
|
||||||
|
(let [^Path path (pt/-path path)
|
||||||
|
attrs (make-file-attrs "rwxr-xr-x")]
|
||||||
|
(Files/createDirectories path attrs)))
|
||||||
|
|
||||||
(defn create-dir!
|
(defn create-dir!
|
||||||
"Create a new directory."
|
"Create a new directory."
|
||||||
[path]
|
[path]
|
||||||
|
@ -146,3 +160,9 @@
|
||||||
(Files/delete dir)
|
(Files/delete dir)
|
||||||
FileVisitResult/CONTINUE))]
|
FileVisitResult/CONTINUE))]
|
||||||
(Files/walkFileTree path visitor)))
|
(Files/walkFileTree path visitor)))
|
||||||
|
|
||||||
|
(defn create-tempfile
|
||||||
|
"Create a temporal file."
|
||||||
|
[& {:keys [suffix prefix]}]
|
||||||
|
(->> (make-file-attrs "rwxr-xr-x")
|
||||||
|
(Files/createTempFile prefix suffix)))
|
6
backend/vendor/storages/impl.clj
vendored
6
backend/vendor/storages/impl.clj
vendored
|
@ -7,7 +7,7 @@
|
||||||
(ns storages.impl
|
(ns storages.impl
|
||||||
"Implementation details and helpers."
|
"Implementation details and helpers."
|
||||||
(:require [storages.proto :as pt]
|
(:require [storages.proto :as pt]
|
||||||
[storages.util :as util]
|
[storages.fs :as fs]
|
||||||
[buddy.core.codecs :as codecs]
|
[buddy.core.codecs :as codecs]
|
||||||
[clojure.java.io :as io])
|
[clojure.java.io :as io])
|
||||||
(:import java.io.File
|
(:import java.io.File
|
||||||
|
@ -79,11 +79,11 @@
|
||||||
|
|
||||||
(defn- path->input-stream
|
(defn- path->input-stream
|
||||||
[^Path path]
|
[^Path path]
|
||||||
(Files/newInputStream path util/read-open-opts))
|
(Files/newInputStream path fs/read-open-opts))
|
||||||
|
|
||||||
(defn- path->output-stream
|
(defn- path->output-stream
|
||||||
[^Path path]
|
[^Path path]
|
||||||
(Files/newOutputStream path util/write-open-opts))
|
(Files/newOutputStream path fs/write-open-opts))
|
||||||
|
|
||||||
(extend-type Path
|
(extend-type Path
|
||||||
io/IOFactory
|
io/IOFactory
|
||||||
|
|
Loading…
Reference in a new issue