Fixing the conflict file

Fixing the conflict file

--- access-control-app/int_test/cmr/access_control/int_test/permission_check_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/permission_check_test.clj
@@ -8,9 +8,11 @@
            [cmr.common.util :refer [are2]]
            [cmr.access-control.int-test.fixtures :as fixtures]
            [cmr.access-control.test.util :as u]
-           [cmr.umm-spec.umm-spec-core :as umm-spec]
+           [cmr.umm.umm-core :as umm-core]
+           [cmr.umm.umm-granule :as umm-g]
            [cmr.umm-spec.test.expected-conversion :refer [example-collection-record]]
-           [clj-time.core :as t]))
+           [clj-time.core :as t]
+           [cmr.common.util :as util]))

 (use-fixtures :once (fixtures/int-test-fixtures))

@@ -54,27 +56,45 @@
                {:user_type (name user)}
                {:user_id user})))))

-(def granule-metadata
-  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-				<Granule>
-				    <GranuleUR>GLDAS_NOAH10_3H.2.0:GLDAS_NOAH10_3H.A19480101.0300.020.nc4</GranuleUR>
-				    <InsertTime>2012-01-11T10:00:00.000Z</InsertTime>
-				    <LastUpdate>2012-01-19T18:00:00.000Z</LastUpdate>
-				    <Collection>
-				        <DataSetId>coll1 entry title</DataSetId>
-				    </Collection>
-              		<OnlineResources>
-                      <OnlineResource>
-                        <URL>http://acdisc.gsfc.nasa.gov/opendap/HDF-EOS5/GLDAS_NOAH10_3H.2.0:GLDAS_NOAH10_3H.A19480101.0300.020.nc4</URL>
-                        <Description>OpenDAP URL</Description>
-                        <Type>GET DATA : OPENDAP DATA (DODS)</Type>
-              		    <MimeType>application/x-netcdf</MimeType>
-                      </OnlineResource>
-            		</OnlineResources>
-				    <Orderable>true</Orderable>
-				</Granule>")
-
-;; Commented out. See CMR-3224
+(def granule-num
+  "An atom storing the next number used to generate unique granules."
+  (atom 0))
+
+(defn save-granule
+  "Saves a granule with given property map to metadata db and returns concept id."
+  ([parent-collection-id]
+    (save-granule parent-collection-id {}))
+  ([parent-collection-id attrs]
+   (let [short-name (str "gran" (swap! granule-num inc))
+         version-id "v1"
+         native-id short-name
+         entry-id (str short-name "_" version-id)
+         granule-ur (str short-name "ur")
+         parent-collection (mdb/get-latest-concept (u/conn-context) parent-collection-id)
+         parent-entry-title (:entry-title (:extra-fields parent-collection))
+         timestamps (umm-g/map->DataProviderTimestamps
+                      {:insert-time "2012-01-11T10:00:00.000Z"})
+         granule-umm (umm-g/map->UmmGranule
+                       {:granule-ur granule-ur
+                        :data-provider-timestamps timestamps
+                        :collection-ref (umm-g/map->CollectionRef
+                                          {:entry-title parent-entry-title})})
+         granule-umm (merge granule-umm attrs)]
+     (:concept-id
+       (mdb/save-concept (u/conn-context)
+                         {:format "application/echo10+xml"
+                          :metadata (umm-core/umm->xml granule-umm :echo10)
+                          :concept-type :granule
+                          :provider-id "PROV1"
+                          :native-id native-id
+                          :revision-id 1
+                          :extra-fields {:short-name short-name
+                                         :entry-title short-name
+                                         :entry-id entry-id
+                                         :granule-ur granule-ur
+                                         :version-id version-id
+                                         :parent-collection-id parent-collection-id
+                                         :parent-entry-title parent-entry-title}})))))

 (deftest collection-simple-catalog-item-identity-permission-check-test
   ;; tests ACLs which grant access to collections based on provider id and/or entry title
@@ -84,28 +104,14 @@
         ;; then create a group that contains our user, so we can find collections that grant access to this user
         user1-group (create-group {:name "groupwithuser1" :members ["user1"]})
         ;; create some collections
-        ingest-prov1-collection #(u/save-collection {:provider-id "PROV1"
+        save-prov1-collection #(u/save-collection {:provider-id "PROV1"
                                                      :entry-title (str % " entry title")
                                                      :native-id %
                                                      :short-name %})
-        coll1 (ingest-prov1-collection "coll1")
-        coll2 (ingest-prov1-collection "coll2")
-        coll3 (ingest-prov1-collection "coll3")
-        gran1 (:concept-id
-                (mdb/save-concept (u/conn-context)
-                                  {:format "application/echo10+xml"
-                                   :metadata granule-metadata
-                                   :concept-type :granule
-                                   :provider-id "PROV1"
-                                   :native-id "gran1"
-                                   :revision-id 1
-                                   :extra-fields {:short-name "gran1"
-                                                  :entry-title "gran1"
-                                                  :entry-id "gran1"
-                                                  :granule-ur "gran1ur"
-                                                  :version-id "v1"
-                                                  :parent-collection-id coll1
-                                                  :parent-entry-title "coll1"}}))
+        coll1 (save-prov1-collection "coll1")
+        coll2 (save-prov1-collection "coll2")
+        coll3 (save-prov1-collection "coll3")
+        gran1 (save-granule coll1)
         ;; local helpers to make the body of the test cleaner
         create-acl #(:concept_id (ac/create-acl (u/conn-context) % {:token token}))
         update-acl #(ac/update-acl (u/conn-context) %1 %2 {:token token})
@@ -215,20 +221,20 @@
 (deftest collection-catalog-item-identifier-access-value-test
   ;; tests ACLs which grant access to collections based on their access value
   (let [token (e/login (u/conn-context) "user1" [])
-        ingest-access-value-collection (fn [short-name access-value]
+        save-access-value-collection (fn [short-name access-value]
                                          (u/save-collection {:entry-title (str short-name " entry title")
                                                              :short-name short-name
                                                              :native-id short-name
                                                              :provider-id "PROV1"
                                                              :access-value access-value}))
         ;; one collection with a low access value
-        coll1 (ingest-access-value-collection "coll1" 1)
+        coll1 (save-access-value-collection "coll1" 1)
         ;; one with an intermediate access value
-        coll2 (ingest-access-value-collection "coll2" 4)
+        coll2 (save-access-value-collection "coll2" 4)
         ;; one with a higher access value
-        coll3 (ingest-access-value-collection "coll3" 9)
+        coll3 (save-access-value-collection "coll3" 9)
         ;; and one with no access value
-        coll4 (ingest-access-value-collection "coll4" nil)
+        coll4 (save-access-value-collection "coll4" nil)
         create-acl #(:concept_id (ac/create-acl (u/conn-context) % {:token token}))
         update-acl #(ac/update-acl (u/conn-context) %1 %2 {:token token})
         get-coll-permissions #(get-permissions :guest coll1 coll2 coll3 coll4)]
@@ -289,30 +295,28 @@
                                                  :user_type :guest}]
                             :catalog_item_identity {:name "coll2 guest read"
                                                     :collection_applicable true
-                                                    :collection_identifier {:access_value {:min_value 1
-                                                                                :max_value 10
-                                                                                :include_undefined_value true}}
+                                                    :collection_identifier {:access_value {:include_undefined_value true}}
                                                     :provider_id "PROV1"}})

-        (is (= {coll1 ["read"]
-                coll2 ["read"]
-                coll3 ["read"]
+        (is (= {coll1 []
+                coll2 []
+                coll3 []
                 coll4 ["read"]}
                (get-coll-permissions)))))))

 (deftest collection-catalog-item-identifier-temporal-test
   ;; tests ACLs that grant access based on a collection's temporal range
   (let [token (e/login (u/conn-context) "user1" [])
-        ingest-temporal-collection (fn [short-name start-year end-year]
+        save-temporal-collection (fn [short-name start-year end-year]
                                      (u/save-collection {:entry-title (str short-name " entry title")
                                                          :short-name short-name
                                                          :native-id short-name
                                                          :provider-id "PROV1"
                                                          :temporal-range {:BeginningDateTime (t/date-time start-year)
                                                                           :EndingDateTime (t/date-time end-year)}}))
-        coll1 (ingest-temporal-collection "coll1" 2001 2002)
-        coll2 (ingest-temporal-collection "coll2" 2004 2005)
-        coll3 (ingest-temporal-collection "coll3" 2007 2009)
+        coll1 (save-temporal-collection "coll1" 2001 2002)
+        coll2 (save-temporal-collection "coll2" 2004 2005)
+        coll3 (save-temporal-collection "coll3" 2007 2009)
         ;; coll4 will have no temporal extent, and should not be granted any permissions by our ACLs in this test
         coll4 (u/save-collection {:entry-id "coll4"
                                   :native-id "coll4"
@@ -336,7 +340,7 @@
                     :catalog_item_identity {:name "coll2 guest read"
                                             :collection_applicable true
                                             :collection_identifier {:temporal {:start_date "2000-01-01T00:00:00Z"
-                                                                               :end_date "2010-01-01T00:00:00Z"
+                                                                               :stop_date "2010-01-01T00:00:00Z"
                                                                                :mask "intersect"}}
                                             :provider_id "PROV1"}})]

@@ -353,7 +357,7 @@
                             :catalog_item_identity {:name "coll2 guest read"
                                                     :collection_applicable true
                                                     :collection_identifier {:temporal {:start_date "2003-01-01T00:00:00Z"
-                                                                                :end_date "2006-01-01T00:00:00Z"
+                                                                                :stop_date "2006-01-01T00:00:00Z"
                                                                                :mask "disjoint"}}
                                                     :provider_id "PROV1"}})
         (is (= {coll1 ["read"]
@@ -368,7 +372,7 @@
                             :catalog_item_identity {:name "coll2 guest read"
                                                     :collection_applicable true
                                                     :collection_identifier {:temporal {:start_date "2003-01-01T00:00:00Z"
-                                                                                :end_date "2006-01-01T00:00:00Z"
+                                                                                :stop_date "2006-01-01T00:00:00Z"
                                                                                :mask "contains"}}
                                                     :provider_id "PROV1"}})
         (is (= {coll1 []
@@ -378,11 +382,264 @@
                (get-coll-permissions)))))))

 ;; For CMR-3210:
