/.nrepl-port | /.nrepl-port | ||||
.hgignore | .hgignore | ||||
.hg/ | .hg/ | ||||
.clj-kondo |
(defproject tservice-plugins/quartet-metqc-report "v0.1.3" | |||||
(defproject quartet-metqc-report "0.1.3" | |||||
:description "Visualizes Quality Control(QC) results for Quartet Project." | :description "Visualizes Quality Control(QC) results for Quartet Project." | ||||
:url "https://github.com/tservice-plugins/quartet-metqc-report" | |||||
:url "https://github.com/chinese-quartet/quartet-metqc-report" | |||||
:license {:name "Eclipse Public License" | :license {:name "Eclipse Public License" | ||||
:url "http://www.eclipse.org/legal/epl-v10.html"} | :url "http://www.eclipse.org/legal/epl-v10.html"} | ||||
:min-lein-version "2.5.0" | :min-lein-version "2.5.0" | ||||
:dependencies | :dependencies | ||||
[[org.clojure/data.csv "1.0.0"] | [[org.clojure/data.csv "1.0.0"] | ||||
[me.raynes/fs "1.4.6"] | |||||
[com.github.yjcyxky/local-fs "0.1.5"] | |||||
[org.clojure/tools.logging "1.1.0"] | [org.clojure/tools.logging "1.1.0"] | ||||
[org.clojure/core.async "0.4.500" | |||||
:exclusions [org.clojure/tools.reader]]] | |||||
[metosin/spec-tools "0.10.5"]] | |||||
:test-paths ["test"] | |||||
:plugins [[lein-cloverage "1.0.13"] | |||||
[lein-shell "0.5.0"] | |||||
[lein-changelog "0.3.2"]] | |||||
:aliases {"update-version" ["shell" "sed" "-i" "" "s/version \"[0-9.]*\"/version \"${:version}\"/" "src/quartet_metqc_report/version.clj"]} | |||||
:deploy-repositories [["releases" :clojars]] | |||||
:release-tasks [["change" "version" "leiningen.release/bump-version"] | |||||
["change" "version" "leiningen.release/bump-version" "release"] | |||||
["changelog" "release"] | |||||
["update-version"] | |||||
["deploy"]] | |||||
:profiles | :profiles | ||||
{:provided | {:provided | ||||
{:dependencies | {:dependencies | ||||
[[org.clojure/clojure "1.10.1"] | [[org.clojure/clojure "1.10.1"] | ||||
[org.clojars.yjcyxky/tservice "0.6.0"]]} | |||||
[com.github.yjcyxky/tservice-core "0.2.0"]]} | |||||
:uberjar | :uberjar | ||||
{:auto-clean true | {:auto-clean true | ||||
:omit-source true | :omit-source true | ||||
:javac-options ["-target" "1.8", "-source" "1.8"] | :javac-options ["-target" "1.8", "-source" "1.8"] | ||||
:target-path "target/%s" | :target-path "target/%s" | ||||
:resource-paths ["resources"] | |||||
:uberjar-name "quartet-metqc-report.tservice-plugin.jar"}}) | |||||
:resource-paths ["resources"]}}) |
version: v0.1.3 | version: v0.1.3 | ||||
description: Generate the QC Report for Quartet Metabolomics data. | description: Generate the QC Report for Quartet Metabolomics data. | ||||
category: Report | category: Report | ||||
home: https://github.com/tservice-plugins/quartet-metqc-report | |||||
source: PGx | |||||
home: https://github.com/chinese-quartet/quartet-metqc-report | |||||
source: Chinese Quartet | |||||
short_name: quartet-metqc-report | short_name: quartet-metqc-report | ||||
icons: | icons: | ||||
- src: "" | - src: "" | ||||
type: image/png | type: image/png | ||||
sizes: 192x192 | sizes: 192x192 | ||||
author: PGx | |||||
author: Jingcheng Yang | |||||
maintainers: | |||||
- Jingcheng Yang | |||||
tags: | |||||
- R | |||||
- Chart | |||||
readme: https://github.com/chinese-quartet/quartet-metqc-report/blob/master/README.md | |||||
plugin: | plugin: | ||||
name: quartet-metqc-report | name: quartet-metqc-report | ||||
display-name: QC Report for Quartet Metabolomics | display-name: QC Report for Quartet Metabolomics | ||||
init: | init: | ||||
# Unpack environment file to the directory, repository/envs/quartet-metqc-report | # Unpack environment file to the directory, repository/envs/quartet-metqc-report | ||||
- step: unpack-env | - step: unpack-env | ||||
envname: quartet-metqc-report | |||||
postunpack: chmod a+x {{ENV_DEST_DIR}}/bin/metqc.sh | |||||
envtype: environment | |||||
envname: bin | |||||
postunpack: chmod a+x {{ENV_DIR}}/bin/metqc.sh | |||||
- step: unpack-env | |||||
envtype: environment | |||||
envname: renv | |||||
- step: unpack-env | |||||
envtype: environment | |||||
envname: requirements.txt | |||||
- step: unpack-env | |||||
envtype: environment | |||||
envname: renv.lock | |||||
- step: load-namespace | - step: load-namespace | ||||
namespace: tservice.plugins.quartet-metqc-report | |||||
namespace: quartet-metqc-report.core | |||||
- step: register-plugin | - step: register-plugin | ||||
entrypoint: tservice.plugins.quartet-metqc-report/metadata | |||||
entrypoint: quartet-metqc-report.core/metadata | |||||
- step: init-event | - step: init-event | ||||
entrypoint: tservice.plugins.quartet-metqc-report/events-init | |||||
entrypoint: quartet-metqc-report.core/events-init |
(ns quartet-metqc-report.core | |||||
(:require [tservice-core.tasks.http :as http-task] | |||||
[quartet-metqc-report.spec :as spec] | |||||
[quartet-metqc-report.task :as task])) | |||||
(def metadata | |||||
(http-task/make-routes "quartet-metqc-report" :ReportPlugin | |||||
{:method-type :post | |||||
:endpoint "quartet-metqc-report" | |||||
:summary "Generate the QC Report for Quartet Metabolomics data." | |||||
:body-schema spec/quartet-metqc-report-params-body | |||||
:response-schema any? | |||||
:handler task/post-handler})) | |||||
(def events-init task/events-init) |
(ns quartet-metqc-report.metqc | |||||
"A wrapper for metqc tool." | |||||
(:require [clojure.string :as clj-str] | |||||
[local-fs.core :as fs-lib] | |||||
[clojure.java.shell :as shell :refer [sh]] | |||||
[tservice-core.plugins.util :refer [call-command!]] | |||||
[tservice-core.plugins.env :refer [get-context-path add-env-to-path]] | |||||
[clojure.tools.logging :as log] | |||||
[quartet-metqc-report.version :as v])) | |||||
(defn call-metqc! | |||||
"Call metqc bash script. more details on https://github.com/chinese-quartet/MetQC | |||||
exp-file: Proteomics profiled data. | |||||
meta-file: proteomics metadata. | |||||
result-dir: A directory for result files." | |||||
[exp-file meta-file result-dir] | |||||
(let [command ["bash" "-c" | |||||
(format "metqc.sh -d %s -m %s -o %s" exp-file meta-file result-dir)] | |||||
path-var (add-env-to-path v/plugin-name) | |||||
rprofile (fs-lib/join-paths (get-context-path :env v/plugin-name) "Rprofile")] | |||||
(log/info "PATH variable: " path-var) | |||||
(log/info "Rprofile file is in " rprofile) | |||||
(shell/with-sh-env {:PATH path-var | |||||
:R_PROFILE_USER rprofile | |||||
:LC_ALL "en_US.utf-8" | |||||
:LANG "en_US.utf-8"} | |||||
(let [result (apply sh command)] | |||||
{:status (if (= (:exit result) 0) "Success" "Error") | |||||
:msg (str (:out result) "\n" (:err result))})))) | |||||
(defn multiqc | |||||
"A multiqc wrapper for generating multiqc report: | |||||
TODO: set the absolute path of multiqc binary instead of environment variable | |||||
Required: | |||||
analysis-dir: Analysis directory, e.g. data directory from project | |||||
outdir: Create report in the specified output directory. | |||||
Options: | |||||
| key | description | | |||||
| -------------------|-------------| | |||||
| :dry-run? | Dry run mode | | |||||
| :filename | Report filename. Use 'stdout' to print to standard out. | | |||||
| :comment | Custom comment, will be printed at the top of the report. | | |||||
| :title | Report title. Printed as page header, used for filename if not otherwise specified. | | |||||
| :force? | Overwrite any existing reports | | |||||
| :prepend-dirs? | Prepend directory to sample names | | |||||
| :template | default, other custom template | | |||||
| :config | Where is the config file | | |||||
| :env | An environemnt map for running multiqc, such as {:PATH (get-path-variable)} | | |||||
Example: | |||||
(multiqc 'XXX' 'YYY' {:filename 'ZZZ' | |||||
:comment '' | |||||
:title '' | |||||
:force? true | |||||
:prepend-dirs? true})" | |||||
[analysis-dir outdir {:keys [dry-run? filename comment title force? prepend-dirs? template config env] | |||||
:or {dry-run? false | |||||
force? true | |||||
prepend-dirs? false | |||||
filename "multiqc_report.html" | |||||
comment "" | |||||
template "default" | |||||
title "iSEQ Analyzer Report"}}] | |||||
(let [force-arg (if force? "--force" "") | |||||
dirs-arg (if prepend-dirs? "--dirs" "") | |||||
config-arg (if config (str "-c " config) "") | |||||
multiqc-command (filter #(> (count %) 0) ["multiqc" | |||||
force-arg dirs-arg config-arg | |||||
"--title" (format "'%s'" title) | |||||
"--comment" (format "'%s'" comment) | |||||
"--filename" filename | |||||
"--outdir" outdir | |||||
"-t" template | |||||
analysis-dir]) | |||||
command (clj-str/join " " multiqc-command)] | |||||
(if dry-run? | |||||
(log/info command) | |||||
(if env | |||||
(call-command! command env) | |||||
(call-command! command))))) | |||||
(defn is-localpath? | |||||
[filepath] | |||||
(re-matches #"^file:\/\/.*" filepath)) | |||||
(defn correct-filepath | |||||
[filepath] | |||||
(if (is-localpath? filepath) | |||||
(clj-str/replace filepath #"^file:\/\/" "") | |||||
filepath)) |
(ns quartet-metqc-report.spec | |||||
(:require [clojure.spec.alpha :as s] | |||||
[spec-tools.core :as st])) | |||||
;;; ------------------------------------------------ Event Specs ------------------------------------------------ | |||||
(s/def ::metadata_file | |||||
(st/spec | |||||
{:spec (s/and string? #(re-matches #"^[a-zA-Z0-9]+:\/\/(\/|\.\/)[a-zA-Z0-9_]+.*" %)) | |||||
:type :string | |||||
:description "File path for metadata file, such as file:///xxx/xxx/metadata.csv" | |||||
:swagger/default nil | |||||
:reason "The filepath must be string."})) | |||||
(s/def ::data_file | |||||
(st/spec | |||||
{:spec (s/and string? #(re-matches #"^[a-zA-Z0-9]+:\/\/(\/|\.\/)[a-zA-Z0-9_]+.*" %)) | |||||
:type :string | |||||
:description "File path for metabolomics profiled data, such as file:///xxx/xxx/data.csv" | |||||
:swagger/default nil | |||||
:reason "The filepath must be string."})) | |||||
(s/def ::name | |||||
(st/spec | |||||
{:spec string? | |||||
:type :string | |||||
:description "The name of the report" | |||||
:swagger/default "" | |||||
:reason "Not a valid name"})) | |||||
(s/def ::description | |||||
(st/spec | |||||
{:spec string? | |||||
:type :string | |||||
:description "Description of the report" | |||||
:swagger/default "" | |||||
:reason "Not a valid description."})) | |||||
(def quartet-metqc-report-params-body | |||||
"A spec for the body parameters." | |||||
(s/keys :req-un [::name ::data_file ::metadata_file] | |||||
:opt-un [::description])) |
(ns quartet-metqc-report.task | |||||
(:require [quartet-metqc-report.metqc :as metqc] | |||||
[local-fs.core :as fs-lib] | |||||
[tservice-core.plugins.env :refer [add-env-to-path create-task! update-task!]] | |||||
[tservice-core.plugins.util :as util] | |||||
[clojure.data.json :as json] | |||||
[clojure.tools.logging :as log] | |||||
[tservice-core.tasks.async :refer [publish-event! make-events-init]])) | |||||
(defn date | |||||
[] | |||||
(.format (java.text.SimpleDateFormat. "yyyy-MM-dd") | |||||
(new java.util.Date))) | |||||
(defn update-process! | |||||
[^String task-id ^Integer percentage] | |||||
(let [record (cond | |||||
(= percentage 100) {:status "Finished" | |||||
:percentage 100 | |||||
:finished_time (util/time->int (util/now))} | |||||
(= percentage -1) {:status "Failed" | |||||
:finished_time (util/time->int (util/now))} | |||||
:else {:percentage percentage}) | |||||
record (merge {:id task-id} record)] | |||||
(update-task! record))) | |||||
(defn update-log-process! | |||||
"Update message into log file and process into database." | |||||
[log-path coll task-id process] | |||||
(spit log-path (json/write-str coll)) | |||||
(update-process! task-id process)) | |||||
(defn post-handler | |||||
[{{:keys [name data_file metadata_file description owner plugin-context] | |||||
:or {description (format "Quality control report for %s" name)} | |||||
:as payload} :body}] | |||||
(log/info (format "Create a report %s with %s" name payload)) | |||||
(let [payload (merge {:description description} payload) | |||||
data-file (metqc/correct-filepath data_file) | |||||
metadata-file (metqc/correct-filepath metadata_file) | |||||
workdir (fs-lib/dirname data-file) | |||||
log-path (fs-lib/join-paths workdir "log") | |||||
response {:report (format "%s/multiqc_report.html" workdir) | |||||
:log log-path} | |||||
task-id (create-task! {:name name | |||||
:description description | |||||
:payload payload | |||||
:owner owner | |||||
:plugin-name "quartet-metqc-report" | |||||
:plugin-type "ReportPlugin" | |||||
:plugin-version (:plugin-version plugin-context) | |||||
:response response}) | |||||
result-dir (fs-lib/join-paths workdir "results")] | |||||
(fs-lib/create-directories! result-dir) | |||||
(spit log-path (json/write-str {:status "Running" | |||||
:msg ""})) | |||||
(update-process! task-id 0) | |||||
(publish-event! "quartet_metqc_report" | |||||
{:data-file data-file | |||||
:metadata-file metadata-file | |||||
:dest-dir workdir | |||||
:task-id task-id | |||||
:metadata {:name name | |||||
:description description | |||||
:plugin-name "quartet-metqc-report" | |||||
:plutin-type "ReportPlugin" | |||||
:plugin-version (:plugin-version plugin-context)}}) | |||||
response)) | |||||
(defn- make-report! | |||||
[{:keys [data-file metadata-file dest-dir metadata task-id]}] | |||||
(let [log-path (fs-lib/join-paths dest-dir "log") | |||||
result-dir (fs-lib/join-paths dest-dir "results") | |||||
parameters-file (fs-lib/join-paths result-dir "general_information.json") | |||||
results (util/chain-fn-coll [(fn [] | |||||
(update-process! task-id 20) | |||||
(metqc/call-metqc! data-file metadata-file result-dir)) | |||||
(fn [] | |||||
(update-process! task-id 50) | |||||
(spit parameters-file (json/write-str {"Report Name" (:name metadata) | |||||
"Description" (:description metadata) | |||||
"Report Tool" (format "%s-%s" | |||||
(:plugin-name metadata) | |||||
(:plugin-version metadata)) | |||||
"Team" "Quartet Team" | |||||
"Date" (date)})) | |||||
{:status "Success" :msg ""}) | |||||
(fn [] | |||||
(update-process! task-id 80) | |||||
(metqc/multiqc result-dir dest-dir | |||||
{:template "quartet_metabolite_report" | |||||
:title "Quartet Report for Metabolomics" | |||||
:env {:PATH (add-env-to-path "quartet-metqc-report")}}))] | |||||
(fn [result] (= (:status result) "Success"))) | |||||
status (:status (last results)) | |||||
msg (apply str (map :msg results)) | |||||
process (if (= status "Success") 100 -1)] | |||||
(log/info (format "Running batch command: %s" (pr-str results))) | |||||
(update-log-process! log-path {:status status | |||||
:msg msg} | |||||
task-id process))) | |||||
(def events-init | |||||
"Automatically called during startup; start event listener for quartet_metqc_report events." | |||||
(make-events-init "quartet_metqc_report" make-report!)) |
(ns quartet-metqc-report.version) | |||||
(def plugin-name "quartet-metqc-report") | |||||
(def version "0.1.3") |
(ns tservice.plugins.quartet-metqc-report | |||||
(:require [clojure.data.json :as json] | |||||
[clojure.spec.alpha :as s] | |||||
[spec-tools.core :as st] | |||||
[clojure.tools.logging :as log] | |||||
[tservice.lib.files :as ff] | |||||
[tservice.api.config :refer [add-env-to-path]] | |||||
[tservice.lib.fs :as fs-lib] | |||||
[tservice.vendor.multiqc :as mq] | |||||
[tservice.plugins.quartet-metqc-report.metqc :as metqc] | |||||
[tservice.api.task :refer [make-events-init publish-event! make-plugin-metadata create-task! update-process!]])) | |||||
;;; ------------------------------------------------ Event Specs ------------------------------------------------ | |||||
(s/def ::metadata_file | |||||
(st/spec | |||||
{:spec (s/and string? #(re-matches #"^[a-zA-Z0-9]+:\/\/(\/|\.\/)[a-zA-Z0-9_]+.*" %)) | |||||
:type :string | |||||
:description "File path for metadata file, such as file:///xxx/xxx/metadata.csv" | |||||
:swagger/default nil | |||||
:reason "The filepath must be string."})) | |||||
(s/def ::data_file | |||||
(st/spec | |||||
{:spec (s/and string? #(re-matches #"^[a-zA-Z0-9]+:\/\/(\/|\.\/)[a-zA-Z0-9_]+.*" %)) | |||||
:type :string | |||||
:description "File path for metabolomics profiled data, such as file:///xxx/xxx/data.csv" | |||||
:swagger/default nil | |||||
:reason "The filepath must be string."})) | |||||
(s/def ::name | |||||
(st/spec | |||||
{:spec string? | |||||
:type :string | |||||
:description "The name of the report" | |||||
:swagger/default "" | |||||
:reason "Not a valid name"})) | |||||
(s/def ::description | |||||
(st/spec | |||||
{:spec string? | |||||
:type :string | |||||
:description "Description of the report" | |||||
:swagger/default "" | |||||
:reason "Not a valid description."})) | |||||
(def quartet-metqc-report-params-body | |||||
"A spec for the body parameters." | |||||
(s/keys :req-un [::name ::data_file ::metadata_file] | |||||
:opt-un [::description])) | |||||
;;; ------------------------------------------------ Event Metadata ------------------------------------------------ | |||||
(def metadata | |||||
(make-plugin-metadata | |||||
{:name "quartet-metqc-report" | |||||
:summary "Visualizes Quality Control(QC) results from metabolomics data for Quartet Project." | |||||
:params-schema quartet-metqc-report-params-body | |||||
:handler (fn [{:keys [name data_file metadata_file description owner plugin-context] | |||||
:or {description (format "Quality control report for %s" name)} | |||||
:as payload}] | |||||
(let [payload (merge {:description description} payload) | |||||
data-file (metqc/correct-filepath data_file) | |||||
metadata-file (metqc/correct-filepath metadata_file) | |||||
workdir (metqc/dirname data-file) | |||||
log-path (fs-lib/join-paths workdir "log") | |||||
response {:report (format "%s/multiqc_report.html" workdir) | |||||
:log log-path | |||||
:response-type :data2report} | |||||
task-id (create-task! {:name name | |||||
:description description | |||||
:payload payload | |||||
:owner owner | |||||
:plugin-name "quartet-metqc-report" | |||||
:plugin-type "ReportPlugin" | |||||
:plugin-version (:plugin-version plugin-context) | |||||
:response response}) | |||||
result-dir (fs-lib/join-paths workdir "results")] | |||||
(fs-lib/create-directories! result-dir) | |||||
(log/info (format "Create a report %s with %s in %s" name payload workdir)) | |||||
(spit log-path (json/write-str {:status "Running" | |||||
:msg ""})) | |||||
(update-process! task-id 0) | |||||
(publish-event! "quartet_metqc_report" | |||||
{:data-file data-file | |||||
:metadata-file metadata-file | |||||
:dest-dir workdir | |||||
:task-id task-id | |||||
:metadata {:name name | |||||
:description description | |||||
:plugin-name "quartet-metqc-report" | |||||
:plutin-type "ReportPlugin" | |||||
:plugin-version (:plugin-version plugin-context)}}) | |||||
response)) | |||||
:plugin-type :ReportPlugin | |||||
:response-type :data2report})) | |||||
(defn update-log-process! | |||||
"Update message into log file and process into database." | |||||
[log-path coll task-id process] | |||||
(spit log-path (json/write-str coll)) | |||||
(update-process! task-id process)) | |||||
(defn date | |||||
[] | |||||
(.format (java.text.SimpleDateFormat. "yyyy-MM-dd") | |||||
(new java.util.Date))) | |||||
(defn- make-report! | |||||
[{:keys [data-file metadata-file dest-dir metadata task-id]}] | |||||
(let [log-path (fs-lib/join-paths dest-dir "log") | |||||
result-dir (fs-lib/join-paths dest-dir "results") | |||||
parameters-file (fs-lib/join-paths result-dir "general_information.json") | |||||
results (ff/chain-fn-coll [(fn [] | |||||
(update-process! task-id 20) | |||||
(metqc/call-metqc! data-file metadata-file result-dir)) | |||||
(fn [] | |||||
(update-process! task-id 50) | |||||
(spit parameters-file (json/write-str {"Report Name" (:name metadata) | |||||
"Description" (:description metadata) | |||||
"Report Tool" (format "%s-%s" | |||||
(:plugin-name metadata) | |||||
(:plugin-version metadata)) | |||||
"Team" "Quartet Team" | |||||
"Date" (date)})) | |||||
{:status "Success" :msg ""}) | |||||
(fn [] | |||||
(update-process! task-id 80) | |||||
(mq/multiqc result-dir dest-dir | |||||
{:template "quartet_metabolite_report" | |||||
:title "Quartet Report for Metabolomics" | |||||
:env {:PATH (add-env-to-path "quartet-metqc-report")}}))] | |||||
(fn [result] (= (:status result) "Success"))) | |||||
status (:status (last results)) | |||||
msg (apply str (map :msg results)) | |||||
process (if (= status "Success") 100 -1)] | |||||
(log/info (format "Running batch command: %s" (pr-str results))) | |||||
(update-log-process! log-path {:status status | |||||
:msg msg} | |||||
task-id process))) | |||||
;;; --------------------------------------------------- Lifecycle ---------------------------------------------------- | |||||
(def events-init | |||||
"Automatically called during startup; start event listener for quartet_metqc_report events." | |||||
(make-events-init "quartet_metqc_report" make-report!)) |
(ns tservice.plugins.quartet-metqc-report.metqc | |||||
"A wrapper for metqc tool." | |||||
(:require [tservice.api.config :refer [add-env-to-path]] | |||||
[tservice.lib.files :refer [is-localpath? get-plugin-jar-env-dir]] | |||||
[clojure.string :as clj-str] | |||||
[tservice.lib.fs :as fs-lib] | |||||
[clojure.java.shell :as shell :refer [sh]] | |||||
[clojure.java.io :refer [file]])) | |||||
(defn call-metqc! | |||||
"Call metqc bash script. more details on https://github.com/chinese-quartet/MetQC | |||||
exp-file: Proteomics profiled data. | |||||
meta-file: proteomics metadata. | |||||
result-dir: A directory for result files. | |||||
" | |||||
[exp-file meta-file result-dir] | |||||
(shell/with-sh-env {:PATH (add-env-to-path "quartet-metqc-report") | |||||
:R_PROFILE_USER (fs-lib/join-paths (get-plugin-jar-env-dir "quartet-metqc-report") "Rprofile") | |||||
:LC_ALL "en_US.utf-8" | |||||
:LANG "en_US.utf-8"} | |||||
(let [command ["bash" "-c" | |||||
(format "metqc.sh -d %s -m %s -o %s" exp-file meta-file result-dir)] | |||||
result (apply sh command) | |||||
status (if (= (:exit result) 0) "Success" "Error") | |||||
msg (str (:out result) "\n" (:err result))] | |||||
{:status status | |||||
:msg msg}))) | |||||
(defn correct-filepath | |||||
[filepath] | |||||
(if (is-localpath? filepath) | |||||
(clj-str/replace filepath #"^file:\/\/" "") | |||||
filepath)) | |||||
(defn ^String basename | |||||
"Returns the basename of 'path'. | |||||
This works by calling getName() on a java.io.File instance. It's prefered | |||||
over last-dir-in-path for that reason. | |||||
Parameters: | |||||
path - String containing the path for an item in iRODS. | |||||
Returns: | |||||
String containing the basename of path." | |||||
[^String path] | |||||
(.getName (file path))) | |||||
(defn ^String dirname | |||||
"Returns the dirname of 'path'. | |||||
This works by calling getParent() on a java.io.File instance. | |||||
Parameters: | |||||
path - String containing the path for an item in iRODS. | |||||
Returns: | |||||
String containing the dirname of path." | |||||
[^String path] | |||||
(when path (.getParent (file path)))) |