diff --git a/client/src/components/Form/Elements/FormData/FormData.test.js b/client/src/components/Form/Elements/FormData/FormData.test.js index 42910c30a0e..9b97ed3296a 100644 --- a/client/src/components/Form/Elements/FormData/FormData.test.js +++ b/client/src/components/Form/Elements/FormData/FormData.test.js @@ -36,7 +36,7 @@ const defaultOptions = { { id: "hda1", hid: 1, name: "hdaName1", src: "hda", tags: ["tag1"] }, { id: "hda2", hid: 2, name: "hdaName2", src: "hda", tags: ["tag1", "tag2"] }, { id: "hda3", hid: 3, name: "hdaName3", src: "hda", tags: ["tag2", "tag3"] }, - { id: "hda3", hid: 4, name: "hdaName4", src: "hda" }, + { id: "hda4", hid: 4, name: "hdaName4", src: "hda" }, ], hdca: [ { id: "hdca5", hid: 5, name: "hdcaName5", src: "hdca" }, @@ -61,7 +61,7 @@ describe("FormData", () => { const value_1 = { batch: false, product: false, - values: [{ id: "hda3", src: "hda", map_over_type: null }], + values: [{ id: "hda4", src: "hda", map_over_type: null }], }; const options = wrapper.find(".btn-group").findAll("button"); expect(options.length).toBe(4); @@ -122,7 +122,7 @@ describe("FormData", () => { expect(wrapper.emitted().input.length).toEqual(1); const selectedValues = wrapper.findAll(SELECTED_VALUE); expect(selectedValues.length).toBe(2); - expect(selectedValues.at(0).text()).toBe("4: hdaName4"); + expect(selectedValues.at(0).text()).toBe("3: hdaName3"); expect(selectedValues.at(1).text()).toBe("2: hdaName2"); const value_0 = { batch: false, @@ -153,6 +153,39 @@ describe("FormData", () => { expect(wrapper.emitted().input[2][0]).toEqual(null); }); + it("properly sorts multiple datasets", async () => { + const wrapper = createTarget({ + value: { + // the order of values does not matter here + values: [ + { id: "hda2", src: "hda" }, + { id: "hda3", src: "hda" }, + { id: "hda1", src: "hda" }, + ], + }, + multiple: true, + optional: true, + options: defaultOptions, + }); + const selectedValues = wrapper.findAll(SELECTED_VALUE); + expect(selectedValues.length).toBe(3); + // the values in the multiselect are sorted by hid DESC + expect(selectedValues.at(0).text()).toBe("3: hdaName3"); + expect(selectedValues.at(1).text()).toBe("2: hdaName2"); + expect(selectedValues.at(2).text()).toBe("1: hdaName1"); + await selectedValues.at(0).trigger("click"); + const value_sorted = { + batch: false, + product: false, + values: [ + // the values in the emitted input are sorted by hid ASC + { id: "hda1", map_over_type: null, src: "hda" }, + { id: "hda2", map_over_type: null, src: "hda" }, + ], + }; + expect(wrapper.emitted().input[1][0]).toEqual(value_sorted); + }); + it("dataset collection as hda", async () => { const wrapper = createTarget({ value: { values: [{ id: "dce1", src: "dce" }] }, diff --git a/client/src/components/Form/Elements/FormData/FormData.vue b/client/src/components/Form/Elements/FormData/FormData.vue index 28bddeb966d..8a9f97e4a9b 100644 --- a/client/src/components/Form/Elements/FormData/FormData.vue +++ b/client/src/components/Form/Elements/FormData/FormData.vue @@ -111,6 +111,17 @@ const currentValue = computed({ return undefined; }, set: (val) => { + if (val && Array.isArray(val) && val.length > 0) { + val.sort((a, b) => { + const aHid = a.hid; + const bHid = b.hid; + if (aHid && bHid) { + return aHid - bHid; + } else { + return 0; + } + }); + } $emit("input", createValue(val)); }, }); diff --git a/doc/source/releases/23.0_announce.rst b/doc/source/releases/23.0_announce.rst index 966e50be8a9..4d89c551809 100644 --- a/doc/source/releases/23.0_announce.rst +++ b/doc/source/releases/23.0_announce.rst @@ -1,6 +1,6 @@ =========================================================== - 2023 Galaxy Release (v 23.0) +23.0 Galaxy Release (April 2023) =========================================================== .. include:: _header.rst diff --git a/doc/source/releases/23.0_announce_user.rst b/doc/source/releases/23.0_announce_user.rst index 9ba0ac5463d..4d83e25f6d0 100644 --- a/doc/source/releases/23.0_announce_user.rst +++ b/doc/source/releases/23.0_announce_user.rst @@ -1,6 +1,6 @@ =========================================================== - 2023 Galaxy Release (v 23.0) +23.0 Galaxy Release (April 2023) =========================================================== .. include:: _header.rst diff --git a/doc/source/releases/23.1_announce.rst b/doc/source/releases/23.1_announce.rst index a3a2f0b4c2a..cd5be76d95e 100644 --- a/doc/source/releases/23.1_announce.rst +++ b/doc/source/releases/23.1_announce.rst @@ -1,6 +1,6 @@ =========================================================== -Mid 2023 Galaxy Release (v 23.1) +23.1 Galaxy Release (June 2023) =========================================================== .. include:: _header.rst diff --git a/doc/source/releases/23.1_announce_user.rst b/doc/source/releases/23.1_announce_user.rst index 277aaeb395a..6396f2f591e 100644 --- a/doc/source/releases/23.1_announce_user.rst +++ b/doc/source/releases/23.1_announce_user.rst @@ -1,6 +1,6 @@ =========================================================== -June 2023 Galaxy Release (v 23.1) +23.1 Galaxy Release (June 2023) =========================================================== .. include:: _header.rst diff --git a/doc/source/releases/23.2.rst b/doc/source/releases/23.2.rst index 6d40457cd68..1efff92ae75 100644 --- a/doc/source/releases/23.2.rst +++ b/doc/source/releases/23.2.rst @@ -160,6 +160,12 @@ Enhancements `Pull Request 17178`_ .. enhancement +* Make release titles consistent + (thanks to `@martenson `__). + `Pull Request 17341`_ +* Use python-isal for fast zip deflate compression in rocrate export + (thanks to `@mvdbeek `__). + `Pull Request 17342`_ * Improve embed performance (thanks to `@ElectronicBlueberry `__). `Pull Request 17326`_ @@ -378,6 +384,9 @@ Enhancements `Pull Request 17182`_ .. small_enhancement +* Ensure release notes include all PRs added during the freeze by re-running the release note bootstrapping + (thanks to `@jdavcs `__). + `Pull Request 17344`_ * Tool Shed client build separation (thanks to `@dannon `__). `Pull Request 15000`_ @@ -687,6 +696,12 @@ Fixes `Pull Request 17055`_ .. bug +* Write to a temp filename in posix file source plugin + (thanks to `@natefoo `__). + `Pull Request 17350`_ +* Always store multi select data input values in fixed order + (thanks to `@guerler `__). + `Pull Request 17352`_ * Remove duplicates when copying sections for tool panel view (thanks to `@bernt-matthias `__). `Pull Request 17117`_ diff --git a/doc/source/releases/23.2_announce.rst b/doc/source/releases/23.2_announce.rst index bc9efe260b2..1929a549492 100644 --- a/doc/source/releases/23.2_announce.rst +++ b/doc/source/releases/23.2_announce.rst @@ -1,6 +1,6 @@ =========================================================== -Late 2023 Galaxy Release (v 23.2) +23.2 Galaxy Release (January 2024) =========================================================== .. include:: _header.rst @@ -12,7 +12,7 @@ Highlights **InvenioRDM** has been integrated into Galaxy. Users can now import files directly from InvenioRDM repositories into Galaxy, and publish records containing artifacts (Histories, datasets, etc.) from Galaxy to InvenioRDM. -**Miscellaneous improvements.** There have been numerous updates to the UI, including Galaxy Help forum integration, improved navigation and styling, helpful warnings, improvements to search, etc. Check out the `23.2 user release notes <23.2_announce_user.html>`__ for all the details. +**Miscellaneous improvements.** There have been numerous updates to the UI, including Galaxy Help forum integration, improved navigation and styling, helpful warnings, improvements to search, etc. Check out the `23.2 user release notes <23.2_announce_user.html>`__ for all the details. Are you an admin? See the Administration Notes below, and check out `some admin relevant PRs `__. diff --git a/doc/source/releases/23.2_announce_user.rst b/doc/source/releases/23.2_announce_user.rst index 25fb6d1738b..5d4955bfc9e 100644 --- a/doc/source/releases/23.2_announce_user.rst +++ b/doc/source/releases/23.2_announce_user.rst @@ -1,6 +1,6 @@ =========================================================== -Late 2023 Galaxy Release (v 23.2) +23.2 Galaxy Release (January 2024) =========================================================== .. include:: _header.rst diff --git a/doc/source/releases/23.2_prs.rst b/doc/source/releases/23.2_prs.rst index ae544f45c27..9cd4c15c4c0 100644 --- a/doc/source/releases/23.2_prs.rst +++ b/doc/source/releases/23.2_prs.rst @@ -1,5 +1,11 @@ .. github_links +.. _Pull Request 17341: https://github.com/galaxyproject/galaxy/pull/17341 +.. _Pull Request 17342: https://github.com/galaxyproject/galaxy/pull/17342 +.. _Pull Request 17343: https://github.com/galaxyproject/galaxy/pull/17343 +.. _Pull Request 17344: https://github.com/galaxyproject/galaxy/pull/17344 +.. _Pull Request 17350: https://github.com/galaxyproject/galaxy/pull/17350 +.. _Pull Request 17352: https://github.com/galaxyproject/galaxy/pull/17352 .. _Pull Request 15238: https://github.com/galaxyproject/galaxy/pull/15238 .. _Pull Request 16883: https://github.com/galaxyproject/galaxy/pull/16883 .. _Pull Request 17117: https://github.com/galaxyproject/galaxy/pull/17117 diff --git a/doc/source/releases/24.0_announce.rst b/doc/source/releases/24.0_announce.rst index 582d1245f91..d6ef5449d03 100644 --- a/doc/source/releases/24.0_announce.rst +++ b/doc/source/releases/24.0_announce.rst @@ -2,7 +2,7 @@ :orphan: =========================================================== -February 2024 Galaxy Release (v 24.0) +24.0 Galaxy Release (Early 2024) =========================================================== diff --git a/lib/galaxy/files/sources/posix.py b/lib/galaxy/files/sources/posix.py index cb117e6bc53..a844cf68b55 100644 --- a/lib/galaxy/files/sources/posix.py +++ b/lib/galaxy/files/sources/posix.py @@ -105,14 +105,18 @@ class PosixFilesSource(BaseFilesSource): target_native_path = os.path.normpath(target_native_path) assert target_native_path.startswith(os.path.normpath(effective_root)) - target_native_path_parent = os.path.dirname(target_native_path) + target_native_path_parent, target_native_path_name = os.path.split(target_native_path) if not os.path.exists(target_native_path_parent): if self.allow_subdir_creation: os.makedirs(target_native_path_parent) else: raise Exception("Parent directory does not exist.") - shutil.copyfile(native_path, target_native_path) + # Use a temporary name while writing so anything that consumes written files can detect when they've completed, + # and identify interrupted writes + target_native_path_part = os.path.join(target_native_path_parent, f"_{target_native_path_name}.part") + shutil.copyfile(native_path, target_native_path_part) + os.rename(target_native_path_part, target_native_path) def _to_native_path(self, source_path: str, user_context=None): source_path = os.path.normpath(source_path) diff --git a/scripts/cleanup_datasets/pgcleanup.py b/scripts/cleanup_datasets/pgcleanup.py index 0c7f01bd9be..735f2d0a47c 100755 --- a/scripts/cleanup_datasets/pgcleanup.py +++ b/scripts/cleanup_datasets/pgcleanup.py @@ -912,7 +912,8 @@ class PurgeHistorylessHDAs(PurgesHDAs, RemovesMetadataFiles, RequiresDiskUsageRe FROM dataset WHERE history_id IS NULL{force_retry_sql}{object_store_id_sql} AND history_dataset_association.update_time < (NOW() AT TIME ZONE 'utc' - interval '%(days)s days') - RETURNING id), + RETURNING history_dataset_association.id as id, + history_dataset_association.history_id as history_id), hda_events AS (INSERT INTO cleanup_event_hda_association (create_time, cleanup_event_id, hda_id) @@ -920,12 +921,15 @@ class PurgeHistorylessHDAs(PurgesHDAs, RemovesMetadataFiles, RequiresDiskUsageRe FROM purged_hda_ids), {purge_hda_dependencies_sql} SELECT purged_hda_ids.id AS purged_hda_id, + history.user_id AS recalculate_disk_usage_user_id, deleted_metadata_file_ids.id AS deleted_metadata_file_id, deleted_metadata_file_ids.uuid AS deleted_metadata_file_uuid, deleted_metadata_file_ids.object_store_id AS object_store_id, deleted_icda_ids.id AS deleted_icda_id, deleted_icda_ids.hda_id AS deleted_icda_hda_id FROM purged_hda_ids + LEFT OUTER JOIN history + ON purged_hda_ids.history_id = history.id LEFT OUTER JOIN deleted_metadata_file_ids ON deleted_metadata_file_ids.hda_id = purged_hda_ids.id LEFT OUTER JOIN deleted_icda_ids