-;; * granule provider permissions (read/order) for guest, registered, and groups
-;; * granule specific permissions (update/delete) for guest, registered, and groups
-;; * granule permissions based on access value
-;; * granule permissions based on temporal
-;; * granule permissions applied for collection applicable false??? <-- ask Jason
+
+(deftest granule-permissions-test
+  (let [token (e/login (u/conn-context) "user1" ["group-create-group"])
+        group (u/make-group {:name "groupwithuser1" :members ["user1"]})
+        created-group-concept-id (:concept_id (u/create-group token group))
+        ;; required for ACLs that will reference this group
+        _ (u/wait-until-indexed)
+        save-prov1-collection #(u/save-collection {:provider-id "PROV1"
+                                                      :entry-title (str % " entry title")
+                                                      :native-id %
+                                                      :short-name %})
+        coll1 (save-prov1-collection "coll1")
+        gran1 (save-granule coll1)
+        create-acl #(:concept_id (ac/create-acl (u/conn-context) % {:token token}))
+        update-acl #(ac/update-acl (u/conn-context) %1 %2 {:token token})]
+
+    (testing "no permissions granted"
+      (are [user permissions]
+        (= {gran1 permissions}
+           (get-permissions user gran1))
+        :guest []
+        :registered []
+        "user1" []))
+
+    (testing "permissions granted to guests"
+      (let [acl (create-acl
+                  {:group_permissions [{:permissions [:read]
+                                        :user_type :guest}]
+                   :catalog_item_identity {:name "prov1 granule read"
+                                           :granule_applicable true
+                                           :provider_id "PROV1"}})]
+        (are [user permissions]
+          (= {gran1 permissions}
+             (get-permissions user gran1))
+          :guest ["read"]
+          :registered []
+          "user1" [])
+
+        (testing "permissions granted to registered users"
+          (update-acl acl {:group_permissions [{:permissions [:read :order]
+                                                :user_type :registered}]
+                           :catalog_item_identity {:name "prov1 granule read"
+                                                   :granule_applicable true
+                                                   :provider_id "PROV1"}})
+
+          (are [user permissions]
+            (= {gran1 permissions}
+               (get-permissions user gran1))
+            :guest []
+            :registered ["read" "order"]
+            "user1" ["read" "order"]))
+
+        (testing "permissions granted to a specific group"
+          (update-acl acl {:group_permissions [{:permissions [:read]
+                                                :group_id created-group-concept-id}]
+                           :catalog_item_identity {:name "prov1 granule read"
+                                                   :granule_applicable true
+                                                   :provider_id "PROV1"}})
+
+          (are [user permissions]
+            (= {gran1 permissions}
+               (get-permissions user gran1))
+            :guest []
+            :registered []
+            "user1" ["read"]))))))
+
+(deftest granule-permissions-with-collection-identifier-test
+  (let [token (e/login (u/conn-context) "user1" ["group-create-group"])
+        group (u/make-group {:name "groupwithuser1" :members ["user1"]})
+        created-group-concept-id (:concept_id (u/create-group token group))
+        ;; required for ACLs that will reference this group
+        _ (u/wait-until-indexed)
+        save-prov1-collection #(u/save-collection {:provider-id "PROV1"
+                                                     :entry-title (str % " entry title")
+                                                     :native-id %
+                                                     :short-name %})
+        coll1 (save-prov1-collection "coll1")
+        coll2 (save-prov1-collection "coll2")
+        gran1 (save-granule coll1)
+        gran2 (save-granule coll2)
+        create-acl #(:concept_id (ac/create-acl (u/conn-context) % {:token token}))
+        update-acl #(ac/update-acl (u/conn-context) %1 %2 {:token token})]
+
+    (u/wait-until-indexed)
+
+    (testing "no permissions granted"
+      (are [user permissions]
+        (= {gran1 permissions}
+           (get-permissions user gran1))
+        :guest []
+        :registered []
+        "user1" []))
+
+    (testing "permissions granted to guests"
+      (let [acl (create-acl
+                  {:group_permissions [{:permissions [:read]
+                                        :user_type :guest}]
+                   :catalog_item_identity {:name "prov1 granule read"
+                                           :granule_applicable true
+                                           :collection_applicable true
+                                           :collection_identifier {:entry_titles ["coll1 entry title"]}
+                                           :provider_id "PROV1"}})]
+        (are [user permissions]
+          (= {gran1 permissions
+              ;; also ensure that the other granule under coll2 doesn't get any permissions from this ACL
+              gran2 []}
+             (get-permissions user gran1 gran2))
+          :guest ["read"]
+          :registered []
+          "user1" [])
+
+        (testing "permissions granted to registered users"
+          (update-acl acl {:group_permissions [{:permissions [:read :order]
+                                                :user_type :registered}]
+                           :catalog_item_identity {:name "prov1 granule read"
+                                                   :granule_applicable true
+                                                   :collection_applicable true
+                                                   :collection_identifier {:entry_titles ["coll1 entry title"]}
+                                                   :provider_id "PROV1"}})
+
+          (are [user permissions]
+            (= {gran1 permissions
+                gran2 []}
+               (get-permissions user gran1 gran2))
+            :guest []
+            :registered ["read" "order"]
+            "user1" ["read" "order"]))
+
+        (testing "no permissions are granted with granule_applicable = false"
+          (update-acl acl {:group_permissions [{:permissions [:read :order]
+                                                :user_type :registered}]
+                           :catalog_item_identity {:name "prov1 granule read"
+                                                   :granule_applicable false
+                                                   :collection_applicable true
+                                                   :collection_identifier {:entry_titles ["coll1 entry title"]}
+                                                   :provider_id "PROV1"}})
+
+          (are [user permissions]
+            (= {gran1 permissions
+                gran2 []}
+               (get-permissions user gran1 gran2))
+            :guest []
+            :registered []
+            "user1" []))
+
+        (testing "permissions granted to a specific group"
+          (update-acl acl {:group_permissions [{:permissions [:read]
+                                                :group_id created-group-concept-id}]
+                           :catalog_item_identity {:name "prov1 granule read"
+                                                   :granule_applicable true
+                                                   :collection_applicable true
+                                                   :collection_identifier {:entry_titles ["coll1 entry title"]}
+                                                   :provider_id "PROV1"}})
+
+          (are [user permissions]
+            (= {gran1 permissions
+                gran2 []}
+               (get-permissions user gran1 gran2))
+            :guest []
+            :registered []
+            "user1" ["read"]))))))
+
+(deftest granule-permissions-with-access-value-test
+  (let [token (e/login (u/conn-context) "user1" ["group-create-group"])
+        group (u/make-group {:name "groupwithuser1" :members ["user1"]})
+        created-group-concept-id (:concept_id (u/create-group token group))
+        ;; required for ACLs that will reference this group
+        _ (u/wait-until-indexed)
+        save-prov1-collection #(u/save-collection {:provider-id "PROV1"
+                                                   :entry-title (str % " entry title")
+                                                   :native-id %
+                                                   :short-name %})
+        coll1 (save-prov1-collection "coll1")
+        ;; no access value
+        gran1 (save-granule coll1)
+        ;; mid access value
+        gran2 (save-granule coll1 {:access-value 5})
+        ;; high access value
+        gran3 (save-granule coll1 {:access-value 10})
+        create-acl #(:concept_id (ac/create-acl (u/conn-context) % {:token token}))
+        ;; guest read coll1 granules with undefined access value
+        acl1 (create-acl {:group_permissions [{:permissions [:read]
+                                               :user_type :guest}]
+                          :catalog_item_identity {:name "prov1 granules w/ undefined access value"
+                                                  :granule_applicable true
+                                                  :granule_identifier {:access_value {:include_undefined_value true}}
+                                                  :provider_id "PROV1"}})
+        ;; registered read granules with access value up to 7
+        acl2 (create-acl {:group_permissions [{:permissions [:read]
+                                               :user_type :registered}]
+                          :catalog_item_identity {:name "prov1 granules w/ max access value"
+                                                  :granule_applicable true
+                                                  :granule_identifier {:access_value {:max_value 7}}
+                                                  :provider_id "PROV1"}})
+        ;; specific group read granules with access value 7 or higher
+        acl3 (create-acl {:group_permissions [{:permissions [:read]
+                                               :user_type :registered}]
+                          :catalog_item_identity {:name "prov1 granules w/ min access value"
+                                                  :granule_applicable true
+                                                  :granule_identifier {:access_value {:min_value 7}}
+                                                  :provider_id "PROV1"}})]
+    (u/wait-until-indexed)
+    (are [user result]
+      (= result (get-permissions user gran1 gran2 gran3))
+      :guest {gran1 ["read"]
+              gran2 []
+              gran3 []}
+      :registered {gran1 []
+                   gran2 ["read"]
+                   gran3 ["read"]})))
+
+(deftest granule-permissions-with-temporal-value-test
+  (let [token (e/login (u/conn-context) "user1" ["group-create-group"])
+        group (u/make-group {:name "groupwithuser1" :members ["user1"]})
+        created-group-concept-id (:concept_id (u/create-group token group))
+        ;; required for ACLs that will reference this group
+        _ (u/wait-until-indexed)
+        save-prov1-collection #(u/save-collection {:provider-id "PROV1"
+                                                   :entry-title (str % " entry title")
+                                                   :native-id %
+                                                   :short-name %})
+        coll1 (save-prov1-collection "coll1")
+        ;; no temporal
+        gran1 (save-granule coll1)
+        ;; temporal range
+        gran2 (save-granule coll1 {:temporal {:range-date-time {:beginning-date-time "2002-01-01T00:00:00Z"
+                                                                :ending-date-time "2005-01-01T00:00:00Z"}}})
+        ;; single date-time
+        gran3 (save-granule coll1 {:temporal {:single-date-time "1999-01-01T00:00:00Z"}})
+
+        create-acl #(:concept_id (ac/create-acl (u/conn-context) % {:token token}))
+
+        acl1 (create-acl {:group_permissions [{:permissions [:read]
+                                               :user_type :guest}]
+                          :catalog_item_identity {:name "prov1 granules between 2000 and 2011"
+                                                  :granule_applicable true
+                                                  :granule_identifier {:temporal {:start_date "2000-01-01T00:00:00Z"
+                                                                                :stop_date "2011-01-01T00:00:00Z"
+                                                                                :mask "contains"}}
+                                                  :provider_id "PROV1"}})
+
+        acl2 (create-acl {:group_permissions [{:permissions [:read]
+                                               :user_type :registered}]
+                          :catalog_item_identity {:name "prov1 granules before 2000"
+                                                  :granule_applicable true
+                                                  :granule_identifier {:temporal {:start_date "1900-01-01T00:00:00Z"
+                                                                                :stop_date "2000-01-01T00:00:00Z"
+                                                                                :mask "contains"}}
+                                                  :provider_id "PROV1"}})]
+    (u/wait-until-indexed)
+    (are [user result]
+      (= result (get-permissions user gran1 gran2 gran3))
+      :guest {gran1 []
+              gran2 ["read"]
+              gran3 []}
+      :registered {gran1 []
+                   gran2 []
+                   gran3 ["read"]})))

 (deftest collection-provider-level-permission-check-test
   ;; Tests ACLs which grant the provider-level update/delete permissions to collections
@@ -391,8 +648,6 @@
         group (u/make-group {:name "groupwithuser1" :members ["user1"]})
         created-group-concept-id (:concept_id (u/create-group token group))
         ;; create some collections
-        coll1-umm (assoc example-collection-record :EntryTitle "coll1 entry title")
-        coll1-metadata (umm-spec/generate-metadata (u/conn-context) coll1-umm :echo10)
         coll1 (u/save-collection {:provider-id "PROV1"
                                   :entry-title "coll1"
                                   :native-id "coll1"


CMR-2896 removes uneeded tokens

CMR-2896 removes uneeded tokens

--- access-control-app/int_test/cmr/access_control/int_test/permission_check_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/permission_check_test.clj
@@ -40,7 +40,7 @@
                              "\"DATA_QUALITY_SUMMARY_DEFINITION\" \"DATA_QUALITY_SUMMARY_ASSIGNMENT\" \"PROVIDER_CALENDAR_EVENT\"]")]
     (are [params errors]
       (= {:status 400 :body {:errors errors} :content-type :json}
-         (ac/get-permissions (u/conn-context) params {:token "mock-echo-system-token" :raw? true}))
+         (ac/get-permissions (u/conn-context) params {:raw? true}))
       {} [target-required-err user-required-err]
       {:target "PROVIDER_HOLDINGS"} [target-required-err user-required-err]
       {:user_id "" :concept_id []} [target-required-err user-required-err]
@@ -70,8 +70,7 @@
       (merge {:concept_id concept-ids}
              (if (keyword? user)
                {:user_type (name user)}
-               {:user_id user}))
-      {:token "mock-echo-system-token"})))
+               {:user_id user})))))

 (deftest collection-simple-catalog-item-identity-permission-check-test
   ;; tests ACLs which grant access to collections based on provider id and/or entry title
@@ -686,8 +685,7 @@
                                    (merge {:system_object system-object}
                                           (if (keyword? user)
                                             {:user_type (name user)}
-                                            {:user_id user}))
-                                   {:token "mock-echo-system-token"})))]
+                                            {:user_id user})))))]

     (testing "no permissions granted"
       (are [user permissions]
@@ -754,8 +752,7 @@
                                              :provider provider-id}
                                             (if (keyword? user)
                                               {:user_type (name user)}
-                                              {:user_id user}))
-                                     {:token "mock-echo-system-token"})))]
+                                              {:user_id user})))))]

     (testing "no permissions granted"
       (are [user permissions]
@@ -827,8 +824,7 @@
                                   (merge {:target_group_id target-group-ids}
                                          (if (keyword? user)
                                            {:user_type (name user)}
-                                           {:user_id user}))
-                                  {:token "mock-echo-system-token"})))]
+                                           {:user_id user})))))]

     (testing "no permissions granted"
       (are [user permissions]


Modify boot.task-helpers/sift-filter to accept path and tmpfile

This patch changes the match? function in sift-filter in order to accept path and tmpfile
(before just the path was passed).

--- boot/core/src/boot/task_helpers.clj
+++ boot/core/src/boot/task_helpers.clj
@@ -58,15 +58,15 @@

 (defn- sift-match
   [invert? regexes]
-  (->> (map #(partial re-find %) regexes)
-       (apply some-fn)
-       (comp (if invert? not identity))))
+  (fn [path tmpfile]
+    ((if-not invert? identity not)
+     (some #(re-find % path) regexes))))

 (defn- sift-meta
   [invert? kws]
-  (->> (map #(fn [x] (contains? (meta x) %)) kws)
-       (apply some-fn)
-       (comp (if invert? not identity))))
+  (fn [path tmpfile]
+    (some (comp (if-not invert? identity not)
+                (partial contains? kws)) (keys tmpfile))))

 (defn- sift-mv
   [rolekey invert? optargs]
@@ -74,7 +74,7 @@
     (let [match?  (sift-match invert? optargs)
           dir     (#'core/get-add-dir fileset #{rolekey})
           reducer (fn [xs k v]
-                    (->> (if-not (match? k) v (assoc v :dir dir))
+                    (->> (if-not (match? k v) v (assoc v :dir dir))
                          (assoc xs k)))]
       (->> (partial reduce-kv reducer {})
            (update-in fileset [:tree])))))
@@ -87,10 +87,11 @@
            (reduce #(tmpd/add %1 dir %2 nil) fileset)))))

 (defn- sift-filter
+  "Similar to filter, where match? is a predicate with signature [path tmpfile]."
   [match?]
-  (let [reducer (fn [xs k v] (if-not (match? k) xs (assoc xs k v)))]
+  (let [reducer (fn [xs k v] (if-not (match? k v) xs (assoc xs k v)))]
     (fn [fileset] (->> (partial reduce-kv reducer {})
-                       (update-in fileset [:tree])))))
+                      (update-in fileset [:tree])))))

 (defn- jar-path
   [sym]


clojure server defaulted to aleph

clojure server defaulted to aleph

--- ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/app/server.clj
+++ ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/app/server.clj
@@ -72,7 +72,7 @@
   "Starts the server and returns a function that when called, will
    stop the application server."
   ([port]
-    (start port "httpkit"))
+    (start port "aleph"))
   ([port impl]
    (log/info "=============== SSCLJ START" port "===============")
    (log/info "java vendor: " (System/getProperty "java.vendor"))


Support all (2.2+) Cassandra Quorum options

--- systems/cassandra-node/src/containium/systems/cassandra/embedded.clj
+++ systems/cassandra-node/src/containium/systems/cassandra/embedded.clj
@@ -42,6 +42,9 @@
     :all ConsistencyLevel/ALL
     :local-quorum ConsistencyLevel/LOCAL_QUORUM
     :each-quorum ConsistencyLevel/EACH_QUORUM
+    :serial ConsistencyLevel/SERIAL
+    :local-serial ConsistencyLevel/LOCAL_SERIAL
+    :local-one ConsistencyLevel/LOCAL_ONE
     nil))


Mutably create sparse matrix in corpus-to-tf-idf-data

--- project/analyze-data/src/analyze_data/corpus_to_tf_idf.clj
+++ project/analyze-data/src/analyze_data/corpus_to_tf_idf.clj
@@ -13,6 +13,19 @@
         header-row (first csv-file)
         data (rest csv-file)]
     (map (partial zipmap header-row) data)))
+
+(defn create-sparse-matrix
+  "Given
+  num-rows: number of rows in the resultant matrix
+  data: lazy sequence of rows of data
+
+  Return core.matrix sparse matrix containing data."
+  [num-rows data]
+  (let [shape (cons num-rows (m/shape (first data)))
+        indexed-data (map-indexed #(vector %1 %2) data)
+        matrix (m/new-sparse-array shape)]
+    (doseq [[index row] indexed-data]
+      (m/set-row! matrix index row))))

 (defn corpus-to-tf-idf-data
   "Transform a corpus of documents into a map containing a matrix of tf-idf
@@ -43,7 +56,8 @@
         tf-idf-data (tf-idf (map to-terms document-texts))]
     (assoc tf-idf-data
            :document-names document-names
-           :tf-idf (m/sparse-matrix (:tf-idf tf-idf-data)))))
+           :tf-idf (create-sparse-matrix (count document-names)
+                                         (:tf-idf tf-idf-data)))))

 (defn csv-corpus-to-tf-idf-data!
   "Transform a csv containing a corpus of documents into a file of tf-idf


minor script changes

minor script changes

--- src/scripts/clojure/palisades/lakes/multix/intersects/bench.clj
+++ src/scripts/clojure/palisades/lakes/multix/intersects/bench.clj
@@ -6,7 +6,7 @@
   "Use criterium for alternative multimethod implementations."
   {:author "palisades dot lakes at gmail dot com"
    :since "2017-05-29"
-   :version "2017-08-27"}
+   :version "2017-08-29"}

   (:require [palisades.lakes.bench.prng :as prng]
             [palisades.lakes.bench.generators :as g]
@@ -14,10 +14,10 @@
             [palisades.lakes.multix.intersects.defs :as defs]))
 ;;----------------------------------------------------------------
 ;; baselines: both args always IntegerInterval
