<commit_before>(ns swarmpit.docker.engine.mapper.compose
  (:require [clojure.string :as str]
            [clojure.set :refer [rename-keys]]
            [swarmpit.utils :refer [clean select-keys*]]
            [swarmpit.yaml :refer [->yaml]])
  (:refer-clojure :exclude [alias]))

(defn alias
  [key stackName map]
  (let [name (get map key)]
    (if (= stackName (:stack map))
      (str/replace name (str stackName "_") "")
      name)))

(defn group
  [stackName fn coll]
  (->> coll
       (map #(fn stackName %))
       (into {})))

(defn environment
  [variables]
  (map #(str (:name %) "=" (:value %)) variables))

(defn service-volumes
  [mounts]
  (map #(str (:host %) "=" (:containerPath %) (when (:readOnly %) ":ro")) mounts))

(defn resource
  [{:keys [cpu memory]}]
  {:cpus   (some-> cpu (str))
   :memory (some-> memory (str "M"))})

(defn service
  [stackName service]
  {(keyword (alias :serviceName stackName service))
   {:image       (-> service :repository :image)
    :environment (->> service :variables
                      (map #(str (:name %) "=" (:value %))))
    :ports       (->> service :ports
                      (map #(str (:hostPort %) ":" (:containerPort %) (when (= "udp" (:protocol %)) "/udp"))))
    :volumes     (->> service :mounts
                      (map #(str (alias :host stackName %) "=" (:containerPath %) (when (:readOnly %) ":ro"))))
    :networks    (->> service :networks (map #(alias :networkName stackName %)))
    :deploy      {:mode      (when-not (= "replicated" (:mode service)) (:mode service))
                  :placement {:constraints (->> service :deployment :placement (map :rule))}
                  :resources {:reservations (-> service :resources :reservation resource)
                              :limits       (-> service :resources :limit resource)}}}})

(defn network
  [stackName net]
  {(keyword (alias :networkName stackName net)) (select-keys net [:driver])})

(defn volume
  [stackName volume]
  {(keyword (alias :volumeName stackName volume)) (select-keys volume [:driver])})

(defn ->compose
  [stack]
  (let [name (:stackName stack)]
    (-> {:version  "3"
         :services (group name service (:services stack))
         :networks (group name network (:networks stack))
         :volumes  (group name volume (:volumes stack))}
        (clean))))<commit_msg>external resources added to compose file<commit_after>(ns swarmpit.docker.engine.mapper.compose
  (:require [clojure.string :as str]
            [clojure.set :refer [rename-keys]]
            [swarmpit.utils :refer [clean select-keys*]]
            [swarmpit.docker.utils :refer [trim-stack]]
            [swarmpit.yaml :refer [->yaml]])
  (:refer-clojure :exclude [alias]))

(defn in-stack?
  [stack-name map]
  (= stack-name (:stack map)))

(defn alias
  [key stack-name map]
  (let [name (get map key)]
    (if (in-stack? stack-name map)
      (trim-stack stack-name name)
      name)))

(defn group
  [stack-name fn coll]
  (->> coll
       (map #(fn stack-name %))
       (into {})))

(defn environment
  [variables]
  (map #(str (:name %) "=" (:value %)) variables))

(defn service-volumes
  [mounts]
  (map #(str (:host %) "=" (:containerPath %) (when (:readOnly %) ":ro")) mounts))

(defn resource
  [{:keys [cpu memory]}]
  {:cpus   (when (< 0 cpu) (str cpu))
   :memory (when (< 0 memory) (str memory "M"))})

(defn service
  [stack-name service]
  {(keyword (alias :serviceName stack-name service))
   {:image       (-> service :repository :image)
    :environment (->> service :variables
                      (map #(str (:name %) "=" (:value %))))
    :ports       (->> service :ports
                      (map #(str (:hostPort %) ":" (:containerPort %) (when (= "udp" (:protocol %)) "/udp"))))
    :volumes     (->> service :mounts
                      (map #(str (alias :host stack-name %) "=" (:containerPath %) (when (:readOnly %) ":ro"))))
    :networks    (->> service :networks (map #(alias :networkName stack-name %)))
    :deploy      {:mode      (when-not (= "replicated" (:mode service)) (:mode service))
                  :placement {:constraints (->> service :deployment :placement (map :rule))}
                  :resources {:reservations (-> service :resources :reservation resource)
                              :limits       (-> service :resources :limit resource)}}}})

(defn network
  [stack-name net]
  {(keyword (alias :networkName stack-name net))
   (if (in-stack? stack-name net)
     {:driver      (:driver net)
      :internal    (when (:internal net) true)
      :driver_opts (:options net)}
     {:external true})})

(defn volume
  [stack-name volume]
  {(keyword (alias :volumeName stack-name volume))
   (if (in-stack? stack-name volume)
     {:driver      (:driver volume)
      :driver_opts (:options volume)}
     {:external true})})

(defn secret
  [_ secret]
  {(keyword (:secretName secret))
   {:external true}})

(defn config
  [_ config]
  {(keyword (:configName config))
   {:external true}})

(defn ->compose
  [stack]
  (let [name (:stackName stack)]
    (-> {:version  "3"
         :services (group name service (:services stack))
         :networks (group name network (:networks stack))
         :volumes  (group name volume (:volumes stack))
         :configs  (group name config (:configs stack))
         :secrets  (group name secret (:secrets stack))}
        (clean))))
{'fraction_non_alphanumeric': 0.17534399404983264, 'fraction_numerical': 0.0007437709185570844, 'mean_word_length': 2.699449793672627, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6640434', 'n_tokens_mistral': 1782, 'n_tokens_neox': 1669, 'n_words': 486}