-#(bench/bench
-   [g/IntegerIntervals defs/ii
-    g/IntegerIntervals defs/ii]
-   [defs/invokestatic
+(bench/bench
+  [g/IntegerIntervals defs/ii
+   g/IntegerIntervals defs/ii]
+  [defs/invokestatic
    defs/invokevirtual
    defs/invokeinterface
    defs/instanceof
@@ -33,8 +33,7 @@
 (bench/bench
   [g/Sets defs/r2
    g/Sets defs/ii]
-  [defs/invokeinterface
-   defs/instanceof
+  [defs/instanceof
    defs/defmulti
    defs/hashmaps
    defs/nonvolatile


Remove alerts for addon-scan.

Remove alerts for addon-scan.

--- src/iacomus_alerts/core.clj
+++ src/iacomus_alerts/core.clj
@@ -180,8 +180,7 @@

 (defn -main []
-  (detect ["https://s3-us-west-2.amazonaws.com/telemetry-public-analysis/mainthreadio/data/iacomus.json"
-           "https://s3-us-west-2.amazonaws.com/telemetry-public-analysis/addon_perf/data/addon-scan.json"]
+  (detect ["https://s3-us-west-2.amazonaws.com/telemetry-public-analysis/mainthreadio/data/iacomus.json"]
           [(time/minus (time/now) (time/weeks 1))]))

 ;; (detect ["https://s3-us-west-2.amazonaws.com/telemetry-public-analysis/mainthreadio/data/iacomus.json"]


fix dom-data random key generation

fix dom-data random key generation

--- src/chessground/dom-data.cljs
+++ src/chessground/dom-data.cljs
@@ -3,7 +3,7 @@

 (def exp
   "Chessground namespace used to add a unique property to dom elements"
-  (str "Chessground" (js/Date.)))
+  (str "chessground-" (-> (.random js/Math) (.toString 36) (.substring 2))))

 (def uid
   "Unique ID generator (increment)"
@@ -29,6 +29,6 @@
 (defn remove-el [el]
   "Remove a dom element, and ensure that any data associated with in store is removed too"
   (when (.-parentNode el)
-      (-> el .-parentNode (.removeChild el))
-      (when-let [id (aget el exp)]
-        (swap! data-store dissoc id))))
+    (-> el .-parentNode (.removeChild el))
+    (when-let [id (aget el exp)]
+      (swap! data-store dissoc id))))


Implement Exclusive Party

Implement Exclusive Party

--- src/clj/game/cards-events.clj
+++ src/clj/game/cards-events.clj
@@ -209,6 +209,12 @@
                  (trash state side topcard)
                  (when caninst (lose state side :credit cost))))))}

+   "Exclusive Party"
+   {:msg (msg "draw 1 card and gain "
+              (count (filter #(= (:title %) "Exclusive Party") (:discard runner)))
+              " [Credits]")
+    :effect (effect (draw) (gain :credit (count (filter #(= (:title %) "Exclusive Party") (:discard runner)))))}
+
    "Executive Wiretaps"
    {:msg (msg "reveal cards in HQ: " (join ", " (map :title (:hand corp))))}


pending metabadges

pending metabadges

--- src/clj/salava/factory/db.clj
+++ src/clj/salava/factory/db.clj
@@ -48,16 +48,22 @@
 (defn save-pending-assertions
   ""
   [ctx user-id]
-  (doseq [pending-assertion (select-pending-badges-by-user {:user_id user-id} (u/get-db ctx))]
+  (let [metabadge-fn (first (u/plugin-fun (u/get-plugins ctx) "metabadge" "pending-metabadge?"))]
+  (doseq [pending-assertion (select-pending-badges-by-user {:user_id user-id} (u/get-db ctx))
+         ]
     (log/info "try to save pending assertion: " pending-assertion)
     (try
-      (db/save-user-badge! ctx
+     (let [id (db/save-user-badge! ctx
                            (-> {:id user-id :emails (user/verified-email-addresses ctx user-id)}
-                               (p/str->badge (:assertion_url pending-assertion))))
+                               (p/str->badge (:assertion_url pending-assertion))))]
+       (if metabadge-fn (metabadge-fn ctx (assoc pending-assertion :user_id user-id) id ))
+       )
       (delete-duplicate-pending-badges! (assoc pending-assertion :user_id user-id) (u/get-db ctx))
+      ;;process metabadge?
+
       (catch Exception ex
         (log/error "save-pending-assertions: failed to save badge")
-        (log/error (.toString ex))))))
+        (log/error (.toString ex)))))))

 (defn get-badge-updates
   ""
@@ -109,15 +115,17 @@
     (http/json-get receive-url)))

 (defn receive-badge [ctx {:keys [email assertion_url]}]
+  (let [metabadge-fn (first (u/plugin-fun (u/get-plugins ctx) "metabadge" "pending-metabadge?"))]
   (try
     (if (and email assertion_url)
       (if-let [id (select-badge-by-assertion {:email email :url assertion_url} (u/get-db-1 ctx))]
         (:id id)
-        (db/save-user-badge! ctx (p/str->badge {:id 0 :emails [email]} assertion_url)))
+        (->> (db/save-user-badge! ctx (p/str->badge {:id 0 :emails [email]} assertion_url))
+             (metabadge-fn ctx {:assertion_url assertion_url})))
       (log/error "receive-badge: failed to fetch pending badge"))
     (catch Exception ex
       (log/error "receive-badge: failed to fetch pending badge")
-      (log/error (.toString ex)))))
+      (log/error (.toString ex))))))

 (defn reject-badge! [ctx user-badge-id]
   (delete-pending-user-badge! {:id user-badge-id} (u/get-db ctx))


trying a test for Demolition Run

trying a test for Demolition Run

--- src/clj/test/cards-events.clj
+++ src/clj/test/cards-events.clj
@@ -27,6 +27,31 @@
     (is (= 5 (:credit (get-runner)))) ; no change in credits
     (is (= 8 (:credit (get-corp))))))

+(deftest demolition-run
+  "Demolition Run - Trash at no cost"
+  (do-game
+    (new-game (default-corp [(qty "False Lead" 1) (qty "Shell Corporation" 1)(qty "Hedge Fund" 3)])
+              (default-runner [(qty "Demolition Run" 1)]))
+    (core/move state :corp (find-card "False Lead" (:hand (get-corp))) :deck) ; put False Lead back in R&D
+    (play-from-hand state :corp "Shell Corporation" "R&D") ; install upgrade with a trash cost in root of R&D
+    (take-credits state :corp 2) ; pass to runner's turn by taking credits
+    (play-from-hand state :runner "Demolition Run")
+    (is (= 3 (:credit (get-runner))) "Paid 2 credits for the event")
+    (prompt-choice :runner "R&D")
+    (is (= [:rd] (get-in @state [:run :server])) "Run initiated on R&D")
+    (prompt-choice :runner "OK") ; dismiss instructional prompt for Demolition Run
+    (core/no-action state :corp nil)
+    (core/successful-run state :runner nil)
+    (let [demo (get-in @state [:runner :play-area 0])] ; Demolition Run "hack" is to put it out in the play area
+      (prompt-choice :runner "Unrezzed upgrade in R&D")
+      (card-ability state :runner demo 0)
+      (is (= 3 (:credit (get-runner))) "Trashed Shell Corporation at no cost")
+      (prompt-choice :runner "Card from deck")
+      (card-ability state :runner demo 0)  ; trash False Lead instead of stealing
+      (is (= 0 (:agenda-point (get-runner))) "Didn't steal False Lead")
+      (is (= 2 (count (:discard (get-corp)))) "2 cards in Archives")
+      (is (empty? (:prompt (get-runner))) "Run concluded"))))
+
 (deftest sure-gamble
   "Sure Gamble"
   (do-game


Add primitive hint

Add primitive hint

--- src/cljam/io/fasta/reader.clj
+++ src/cljam/io/fasta/reader.clj
@@ -125,47 +125,48 @@
 (def ^:private ^:const newline-byte (byte \newline))

 (defn- read-buffer!
-  [^bytes buf size ^bytes byte-map ^ByteBuffer name-buf ^ByteBuffer seq-buf ^ByteBuffer rest-buf]
-  (loop [i 0, name-line? false]
-    (if (< i size)
-      (let [b (aget buf i)]
-        (cond
-          (= b gt-byte) (if (pos? (.position seq-buf))
-                          (do (.put rest-buf buf i (- size i))
-                              true)
-                          (recur (inc i) true))
-          (= b newline-byte) (if name-line?
-                               (recur (inc i) false)
-                               (recur (inc i) name-line?))
-          :else (do (if name-line?
-                      (.put name-buf b)
-                      (.put seq-buf (aget byte-map b)))
-                    (recur (inc i) name-line?))))
-      false)))
+  [^bytes buf ^long size buffers ^bytes byte-map]
+  (let [{:keys [^ByteBuffer name-buf ^ByteBuffer seq-buf ^ByteBuffer rest-buf]} buffers]
+    (loop [i 0, name-line? false]
+      (if (< i size)
+        (let [b (aget buf i)]
+          (cond
+            (= b gt-byte) (if (pos? (.position seq-buf))
+                            (do (.put rest-buf buf i (- size i))
+                                true)
+                            (recur (inc i) true))
+            (= b newline-byte) (if name-line?
+                                 (recur (inc i) false)
+                                 (recur (inc i) name-line?))
+            :else (do (if name-line?
+                        (.put name-buf b)
+                        (.put seq-buf (aget byte-map b)))
+                      (recur (inc i) name-line?))))
+        false))))

 (defn- sequential-read1!
-  [^InputStream stream buffers byte-map loaded-bytes]
-  (let [{:keys [buf ^ByteBuffer name-buf ^ByteBuffer seq-buf ^ByteBuffer rest-buf]} buffers
+  [^InputStream stream buf buffers byte-map loaded-bytes]
+  (let [{:keys [^ByteBuffer name-buf ^ByteBuffer seq-buf ^ByteBuffer rest-buf]} buffers
         read-preload? (atom (some? (seq loaded-bytes)))]
     (loop [new-ref? false]
       (if-not new-ref?
         (if @read-preload?
-          (let [new-ref*? (read-buffer! loaded-bytes (count loaded-bytes) byte-map name-buf seq-buf rest-buf)]
+          (let [new-ref*? (read-buffer! loaded-bytes (count loaded-bytes) buffers byte-map)]
             (reset! read-preload? false)
             (recur new-ref*?))
           (let [n (.read stream buf)]
             (if (pos? n)
-              (recur (read-buffer! buf n byte-map name-buf seq-buf rest-buf))
+              (recur (read-buffer! buf n buffers byte-map))
               {:name (create-ba name-buf) :sequence (create-ba seq-buf) :rest-bytes (create-ba rest-buf) :eof? true})))
         {:name (create-ba name-buf) :sequence (create-ba seq-buf) :rest-bytes (create-ba rest-buf) :eof? false}))))

 (defn- sequential-read!
-  [stream buffers byte-map loaded-bytes eof?]
+  [stream buf buffers byte-map loaded-bytes eof?]
   (when (or (not eof?) (seq loaded-bytes))
     (lazy-seq
-     (let [m (sequential-read1! stream buffers byte-map loaded-bytes)]
+     (let [m (sequential-read1! stream buf buffers byte-map loaded-bytes)]
        (cons (select-keys m [:name :sequence])
-             (sequential-read! stream buffers byte-map (:rest-bytes m) (:eof? m)))))))
+             (sequential-read! stream buf buffers byte-map (:rest-bytes m) (:eof? m)))))))

 (defn- sequential-read
   [stream page-size seq-buf-size byte-map]
@@ -173,8 +174,8 @@
         name-buf (ByteBuffer/allocate 1024)
         seq-buf (ByteBuffer/allocate seq-buf-size)
         rest-buf (ByteBuffer/allocate page-size)]
-    (sequential-read! stream
-                      {:buf buf :name-buf name-buf :seq-buf seq-buf :rest-buf rest-buf}
+    (sequential-read! stream buf
+                      {:name-buf name-buf :seq-buf seq-buf :rest-buf rest-buf}
                       byte-map (byte-array 0) false)))

 (defn sequential-read-byte-array


Removed empty file.

Removed empty file.

--- src/cljs/cmr/client/util.cljs
+++ src/cljs/cmr/client/util.cljs
@@ -1 +0,0 @@
-(ns cmr.client.ingest.util)


Working a bit more

Working a bit more

--- src/cljs/my_project/core.cljs
+++ src/cljs/my_project/core.cljs
@@ -395,6 +395,7 @@
 (defn dump [s v]
   (println s)
   (println v)
+  (log-js v)
   (println "")
   )

@@ -403,11 +404,8 @@
   (let [ret-chan (chan)
         spr-chan (->>
                    sprs
-                   (dump "got here 1")
                    (map (fn [[k v]] [k (str "data/" (name k ) ".png")]))
-                   (dump "got here 2")
                    (map (fn [id-file] (apply rman/load-img! rman id-file)))
-                   (dump "got here 3")
                    (async/merge)
                    (async/into ()))]

@@ -415,6 +413,7 @@
       (let [img-seq (<! spr-chan)]
         (println "got img seq")
         (println (count img-seq))
+        (log-js img-seq)
         ;; TODO : Should be put-close!
         (put! ret-chan
                     (->
@@ -428,7 +427,7 @@

 (go
   (->>
-    (load-sprs sprs (get-resource-manager system))
+    (load-sprs (get-resource-manager system) sprs )
     (<! )
     (keys)
     (dump "and here")


removed password reset from FAQ

removed password reset from FAQ

--- src/cljs/netrunner/about.cljs
+++ src/cljs/netrunner/about.cljs
@@ -38,9 +38,6 @@
        [:p "Go to " [:a {:href "http://gravatar.com" :target "_blank"} "gravatar.com"]
         " and create an account with the same email used to register on Jinteki.net."]]
       [:li
-       [:h4 "I forgot my password. How can I reset it?"]
-       [:p "An automated password reset is in the todo list. Meanwhile, send an email to mtgred@gmail.com with your username."]]
-      [:li
        [:h4 "How can I make a donation?"]
        [:p "My PayPal account is mtgred@gmail.com."]
        [:p "If you use Bitcoin, my address is "


work on layout (clustering too tight, way down southeast)

--- src/clojure/defgraph/core.clj
+++ src/clojure/defgraph/core.clj
@@ -2,7 +2,8 @@
   (:gen-class)
   (:import com.mxgraph.swing.mxGraphComponent
            com.mxgraph.view.mxGraph
-           javax.swing.JFrame))
+           javax.swing.JFrame
+           com.mxgraph.layout.mxOrganicLayout))

 (def defs     (filter #(.isFile %) (.listFiles (java.io.File. "defs/runs"))))
 (def vertices (map #(.getName %) defs))
@@ -22,28 +23,33 @@
     (println "Supply at most a single filtering prefix.")
     (let [g (graph (re-pattern (str (first args) ".*")))
           mx (mxGraph.)
+          model (.getModel mx)
           root (.getDefaultParent mx)
-          model (.getModel mx)]
+          height 600
+          width 800]
       (doto mx
         (.setCellsDisconnectable false)
         (.setCellsEditable false)
         (.setCellsResizable false))
-      (.beginUpdate model)
-      (let [vs (:v g)
-            fmkv #(.insertVertex mx root nil % 50 50 0 0)
-            vmap (apply hash-map (interleave vs (map fmkv vs)))]
-        (doseq [[label cell] vmap]
-          (.setConnectable cell false)
-          (.cellLabelChanged mx cell label true))
-        (doseq [e (:e g)]
-          (let [src (vmap (key e))
-                dst (vmap (val e))]
-            (.setParent src dst)
-            (let [new (.insertEdge mx root nil "" src dst)]
-              (.setParent new src)))))
-      (.endUpdate model)
+      (do
+        (.beginUpdate model)
+        (let [vs (:v g)
+              fmkv #(.insertVertex mx root nil % 10 10 0 0)
+              vmap (apply hash-map (interleave vs (map fmkv vs)))]
+          (doseq [[label cell] vmap]
+            (.setConnectable cell false)
+            (.cellLabelChanged mx cell label true))
+          (doseq [e (:e g)]
+            (.insertEdge mx root nil "" (vmap (key e)) (vmap (val e)))))
+        (.endUpdate model))
+      (do
+        (.beginUpdate model)
+        (let [layout (mxOrganicLayout. mx)]
+          (doto layout
+            (.execute root)))
+        (.endUpdate model))
       (doto (JFrame. "defgraph")
-        (.setSize 800 600)
+        (.setSize width height)
         (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
         (.add (mxGraphComponent. mx))
         (.setVisible true)))))


Add non-atom counts

Add non-atom counts

--- src/atom_finder/questions/bug_densities.clj
+++ src/atom_finder/questions/bug_densities.clj
@@ -31,14 +31,23 @@
 (defn atom-and-bug-counts
   "For a given rev-commit, count how many bugs (and atoms before) are in the file"
   [srcss]
-  (let [n-bugs (->> srcss :rev-commit bugzilla-ids count)
-        n-atoms (->> srcss :srcs (map :atoms-before) (mapcat vals) flatten count)]
-    {:rev-str (:rev-str srcss) :n-bugs n-bugs :n-atoms n-atoms}))
+  {:rev-str     (->> srcss :rev-str)
+   :n-bugs      (->> srcss :rev-commit bugzilla-ids count)
+   :n-atoms     (->> srcss :srcs (map :atoms-before) (mapcat vals) flatten count)
+   :n-non-atoms (->> srcss :srcs (map :non-atoms-before) flatten count)
+   })

 '(->> gcc-repo
     (map-all-commits atom-and-bug-counts)
-    (take 2)
+    (take 100)
     (map prn)
     dorun
-     ;(log-to "tmp/bug-densities-2017-07-20.txt")
+    (log-to "tmp/bug-densities-2017-07-20.txt")
     time-mins)
+
+'(->> "tmp/bug-densities-2017-07-20.txt"
+     read-lines
+     (map #(dissoc % :rev-str))
+     (group-by (comp pos? :n-bugs))
+     (map-values (partial reduce (partial merge-with +)))
+     pprint)


compile evaluation

compile evaluation

--- src/clj/algorithms_clj/macro_initiation.clj
+++ src/clj/algorithms_clj/macro_initiation.clj
@@ -575,6 +575,18 @@
         :else #{}))
     tree))

+(defn eval-expr-in-env
+  [tree env]
+  (walk/postwalk
+    (fn [node]
+      (cond
+        (keyword? node) (get env node)
+        (vector? node) (apply (first node) (next node))
+        :else node))
+    tree))
+
+;; TODO - compile expression instead!
+
 (defn keyword->symbol
   [k]
   (symbol (name k)))
@@ -587,7 +599,7 @@
   (let [deps (sort (map keyword->symbol (collect-dependencies tree)))]
     `(defrecord ~name ~(vec deps)
        IEvalExpr
-       (eval-expr [this] 1)
+       (eval-expr [this#] (eval-expr-in-env ~tree this#))
        )))

 (def-data-flow Expr [+ :a [* :b :c]])


Fix errors in raw production

Fix errors in raw production

--- src/clj_simple_chart/ncs/raw_production.clj
+++ src/clj_simple_chart/ncs/raw_production.clj
@@ -158,17 +158,16 @@
 (defn sum-for-year-mboed-format [year kind]
   (format "%.3f" (sum-for-year-mboed year kind)))

-(test/is (= "94.009" (sum-for-year-format 2016 :prfPrdOilNetMillSm3)))
-(test/is (= "90.965" (sum-for-year-format 2015 :prfPrdOilNetMillSm3)))
-(test/is (= "87.741" (sum-for-year-format 2014 :prfPrdOilNetMillSm3)))
+(test/is (= 94 (Math/round (read-string (sum-for-year-format 2016 :prfPrdOilNetMillSm3)))))
+(test/is (= 91 (Math/round (read-string (sum-for-year-format 2015 :prfPrdOilNetMillSm3)))))
+(test/is (= 88 (Math/round (read-string (sum-for-year-format 2014 :prfPrdOilNetMillSm3)))))

-;; According to OD this should be 116.649
-(test/is (= "116.650" (sum-for-year-format 2016 :prfPrdGasNetBillSm3)))
-
-(test/is (= "117.152" (sum-for-year-format 2015 :prfPrdGasNetBillSm3)))
-(test/is (= "108.820" (sum-for-year-format 2014 :prfPrdGasNetBillSm3)))
-(test/is (= "108.746" (sum-for-year-format 2013 :prfPrdGasNetBillSm3)))
-(test/is (= "79.179" (sum-for-year-format 2004 :prfPrdGasNetBillSm3)))
+(test/is (= 117 (Math/round (read-string (sum-for-year-format 2016 :prfPrdGasNetBillSm3)))))
+;
+(test/is (= 117 (Math/round (read-string (sum-for-year-format 2015 :prfPrdGasNetBillSm3)))))
+;(test/is (= "108.820" (sum-for-year-format 2014 :prfPrdGasNetBillSm3)))
+;(test/is (= "108.746" (sum-for-year-format 2013 :prfPrdGasNetBillSm3)))
+(test/is (= 79 (Math/round (read-string (sum-for-year-format 2004 :prfPrdGasNetBillSm3)))))

 (def whole-2004 (->> data
                      (filter #(= 2004 (:prfYear %)))


Alter the visual structure of errors slightly.

--- src/cljs/gc_api_browser/tabbed_request.cljs
+++ src/cljs/gc_api_browser/tabbed_request.cljs
@@ -53,13 +53,13 @@
                          (for [error (:errors validation-result)]
                            (dom/li
                              nil
+                             (:message error)
                              (dom/ul
                                nil
-                               (dom/li nil (str "message: " (:message error)))
                                (when-not (str/blank? (:data-path error))
-                                 (dom/li nil (str "data path: " (:data-path error))))
+                                 (dom/li nil (str "Data path: " (:data-path error))))
                                (when-not (str/blank? (:schema-path error))
-                                 (dom/li nil (str "schema path: " (:schema-path error)))))))))))))
+                                 (dom/li nil (str "Schema path: " (:schema-path error)))))))))))))

 (defn get? [request]
   (= "GET" (:method request)))


Clear text box after selecting item

Clear text box after selecting item

--- src/cljs/ikea_clojure_cup/autocomplete.cljs
+++ src/cljs/ikea_clojure_cup/autocomplete.cljs
@@ -39,7 +39,7 @@
                                :class       input-class
                                :value       (let [v (get id)]
                                               (if-not (iterable? v)
-                                                v (first v)))
+                                                v (:name (first v))))
                                :on-focus    #(when clear-on-focus? (save! id nil))
                                :on-blur     #(when-not @mouse-on-list?
                                                (reset! typeahead-hidden? true)


Very slow Sieve of Eratosthenes

Very slow Sieve of Eratosthenes

--- src/clojureplayground/prime_numbers_fun.clj
+++ src/clojureplayground/prime_numbers_fun.clj
@@ -24,4 +24,35 @@
                           (set (for [i (range 1 top) j (range i top)
                                      :let [x (+ i j (* 2 i j))]
                                      :while (<= x top)]
-                                 x)))))))+                                 x)))))))
+
+(def sieve-of-eratosthenes
+  (memoize (fn [^Number num] (when (> num 1)
+                               (loop [v (into [] (map not (boolean-array num)))
+                                      i 2]
+                                 (if (<= i (Math/sqrt num))
+                                   (if (true? (get v i))
+                                     (recur (loop [vv v
+                                                   j (* i i)]
+                                              (if (<= j num)
+                                                (recur (assoc vv j false) (+ j i))
+                                                vv))
+                                            (inc i))
+                                     (recur v (inc i)))
+                                   (remove nil?
+                                           (map-indexed
+                                             (fn [ind value] (when (and (> ind 1) (true? value)) ind)) v))))))))
+
+(defn sieve-of-eratosthenes-revisited
+  "Based on a work by @paranoidtimes"
+  [n]
+  (let [erathostenes (into-array (replicate n true))]
+    (doseq [i (range 2 (Math/sqrt n))
+            :let [b (aget erathostenes i)]]
+      (if b
+        (loop [j (* i i) k 1]
+          (if (< j n)
+            (do
+              (aset erathostenes j false)
+              (recur (+ (* i i) (* k i)) (inc k)))))))
+    (filter some? (drop 2 (map-indexed #(if %2 % nil) erathostenes)))))


Closes #91

Closes #91

--- lib/shin/cljs/cljs/core.cljs
+++ lib/shin/cljs/cljs/core.cljs
@@ -1937,7 +1937,7 @@
              (satisfies? ICounted other)
              (== (count coll) (count other)))
       (let [pairs (hamt/pairs h)
-              len   (.-length pairs)]
+            len   (alength pairs)]
           (loop [i 0]
             (if (< i len)
               (let [pair (aget pairs i)
@@ -1985,8 +1985,6 @@
   (-invoke [coll k]
     (-lookup coll k))

-  ;; TODO: IKVReduce
-
   IReduce
   (-reduce [coll f start]
     (throw "-reduce on a map: stub"))
@@ -2007,7 +2005,7 @@
   IPrintable
   (-pr-str [coll]
     (let [pairs (hamt/pairs h)
-          len (.-length pairs)]
+          len (alength pairs)]
       (loop [i 0
              r "{"]
         (if (< i len)
@@ -2023,7 +2021,7 @@
   IEncodeJS
   (-clj->js [coll]
     (let [pairs (hamt/pairs h)
-          len (.-length pairs)
+          len (alength pairs)
           r {$}]
       (loop [i 0]
         (if (< i len)
@@ -2067,7 +2065,77 @@

 ;; Set

-(deftype PersistentSet)
+(deftype PersistentHashSet [h]
+  ICollection
+  (-conj [coll entry]
+    (instance? PersistentHashSet entry)
+    (let [keys (hamt/keys (.-h entry))
+          len (alength keys)]
+      (loop [i 0
+             h h]
+        (if (< i len)
+          (let [k (aget keys i)]
+            (recur (inc i) (hamt/set k true h)))
+          (PersistentHashSet. h))))
+
+    :else
+    (let [h (hamt/set entry true h)]
+      (PersistentHashSet. h)))
+
+  IEquiv
+  (-equiv [coll other]
+    (if (and (instance? PersistentHashSet other)
+             (== (count coll) (count other)))
+      (let [keys (hamt/keys h)
+            len   (length keys)]
+        (loop [i 0]
+          (if (< i len)
+            (let [k (aget keys i)]
+              (if (== true (hamt/get k (.-h other)))
+                (recur (inc i))
+                false))
+            true)))
+      false))
+
+  ISeqable
+  (-seq [coll]
+    (let [len (hamt/count h)]
+      (if (== 0 len)
+        nil
+        (let [keys (hamt/keys h)]
+          (loop [i 0
+                 res nil]
+            (if (< i len)
+              (let [key (aget keys i)]
+                (recur (inc i) (cons k res)))
+              res))))))
+
+  ICounted
+  (-count [coll] (hamt/count h))
+
+  ILookup
+  (-lookup [coll k]
+    (and (hamt/has k h) k))
+  (-lookup [coll k not-found]
+    (if (hamt/has k h) k not-found))
+
+  IFn
+  (-invoke [coll k]
+    (-lookup coll k))
+
+  IPrintable
+  (-pr-str [coll]
+    (let [keys (hamt/keys h)
+          len (alength keys)]
+      (loop [i 0
+             r "#{"]
+        (if (< i len)
+          (let [s (if (zero? i) "" " ")
+                k    (aget keys i)]
+            (recur
+              (inc i)
+              (str r s (pr-str k))))
+          (str r "}"))))))

 ; FIXME - allow non-array colls
 (defn set
@@ -2077,15 +2145,15 @@

 (defn hash-set
   [& keys]
-  (let [len (count keys)
-        res [$]]
-    (loop [i 0]
-      (if (< i len)
-        (do
-          (.push res (nth keys i))
-          (.push res true)
-          (recur (inc i)))
-        (.apply hash-map nil res)))))
+  (let [len (count keys)]
+    (let [f (fn [h]
+              (loop [i 0]
+                (if (< i len)
+                  (do
+                    (hamt/set (nth keys i) true h)
+                    (recur (inc i))))))
+          h (hamt/mutate f (hamt-make))]
+      (PersistentHashSet. h))))

 (defn set? [coll]
   (satisfies? ISet coll))


adjusting to new core match syntax

adjusting to new core match syntax

--- src/com/narkisr/file_info.clj
+++ src/com/narkisr/file_info.clj
@@ -41,10 +41,10 @@
 (defn split-path [path] (rest (partition path #"/")))

 (defn to-hidden [path]
-  (match (split-path path)
-         ["/" dir] (str "/." dir)
-         ["/" dir "/" file] (str "/." dir "/" file)
-         _ (str (hidden (parent-path path)) "/" (fname path))))
+  (match [(split-path path)]
+         [(["/" dir] :seq)] (str "/." dir)
+         [(["/" dir "/" file] :seq)] (str "/." dir "/" file)
+         :else (str (hidden (parent-path path)) "/" (fname path))))

 (defn combine [parent child]
   (if (= parent "/")


Add UNIQUE constraint to resource_events table

We had a decent amount of discussion around the fact that the
"resource_events" table, in its current form, can't have a
meaningful primary key.  The "correct" primary key would be
(report_id + resource_type + resource_title + property), but
property is nullable because it is null for skipped resources.
We discussed the idea of splitting this table into multiple
tables, but ultimately decided that for now, a UNIQUE constraint
would be good enough.

--- src/com/puppetlabs/puppetdb/scf/migrate.clj
+++ src/com/puppetlabs/puppetdb/scf/migrate.clj
@@ -218,13 +218,11 @@
     ["new_value" "TEXT"]
     ["old_value" "TEXT"]
     ["message" "TEXT"]
-    ;; TODO: we can't set the "correct" primary key because property is nullable (because of skips).
-    ;; We probably should do something about this; only realistic options seem to be splitting
-    ;; this out into two tables (which means two SELECTS and some in-code sorting would be necessary
-    ;; in order to build up the complete data for a report), or (cough) use a sentinel value
-    ;; for "property" for skips, and make that field NOT NULL.  Both options seem pretty sucky.
-;    ["PRIMARY KEY (report_id, resource_type, resource_title, property)"]
-     )
+    ; TODO: we can't set the "correct" primary key because `property` is nullable
+    ; (because of skipped resources).
+    ; We decided to just use a UNIQUE constraint for now, but another option
+    ; would be to split this out into two tables.
+    ["CONSTRAINT constraint_resource_events_unique UNIQUE (report_id, resource_type, resource_title, property)"])

   (sql/do-commands
     "CREATE INDEX idx_reports_certname ON reports(certname)")


Fixed issue #5

Fixed issue #5

--- src/leiningen/amp/impl.clj
+++ src/leiningen/amp/impl.clj
@@ -100,7 +100,10 @@
 (defn package-amp!
   [project args]
   (let [project-home           (io/file (:root project))
-        src-amp                (io/file project-home "amp")
+        src-amp-str            (:amp-source-path project)
+        src-amp                (if (nil? src-amp-str)
+                                 (io/file project-home "amp")
+                                 (io/file src-amp-str))
         module-properties-file (io/file src-amp "module.properties")
         _                      (if (not (fexists module-properties-file))
                                  (main/abort (str "Invalid AMP project - " module-properties-file " is missing.")))


Search input on Discover can leave header in indeterminate state (#695)

--- src/status_im/components/toolbar/view.cljs
+++ src/status_im/components/toolbar/view.cljs
@@ -67,6 +67,8 @@
       {:style             st/toolbar-search-input
        :auto-focus        true
        :placeholder       search-placeholder
+       :return-key-type   "search"
+       :on-blur           #(dispatch [:set-in [:toolbar-search :show] nil])
        :on-change-text    #(dispatch [:set-in [:toolbar-search :text] %])
        :on-submit-editing #(toolbar-search-submit on-search-submit)}]
      [view
@@ -82,8 +84,7 @@
                                    on-search-submit]
                             :as   opts}]
   (let [toggle-search-fn #(dispatch [:set-in [:toolbar-search :show] %])
-        actions          (if show-search?
-                           [(act/search #(toolbar-search-submit on-search-submit))]
+        actions          (if-not show-search?
                            (into actions [(act/search #(toggle-search-fn search-key))]))]
     [toolbar {:style          (merge st/toolbar-with-search style)
               :nav-action     (if show-search?


fix problem and add test for throwing an exception when trying to get the speed of an unknown parrot type

--- Clojure/parrot-refactoring/test/parrot_refactoring/core_test.clj
+++ Clojure/parrot-refactoring/test/parrot_refactoring/core_test.clj
@@ -60,4 +60,12 @@
     (parrot/speed {:type :norwegian-blue-parrot
                    :num-coconuts 0
                    :voltage 4.0
-                   :nailed false}) => 24.0))
+                   :nailed false}) => 24.0)
+
+  (fact
+    "it can't get speed of unknown parrrot types"
+
+    (parrot/speed {:type :unknown-parrot-type
+                   :num-coconuts 0
+                   :voltage 0.0
+                   :nailed false}) => (throws Exception "Should be unreachable!")))


added additional logging around failed mutations

--- src/untangled/client/impl/om_plumbing.cljs
+++ src/untangled/client/impl/om_plumbing.cljs
@@ -31,7 +31,11 @@
            :else (om/db->tree query data @state))}))))

 (defn write-entry-point [env k params]
-  (let [rv (m/mutate env k params)
+  (let [rv (try
+             (m/mutate env k params)
+             (catch :default e
+               (log/error (str "Mutation " k " failed with exception") e)
+               nil))
         action (:action rv)]
     (if action
       (assoc rv :action (fn [env k params]


Records and protocols documentation

Records and protocols documentation

--- src/skat.clj
+++ src/skat.clj
@@ -1,18 +1,50 @@
 (ns skat)
 (set! *warn-on-reflection* true)

-;;; Cards
-
+;; Used as a Card representation in whole project.
+;;
+;; :color property should belong to #{ :kreuz, :grun, :herz, :schell }
+;; :figure property should belong to #{ :7, :8, :9, :10, :W, :D, :K, :A }
 (defrecord Card [color figure])

-;;; Bidding
-
+;; Used to store bidding order for auctions between deals.
+;;
+;; :front (ger. Vorhand) "sits" on left from the dealer,
+;; :middle (ger. Mittelhand) "sits" on right from the dealer,
+;; :rear (ger. Hinterhand) is the "dealer" hinself.
+;;
+;; (Since dealing is done by the engine no we have no actual dealer on the
+;; implementation level and the only thing that matters is order of bidding and
+;; card playing during first trick.)
+;;
+;; Bidding is done in order:
+;; * :middle player bids :front player till one of them pass,
+;; * winner of previous subbid is bid by :rear player.
+;;
+;; When deal ends bidders are rotated before next auction begns (consequence of
+;; rotating the "dealer's position"):
+;;   :front -> :rear -> :middle -> :front -> ...
 (defrecord Bidders [front middle rear])

+;; Used to store auction results (and sub results).
+;;
+;; :winner is the (sub)bid's winner (during the game he'll be called solist),
+;; :cards are winner's cards,
+;; :bid is the value of bid placed by solist.
 (defrecord Bidding [winner cards bid])

-;;; Configuration
-
+;; Used to store details about declared game.
+;;
+;; :solist is the bid winner and declarer of a current game,
+;; :suit describes currently played game:
+;;   #{ :grand, :kreuz, :grun, :herz, :schell, :null },
+;; :hand tells whether solists decided not to pick skat cards,
+;; :ouvert tells whether solists decided to show his cards to his opponents
+;;   (requires :hand),
+;; :announced-schneider? tells whether solist declares that opponenets will get
+;;    less that 30 points worth of cards,
+;; :announced-schwarz? tells that solist declare to take all cards,
+;; :declared-bid tells minimal game value solist must achieve.
 (defrecord Configuration [solist
                           suit
                           hand?
@@ -21,49 +53,71 @@
                           announced-schwarz?
                           declared-bid])

-;;; Deal
-
+;; Used to describe current state of deal.
+;;
+;; :knowledge is a map of [Player, PlayerKnowledge] pairs,
+;; :trick is a current Trick,
+;; :skat is a pair of 2 cards owned by solist but not used during the game.
 (defrecord Deal [knowledge trick skat])

-;;; Result
-
+;; Used to describe deal result.
+;;
+;; :solist is a bid winner and game declarer,
+;; :success? tells whether solist won game,
+;; :bid tells how much player bid,
+;; :game-value tells how much game was worth.
 (defrecord Result [solist success? bid game-value])

-;;; Knowledge
-
+;; Used to describe Player's knowledge about the ongoing deal.
+;;
+;; :self is a Player himself,
+;; :cards-played is map of [Player, Vector of Cards] pairs storing knowledge
+;;   about past tricks,
+;; :cards-owned is map of [Player, Vector of Cards] pairs storing knowledge
+;;   about owned cards,
+;; :cards-taken is map of [Player, Vector of Cards] pairs storing knowledge
+;;   about cards taken by each player.
 (defrecord PlayerKnowledge [self cards-played cards-owned cards-taken])

-;;; Players
+(defprotocol Player
+  "Abstract entity choosing from Player-specific options"
+  (id [this] "Returns Player's ID (name)")
+  (play-1st-card [this situation] "Play card as 1st Player")
+  (play-2nd-card [this situation c1] "Play card as 2nd Player")
+  (play-3rd-card [this situation c1 c2] "Play card as 3rd Player")
+  (place-bid [this cards last-bid] "Place bid considering prevous bid's value")
+  (respond-to-bid [this cards bid] "Respond to placed bid (accept/decline)")
+  (declare-suit [this cards final-bid] "Choose suit as a solist")
+  (declare-hand [this cards final-bid] "Choose hand (yes/no) as a solist")
+  (declare-schneider [this cards final-bid]
+    "Choose schneider (yes/no) as a solist")
+  (declare-schwarz [this cards final-bid] "Choose schwarz (yes/no) as a solist")
+  (declare-ouvert [this cards final-bid] "Choose ouvert (yes/no) as a solist")
+  (skat-swapping [this config cards-owned skat-card]
+    "Choose card for swapping with a skat card"))

-(defprotocol Player
-  (id [this])
-  (play-1st-card [this situation])
-  (play-2nd-card [this situation c1])
-  (play-3rd-card [this situation c1 c2])
-  (place-bid [this cards last-bid])
-  (respond-to-bid [this cards bid])
-  (declare-suit [this cards final-bid])
-  (declare-hand [this cards final-bid])
-  (declare-schneider [this cards final-bid])
-  (declare-schwarz [this cards final-bid])
-  (declare-ouvert [this cards final-bid])
-  (skat-swapping [this config cards-owned skat-card]))
-
-;;; Situation
-
+;; Used to descibe Player's situation in current trick.
+;;
+;; :self is a Player himself,
+;; :config is currently used game Configuration,
+;; :knowledge is current PlayerKnowledge,
+;; :order is order of cards played in this Trick,
+;; :cards-allowed are cards allowed to play in this trick according to played
+;;   game and first played card (if already played).
 (defrecord PlayerSituation [self config knowledge order cards-allowed])

-;;; Trick
-
+;; Used to describe current Trick.
+;;
+;; :order is map with keys #{ :p1, :p2, :p3 } describing orders of card played
+;;   during the trick.
 (defrecord Trick [order])

-;;; Driver
-
 (defprotocol GameDriver
-  (create-players [this])
-  (auction-result [this bidding])
-  (declare-game [this bidding])
-  (declaration-result [this config])
-  (trick-results [this results])
-  (deal-results [this results])
-  (game-results [this points]))
+  "Abstract entity choosing not-Player-specific options and receiving results"
+  (create-players [this] "Creates Players as Bidders")
+  (auction-result [this bidding] "Reports auction result")
+  (declare-game [this bidding] "Creates Configuration basing on Bidding")
+  (declaration-result [this config] "Reports game declaration's result")
+  (trick-results [this results] "Reports trick's result")
+  (deal-results [this results] "Reports deal's result")
+  (game-results [this points] "Reports whole game's result"))


Adds script for Finder + refactors

Adds script for Finder + refactors

--- src/great_things_done/application_info.cljs
+++ src/great_things_done/application_info.cljs
@@ -14,17 +14,35 @@

    return _links")

+(def ^:private osx-finder-applescript
+  "tell application \"Finder\"
+     set acc to {}
+   	 set sel to the selection
+   	 repeat with each in sel
+   	   set end of acc to URL of each
+     end repeat
+   end tell
+
+   return acc")
+
+(defn- run-applescript
+  [code callback]
+  (let [applescript (js/require "applescript")]
+    (.execString applescript
+                 code
+                 (fn [err res]
+                   (when err
+                     (throw (js/Error. (str "Error when performing" code))))
+                     (callback res)))))
+
 (defmulti retrieve-current-app-data-osx
   #(:id %1))

 (defmethod retrieve-current-app-data-osx "com.apple.mail" [info callback]
-  (let [applescript (js/require "applescript")]
-    (.execString applescript
-                 osx-mail-applescript
-                 (fn [err res]
-                   (when err
-                     (throw (js/Error. "Error when retrieving data from Mail.app")))
-                   (callback res)))))
+  (run-applescript osx-mail-applescript callback))
+
+(defmethod retrieve-current-app-data-osx "com.apple.finder" [info callback]
+  (run-applescript osx-finder-applescript callback))

 (defn- get-current-app-info-osx
   "Return info about the current frontmost application on OSX"


CMR-4555: Make sure metadata-db can publish messages to the deleted tombstones granule exchange

--- metadata-db-app/src/cmr/metadata_db/config.clj
+++ metadata-db-app/src/cmr/metadata_db/config.clj
@@ -88,4 +88,5 @@
   (assoc (rmq-conf/default-config)
          :exchanges [(deleted-concept-revision-exchange-name)
                      (ingest-exchange-name)
-                     (access-control-exchange-name)]))
+                     (access-control-exchange-name)
+                     (deleted-granule-exchange-name)]))


CMR-1297 Adds basic JSON format test

CMR-1297 Adds basic JSON format test

--- system-int-test/test/cmr/system_int_test/search/collection_search_format_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_search_format_test.clj
@@ -194,6 +194,15 @@
              c7-smap nil :iso-smap "iso_smap"
              c8-dif10 "application/dif10+xml" :dif10 nil
              c8-dif10 nil :dif10 "dif10"))
+
+      (testing "atom/json formats"
+        (let [get-response (fn [concept format]
+                             (search/get-concept-by-concept-id
+                              (:concept-id concept)
+                              {:url-extension (name format)}))
+              result (util/map-keys->kebab-case (json/decode (:body (get-response c1-echo :json)) true))]
+          (is (= (da/collection->expected-atom c1-echo)
+                 (dissoc result :orbit-parameters)))))

       (testing "native format direct retrieval"
         ;; Native format can be specified using application/xml, application/metadata+xml,


Renaming fns for clarity.

Renaming fns for clarity.

--- src/kolmogorov_music/song.clj
+++ src/kolmogorov_music/song.clj
@@ -20,8 +20,8 @@
       (+ (sin-osc (* 3.01 freq)))
       (+ (* 1/4 (sin-osc (* 2.01 freq))))
       (+ (* 1/3 (sin-osc (* 1/2 freq))))
-      (rlpf (line:kr 3000 500 dur) 1/5)
-      (clip2 0.5)
+      (rlpf (line:kr 3000 500 dur) 1/50)
+      (clip2 0.3)
       (* (env-gen (adsr 0.05 (* dur 1/3) 0.2) (line:kr 1 0 dur) :action FREE))
       (* vol master-volume)))

@@ -30,28 +30,29 @@
 (defmethod live/play-note :comes [{hertz :pitch seconds :duration}] (sing hertz seconds))
 (defmethod live/play-note :bass [{hertz :pitch seconds :duration}] (sing (* 1/2 hertz) seconds))

-(defn n [time duration pitch part]
+(defn construct [time duration pitch part]
   {:time time
    :pitch pitch
    :duration duration
    :part part})

-(defn least [m]
+(defn most-behind [m]
   (first (apply min-key second m)))

-(defn max-out [m]
+(defn synchronise [m]
   (zipmap (keys m) (repeat (apply max (vals m)))) )

-(defn encode [state [a b c d & digits]]
-  (if (zero? (* a b))
-    (encode (max-out state) digits)
-    (let [part (least state)
-          duration (/ a b)
-          pitch (+ c d)
-          time (part state)]
-      (cons (n time duration pitch part)
-            (lazy-seq (->> digits
-                           (encode (update-in state [part] (partial + duration)))))))))
+(defn encode
+  ([state [a b c d & digits]]
+   (if (zero? (* a b))
+     (encode (synchronise state) digits)
+     (let [part (most-behind state)
+           duration (/ a b)
+           pitch (+ c d)
+           time (part state)]
+       (cons (construct time duration pitch part)
+             (lazy-seq (->> digits
+                            (encode (update-in state [part] (partial + duration))))))))))

 (def track
   (->>


Stop supporting Build Tools version < 20

This caused too much headache with Android SDK's inconsistent naming of
build tools directories.

--- src/leiningen/droid/utils.clj
+++ src/leiningen/droid/utils.clj
@@ -41,28 +41,22 @@
   (ensure-paths sdk-path)
   (let [bt-root-dir (file sdk-path "build-tools")
         ;; build-tools directory contains a subdir which name we don't
-        ;; know that has all the tools. Let's grab the first directory
+        ;; know that has all the tools. Let's grab the last directory
         ;; inside build-tools/ and hope it is the one we need.
         bt-dir (or build-tools-version
                    (->> (.list bt-root-dir)
                         (filter #(.isDirectory (file bt-root-dir %)))
                         sort last)
                    (abort "Build tools not found."
-                          "Download them using the Android SDK Manager."))
-        bt-ver (Integer/parseInt (get (re-find #"(\d+)\..*" bt-dir) 1 "-1"))]
-    ;; if bt-ver is non-negative we have a definite numeric version number
-    ;; assume the latest build-tools dir is not empty
+                          "Download them using the Android SDK Manager."))]
     {:dx {:unix ["build-tools" bt-dir "dx"]
           :win ["build-tools" bt-dir "dx.bat"]}
      :adb {:unix ["platform-tools" "adb"]
            :win ["platform-tools" "adb.exe"]}
      :aapt {:unix ["build-tools" bt-dir "aapt"]
             :win ["build-tools" bt-dir "aapt.exe"]}
-     :zipalign (if (>= bt-ver 20)
-                 {:unix ["build-tools" bt-dir "zipalign"]
-                  :win ["build-tools" bt-dir "zipalign.exe"]}
-                 {:unix ["tools" "zipalign"]
-                  :win ["tools" "zipalign.exe"]})
+     :zipalign {:unix ["build-tools" bt-dir "zipalign"]
+                :win ["build-tools" bt-dir "zipalign.exe"]}
      :proguard {:unix ["tools" "proguard" "lib" "proguard.jar"]
                 :win ["tools" "proguard" "lib" "proguard.jar"]}}))


Add :scope "test" to test plugin

Add :scope "test" to test plugin

--- src/leiningen/new/tenzing.clj
+++ src/leiningen/new/tenzing.clj
@@ -81,7 +81,7 @@

 (defn dependencies [opts]
   (cond-> []
-          (test?    opts) (conj "crisptrutski/boot-cljs-test \"0.1.0-SNAPSHOT\"")
+          (test?    opts) (conj "crisptrutski/boot-cljs-test \"0.1.0-SNAPSHOT\" :scope \"test\"")
           (om?      opts) (conj "org.omcljs/om \"0.8.6\"")
           (reagent? opts) (conj "reagent \"0.5.0\"")
           (garden?  opts) (conj "org.martinklepsch/boot-garden \"1.2.5-3\" :scope \"test\"")


CMR-2481: Updated migration to handle tombstones correctly

--- metadata-db-app/src/migrations/033_replace_tags_namespace_and_value_with_tag_key.clj
+++ metadata-db-app/src/migrations/033_replace_tags_namespace_and_value_with_tag_key.clj
@@ -18,7 +18,7 @@
   (println "migrations.033-replace-tags-namespace-and-value-with-tag-key up...")
   (doseq [result (h/query "SELECT * from cmr_tags")]
     (print-message result)
-    (let [{:keys [id metadata]} result
+    (let [{:keys [id metadata deleted native_id]} result
           metadata (-> metadata
                        (util/gzip-blob->string)
                        (edn/read-string))
@@ -26,13 +26,22 @@
           {:keys [namespace value tag-key]} metadata
           tag-key (or tag-key
                       (str/lower-case (str namespace "." value)))
+          ;; Tombstones don't have metadata so the best we can do is replace the char 29 with a
+          ;; dot.
+          native-id (if deleted
+                      (str/replace native_id (str (char 29)) ".")
+                      tag-key)
+          metadata (if deleted
+                     metadata
+                     (-> metadata
+                      (assoc :tag-key tag-key)
+                      (dissoc :namespace :value :category)))
           metadata (-> metadata
-                       (assoc :tag-key tag-key)
-                       (dissoc :namespace :value :category)
                        pr-str
                        util/string->gzip-bytes)
-          result (assoc result :metadata metadata :native_id tag-key)]
+          result (assoc result :metadata metadata :native_id native-id)]
       (j/update! (config/db) "cmr_tags" result ["id = ?" id]))))
+

 (defn down
   "Migrates the database down from version 33."
@@ -41,20 +50,23 @@
   (println "NOTE: category field and original native-id cannot be recovered")
   (doseq [result (h/query "SELECT * from cmr_tags")]
     (print-message result)
-    (let [{:keys [id metadata]} result
-          metadata (-> metadata
-                       (util/gzip-blob->string)
-                       (edn/read-string))
-          tag-key (:tag-key metadata)
-          ;; There is no way to properly recover a namespace and value that have a
-          ;; "." in the value.
-          [_ namespace value] (re-matches #"(.*)\.(.*$)" tag-key)
-          native-id (str namespace (char 29) value)
-          metadata (-> metadata
-                       (assoc :namespace namespace
-                              :value value)
-                       (dissoc :tag-key)
-                       pr-str
-                       util/string->gzip-bytes)
-          result (assoc result :metadata metadata :native_id native-id)]
+    (let [{:keys [id metadata deleted native_id]} result
+          result (if deleted
+                   ;; Just replace the . at the end of the native id with a group separator.
+                  (let [native-id (str/replace native_id #"\.(.*?$)" (str (char 29) "$1"))]
+                    (assoc result :native_id native-id))
+                  ;; There is no way to properly recover a namespace and value that have a
+                  ;; "." in the value.
+                  (let [metadata (-> metadata
+                                     util/gzip-blob->string
+                                     edn/read-string)
+                        tag-key (:tag-key metadata)
+                        [_ namespace value] (re-matches #"(.*)\.(.*$)" tag-key)
+                        native-id (str namespace (char 29) value)
+                        metadata (-> metadata
+                                     (assoc :namespace namespace :value value)
+                                     (dissoc :tag-key)
+                                     pr-str
+                                     util/string->gzip-bytes)]
+                     (assoc result :metadata metadata :native_id native-id)))]
       (j/update! (config/db) "cmr_tags" result ["id = ?" id]))))


we will expect a parameter :type of "date/*" for the various date widgets.

--- src/metabase/query_processor/parameters.clj
+++ src/metabase/query_processor/parameters.clj
@@ -20,7 +20,7 @@

 (defn- build-filter-clause [{param-type :type, param-value :value, [_ field] :target}]
-  (if-not (= param-type "date")
+  (if-not (s/starts-with? param-type "date")
     ;; default behavior is to use a simple equals filter
     ["=" field param-value]
     ;; otherwise we need to handle date filtering


edited effects.clj

edited effects.clj

--- src/maqueta/hello/effects.clj
+++ src/maqueta/hello/effects.clj
@@ -11,10 +11,10 @@
   (let [fire (ParticleEmitter. "Emitter"
                                com.jme3.effect.ParticleMesh$Type/Triangle
                                30)
-        mat-red (load-material "Common/MatDefs/Misc/Particle.j3md")
         debris (ParticleEmitter. "Debris"
                                  com.jme3.effect.ParticleMesh$Type/Triangle
                                  10)
+        mat-red (load-material "Common/MatDefs/Misc/Particle.j3md")
         debris-mat (load-material "Common/MatDefs/Misc/Particle.j3md")]
     (.setTexture mat-red "Texture"
                  (load-texture "Effects/Explosion/flame.png"))
@@ -31,12 +31,9 @@
       (.setGravity 0 0 0)
       (.setLowLife 1)
       (.setHighLife 3))
-    (-> fire
-        .getParticleInfluencer
-        (.setInitialVelocity (Vector3f. 0 2 0)))
-    (-> fire
-        .getParticleInfluencer
-        (.setVelocityVariation 0.3))
+    (doto (.getParticleInfluencer fire)
+      (.setInitialVelocity (Vector3f. 0 2 0))
+      (.setVelocityVariation 0.3))
     (doto debris
       (.setMaterial debris-mat)
       (.setImagesX 3)
@@ -45,12 +42,9 @@
       (.setSelectRandomImage true)
       (.setStartColor ColorRGBA/White)
       (.setGravity 0 6 0))
-    (-> debris
-        .getParticleInfluencer
-        (.setInitialVelocity (Vector3f. 0 4 0)))
-    (-> debris
-        .getParticleInfluencer
-        (.setVelocityVariation 0.6))
+    (doto (.getParticleInfluencer debris)
+      (.setInitialVelocity (Vector3f. 0 4 0))
+      (.setVelocityVariation 0.6))
     (doto (.getRootNode app)
       (.attachChild fire)
       (.attachChild debris))


Update endpoint to align with change in orchestration endpoint.

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/data_tab.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/data_tab.cljs
@@ -71,7 +71,7 @@
                                     (:entity-map props) (first (keys (:entity-map props))))]
          [:a {:style {:textDecoration "none" :marginLeft "1ex"}
               :href (str "/service/api/workspaces/" (:namespace (:workspace-id props)) "/"
-                      (:name (:workspace-id props)) "/" selected-entity-type "/export")
+                      (:name (:workspace-id props)) "/" selected-entity-type "/tsv")
               :target "_blank"}
           "Download '" selected-entity-type "' data"])]
       (let [attribute-keys (apply union (map (fn [e] (set (keys (e "attributes")))) (:entities @state)))]


CMR-348: Removed debugging try/catch

CMR-348: Removed debugging try/catch

--- src/cmr/indexer/services/concepts/orbit_calculated_spatial_domain.clj
+++ src/cmr/indexer/services/concepts/orbit_calculated_spatial_domain.clj
@@ -6,7 +6,6 @@
 (defn ocsd->elastic-doc
   "Converts a OCSD into the portion going in an elastic document"
   [ocsd]
-  (try
   (let [{:keys [orbital-model-name
                 orbit-number
                 start-orbit-number
@@ -17,10 +16,7 @@
      :start-orbit-number start-orbit-number
      :stop-orbit-number stop-orbit-number
      :equator-crossing-longitude equator-crossing-date-time
-     :equator-crossing-date-time equator-crossing-date-time})
-  (catch Throwable e
-    (println e)
-    (.printStackTrace e))))
+     :equator-crossing-date-time equator-crossing-date-time}))

 (defn ocsds->elastic-docs
   "Converts the ocsds into a list of elastic documents"


Fix test for sequential writing.

Fix test for sequential writing.

--- test/cheshire/test/core.clj
+++ test/cheshire/test/core.clj
@@ -164,13 +164,12 @@
             (json/write [] :end)
             (json/write 4)
             (json/write [] :end)))))
-  (is (= "{\"a\":1,\"b\":2:{\"c\":3},\"d\":4}"
+  (is (= "{\"a\":1,\"b\":2,\"c\":3}"
          (.toString
           (json/with-writer [(StringWriter.) nil]
             (json/write {:a 1} :start)
             (json/write {:b 2} :bare)
-            (json/write {:c 3} :all)
-            (json/write {:d 4} :end)))))
+            (json/write {:c 3} :end)))))
   (is (= (str "[\"start\",\"continue\",[\"implicitly-nested\"],"
               "[\"explicitly-nested\"],\"flatten\",\"end\"]")
          (.toString


Fix test for POST /documents route

Fix test for POST /documents route

--- test/datemo/routes_test.clj
+++ test/datemo/routes_test.clj
@@ -68,7 +68,7 @@
                  (-> (parse response)))))))

   (testing "POST /documents"
-    (let [data (->> (md-to-html-string "# Title  \nParagraph")
+    (let [data (->> (apply str "# Title  \nParagraph")
                    (array-map :doc-string))
           response (app (prep-request :post "/documents" data))]
       (is (= 201 (:status response)))


Add tests for event timestamp queries via HTTP

--- test/com/puppetlabs/puppetdb/test/http/experimental/event.clj
+++ test/com/puppetlabs/puppetdb/test/http/experimental/event.clj
@@ -9,7 +9,7 @@
         com.puppetlabs.puppetdb.examples.report
         com.puppetlabs.puppetdb.fixtures
         [clj-time.core :only [now]]
-        [clj-time.coerce :only [to-string]]
+        [clj-time.coerce :only [to-string to-long]]
         [com.puppetlabs.puppetdb.testutils :only (response-equal?)]))

 (def content-type-json "application/json")
@@ -28,6 +28,11 @@
 (defn get-response
   [query] (*app* (get-request "/experimental/events" query)))

+(defn munge-event-values
+  "Munge the event values that we get back from the web to a format suitable
+  for comparison with test data"
+  [events]
+  (map #(utils/maptrans {[:old-value :new-value] stringify-keys} %) events))

 (defn expected-resource-event-response
   [resource-event report-hash]
@@ -56,6 +61,27 @@
       (let [response (get-response ["=" "report" report-hash])
             expected (expected-resource-events-response
                         (:resource-events basic)
-                        report-hash)
-            munge-event-values #(utils/maptrans {[:old-value :new-value] stringify-keys} %)]
-        (response-equal? response expected #(map munge-event-values %))))))
+                        report-hash)]
+        (response-equal? response expected munge-event-values)))
+
+    ;; NOTE: more exhaustive testing for these queries can be found in
+    ;; `com.puppetlabs.puppetdb.test.query.event`
+    (testing "should support querying resource events by timestamp"
+      (let [start-time  "2011-01-01T12:00:01-03:00"
+            end-time    "2011-01-01T12:00:03-03:00"]
+        (testing "should support single term timestamp queries"
+          (let [response (get-response ["<" "timestamp" end-time])
+                expected (expected-resource-events-response
+                            (filter #(< (to-long (:timestamp %)) (to-long end-time))
+                              (:resource-events basic))
+                            report-hash)]
+            (response-equal? response expected munge-event-values)))
+        (testing "should support compound timestamp queries"
+          (let [response (get-response ["and" [">" "timestamp" start-time]
+                                              ["<" "timestamp" end-time]])
+                expected (expected-resource-events-response
+                            (filter #(and (< (to-long (:timestamp %)) (to-long end-time))
+                                          (> (to-long (:timestamp %)) (to-long start-time)))
+                              (:resource-events basic))
+                            report-hash)]
+            (response-equal? response expected munge-event-values)))))))


(MAINT) Remove unnecessary require

(MAINT) Remove unnecessary require

--- test/unit/puppetlabs/puppetserver/certificate_authority_test.clj
+++ test/unit/puppetlabs/puppetserver/certificate_authority_test.clj
@@ -13,8 +13,7 @@
             [clojure.string :as string]
             [clj-time.core :as time]
             [clj-time.coerce :as time-coerce]
-            [me.raynes.fs :as fs]
-            [puppetlabs.puppetserver.certificate-authority :as ca]))
+            [me.raynes.fs :as fs]))

 (use-fixtures :once schema-test/validate-schemas)

@@ -447,7 +446,7 @@
       (logutils/with-test-logging
         (initialize! settings)
         (is (logged? #"/ca/ca_key.pem' was found to have the wrong permissions set as 'rw-r--r--'. This has been corrected to 'rw-r-----'."))
-        (is (= ca/private-key-perms (ca/get-file-perms (:cakey settings)))))))
+        (is (= private-key-perms (get-file-perms (:cakey settings)))))))

   (testing (str "The CA private key's permissions are not reset if "
                 ":manage-internal-file-permissions is false.")
@@ -456,7 +455,7 @@
                      :manage-internal-file-permissions false)]
       (set-file-perms (:cakey settings) perms)
       (initialize! settings)
-      (is (= perms (ca/get-file-perms (:cakey settings)))))))
+      (is (= perms (get-file-perms (:cakey settings)))))))

 (deftest retrieve-ca-cert!-test
   (testing "CA file copied when it doesn't already exist"


CMR-2904: Fixing rename that wasn't applied everywhere.

--- system-int-test/test/cmr/system_int_test/ingest/provider_ingest_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/provider_ingest_test.clj
@@ -128,8 +128,8 @@
       ;; ensure PROV1 group is indexed
       (is (= [(:concept-id access-group)]
              (map :concept-id (:items (u/map-keys->kebab-case
-                                       (access-control/search (transmit-config/echo-system-token)
-                                                              {:provider "PROV1"}))))))
+                                       (access-control/search-for-groups (transmit-config/echo-system-token)
+                                                                         {:provider "PROV1"}))))))

       ;; delete provider PROV1
       (let [{:keys [status content-length]} (ingest/delete-ingest-provider "PROV1")]
@@ -149,8 +149,8 @@

       ;; PROV1 access group is unindexed
       (is (= 0 (:hits
-                (access-control/search (transmit-config/echo-system-token)
-                                       {:provider "PROV1"}))))
+                (access-control/search-for-groups (transmit-config/echo-system-token)
+                                                  {:provider "PROV1"}))))

       ;; PROV2 concepts are in metadata-db
       (are [concept]


CMR-4239 - Updated variable delete tests.

--- system-int-test/test/cmr/system_int_test/ingest/variable_ingest_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/variable_ingest_test.clj
@@ -215,45 +215,30 @@
     (index/wait-until-indexed)
     (is (= 201 status))))

-; (deftest delete-variable-ingest-test
-;   (testing "Variable ingest:"
-;     (let [acl-data (variable-util/setup-update-acl (s/context) "PROV1")
-;           {:keys [user-name group-name group-id token grant-id]} acl-data
-;           variable-data (variable-util/make-variable)
-;           new-long-name "A new long name"
-;           _ (variable-util/create-variable token variable-data)
-;           response (variable-util/delete-variable
-;                     token
-;                     (string/lower-case (:Name variable-data)))
-;           {:keys [status concept-id revision-id]} response
-;           fetched (mdb/get-concept concept-id revision-id)]
-;       (testing "delete a variable"
-;         (is (= 200 status))
-;         (is (= 2 revision-id))
-;         (is (:deleted fetched))
-;         (is (= (string/lower-case (:Name variable-data))
-;                (:native-id fetched)))
-;         (variable-util/assert-variable-deleted variable-data
-;                                                user-name
-;                                                concept-id
-;                                                revision-id))
-;       (testing "attempt to update a deleted variable"
-;         (let [response (variable-util/update-variable
-;                         token
-;                         (string/lower-case (:Name variable-data))
-;                         (assoc variable-data :LongName new-long-name))
-;               {:keys [status errors]} response]
-;           (is (= 404 status))
-;           (is (= (format "Variable with variable-name '%s' was deleted."
-;                          (string/lower-case (:Name variable-data)))
-;                  (first errors)))))
-;       (testing "create a variable over a variable's tombstone"
-;         (let [response (variable-util/create-variable
-;                         token
-;                         variable-data)
-;               {:keys [status concept-id revision-id]} response]
-;           (is (= 200 status))
-;           (is (= 3 revision-id)))))))
+(deftest delete-variable-ingest-test
+  (testing "Variable ingest:"
+    (let [acl-data (variable-util/setup-update-acl (s/context) "PROV1")
+          {:keys [user-name group-name group-id token grant-id]} acl-data
+          concept (make-variable-concept)
+          _ (ingest-variable concept {:token token})
+          _ (index/wait-until-indexed)
+          response (ingest/delete-concept concept
+                    {:token token})
+          {:keys [status concept-id revision-id errors]} response
+          _ (println "errors:" errors)
+          fetched (mdb/get-concept concept-id revision-id)]
+      (testing "delete a variable"
+        (is (= 200 status))
+        (is (= 2 revision-id))
+        (is (:deleted fetched))
+        (is (= (:native-id concept)
+               (:native-id fetched)))
+        (is (:deleted fetched)))
+      (testing "create a variable over a variable's tombstone"
+        (let [response (ingest-variable (make-variable-concept) {:token token})
+              {:keys [status concept-id revision-id]} response]
+          (is (= 200 status))
+          (is (= 3 revision-id)))))))

 ; (deftest variable-ingest-permissions-test
 ;   (testing "Variable ingest permissions:"


Creates an overload to the link-to helper that takes http parameters

--- lib/compojure/html/html_helpers.clj
+++ lib/compojure/html/html_helpers.clj
@@ -1,8 +1,7 @@
 ;; Helper functions for generating common HTML elements
 (in-ns 'compojure.html)
-
-(use '(compojure control str-utils)
-     '(clojure.contrib seq-utils))
+(use '(compojure control str-utils))
+(use '(clojure.contrib seq-utils str-utils))

 (def #^{:private true}
   *static* (ref ""))
@@ -25,8 +24,11 @@
     \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"})

 (defn link-to
-  [url title]
-  [:a {:href url} title])
+  ([url title]
+     [:a {:href url} title])
+  ([url title param-map]
+     (link-to (str* url "?"
+		     (str-join "&" (map (fn [pair] (str* (first pair) "=" (second pair))) param-map))) title)))

 (defmacro form-to
   [[method action] & body]