From 9a2f2acae8760ff73edc502482993ca724201170 Mon Sep 17 00:00:00 2001 From: Miguel Aranha Baldi Horlle Date: Mon, 7 Oct 2024 16:54:13 -0300 Subject: [PATCH] Linux native packaging. - Resolves #31: RPM (Fedora) and DEB (Ubuntu) native packages - Changing license to GPLv3 - Organizing build scripts - Images for linux packages - XDG Desktop entry - Rust toolchaing configuration --- .github/workflows/build_and_publish.yml | 36 +- .gitignore | 3 +- .licensure.yml | 63 ++ .rpm/krust.spec | 49 ++ COPYING | 674 ++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 88 ++- LICENSE.md | 21 - README.md | 62 ++ build-scripts/create_windows_installer.sh | 17 + build-scripts/linux-rpm-prepare-and-build.sh | 14 + .../win-prepare-and-build.sh | 5 + build.rs | 17 +- create_windows_installer.sh | 11 - data/images/io.miguelbaldi.KRust-symbolic.png | Bin 0 -> 28919 bytes data/images/io.miguelbaldi.KRust.png | Bin 0 -> 29397 bytes data/images/krust.png | Bin 0 -> 6552 bytes data/images/krust.svg | 10 + docker-compose.kafka.yml | 4 + docker-compose.windows.yml | 6 +- docker-compose.yml | 6 +- krust.desktop | 11 + rust-toolchain.toml | 2 + setup.iss | 5 +- src/backend/kafka.rs | 4 + src/backend/mod.rs | 4 + src/backend/repository.rs | 4 + src/backend/settings.rs | 4 + src/backend/worker.rs | 4 + src/component/app.rs | 4 + src/component/cache_manager_dialog.rs | 4 + src/component/connection_list.rs | 4 + src/component/connection_page.rs | 4 + src/component/messages/lists.rs | 4 + src/component/messages/message_viewer.rs | 4 + .../messages_cache_settings_dialog.rs | 4 + src/component/messages/messages_page.rs | 4 + .../messages/messages_send_dialog.rs | 4 + src/component/messages/messages_tab.rs | 4 + src/component/messages/mod.rs | 4 + src/component/mod.rs | 4 + src/component/settings_dialog.rs | 4 + src/component/status_bar.rs | 4 + src/component/task_manager.rs | 4 + src/component/topics/create_dialog.rs | 4 + src/component/topics/mod.rs | 4 + src/component/topics/topics_page.rs | 4 + src/component/topics/topics_tab.rs | 4 + src/config.rs | 4 + src/lib.rs | 8 +- src/main.rs | 4 + src/modals/about.rs | 6 +- src/modals/mod.rs | 4 + src/modals/utils.rs | 4 + src/styles.less | 5 + 55 files changed, 1178 insertions(+), 59 deletions(-) create mode 100644 .licensure.yml create mode 100644 .rpm/krust.spec create mode 100644 COPYING delete mode 100644 LICENSE.md create mode 100644 README.md create mode 100755 build-scripts/create_windows_installer.sh create mode 100755 build-scripts/linux-rpm-prepare-and-build.sh rename win-prepare-and-build.sh => build-scripts/win-prepare-and-build.sh (92%) delete mode 100755 create_windows_installer.sh create mode 100644 data/images/io.miguelbaldi.KRust-symbolic.png create mode 100644 data/images/io.miguelbaldi.KRust.png create mode 100644 data/images/krust.png create mode 100644 data/images/krust.svg create mode 100644 krust.desktop create mode 100644 rust-toolchain.toml diff --git a/.github/workflows/build_and_publish.yml b/.github/workflows/build_and_publish.yml index 0c113be..17f4e7a 100644 --- a/.github/workflows/build_and_publish.yml +++ b/.github/workflows/build_and_publish.yml @@ -7,7 +7,7 @@ env: CARGO_TERM_COLOR: always jobs: - build: + build-linux-appimage-rpm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -18,10 +18,32 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v4 with: - name: executables-linux + name: executables-linux-appimage-rpm if-no-files-found: error path: | target/appimage/*.AppImage + target/generate-rpm/*.rpm + build-linux-deb: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - name: Fix tag reference (workaround for https://github.com/actions/checkout/issues/290) + run: git fetch --update-head-ok -f origin ${{ github.ref }}:${{ github.ref }} + - name: Install system dependencies + run: | + sudo apt-get install -y pkg-config libgtk-4-dev libadwaita-1-dev libsasl2-dev libgtksourceview-5-dev openssl + cargo install cargo-deb + - name: Build + run: | + cargo deb --deb-version $(git describe) + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: executables-linux-deb + if-no-files-found: error + path: | + target/debian/*.deb + build-windows: runs-on: ubuntu-latest steps: @@ -31,7 +53,7 @@ jobs: - name: Build (Windows) run: docker compose -f docker-compose.windows.yml up - name: Make Windows Installer - run: ./create_windows_installer.sh + run: ./build-scripts/create_windows_installer.sh - name: Zip Portable Windows Artifact run: zip -r windows-portable.zip package - name: Upload Artifact @@ -39,13 +61,13 @@ jobs: with: name: executables-windows path: | - *.zip + windows-portable.zip *.exe publish: permissions: contents: write - needs: [build, build-windows] + needs: [build-linux-appimage-rpm, build-linux-deb, build-windows] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') steps: @@ -58,11 +80,13 @@ jobs: if: startsWith(github.ref, 'refs/tags/') with: prerelease: false - draft: true + draft: true generate_release_notes: true append_body: true files: | **/*.AppImage **/*.zip **/*.exe + **/*.deb + **/*.rpm - run: ls -R . diff --git a/.gitignore b/.gitignore index b595094..ef39867 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ krust-setup.exe libs/ package.zip *.log -LICENSE-win.md +LICENSE +*.bak diff --git a/.licensure.yml b/.licensure.yml new file mode 100644 index 0000000..afc989f --- /dev/null +++ b/.licensure.yml @@ -0,0 +1,63 @@ +# Regexes which if matched by a file path will always be excluded from +# getting a license header +excludes: + - \.gitignore + - .*lock + - \.github/.* + - \.vscode/.* + - \.cargo/.* + - \.git/.* + - \.rpm/.* + - \.licensure\.yml + - \.editorconfig + - README.* + - LICENSE.* + - COPYING + - gtksourceview-5 + - package + - target + - libs + - docker-*.yml + - data + - setup.iss + - .*\.(md|rst|txt|iss|desktop|svg|toml) +change_in_place: true + +licenses: + - files: any + ident: GPL-3.0 + unwrap_text: false + authors: + - name: Miguel A. Baldi Hörlle + email: miguel.horlle@gmail.com + template: | + Copyright (c) [year], [name of author]. All rights reserved. Use of + this source code is governed by the [ident] license that can be + found in the COPYING file. + +# Define type of comment characters to apply based on file extensions. +comments: + # The extensions (or singular extension) field defines which file + # extensions to apply the commenter to. + - extensions: + - rs + commenter: + type: line + comment_char: "//" + trailing_lines: 1 + - extensions: + - css + - cpp + - c + - less + commenter: + type: block + start_block_char: "/*\n" + end_block_char: "*/" + per_line_char: "*" + trailing_lines: 1 + - extension: any + commenter: + type: line + comment_char: "#" + trailing_lines: 1 diff --git a/.rpm/krust.spec b/.rpm/krust.spec new file mode 100644 index 0000000..c486e03 --- /dev/null +++ b/.rpm/krust.spec @@ -0,0 +1,49 @@ +%define __spec_install_post %{nil} +%define __os_install_post %{_dbpath}/brp-compress +%define debug_package %{nil} + +Name: krust +Summary: Kafka desktop client +Version: @@VERSION@@ +Release: @@RELEASE@@%{?dist} +License: GPL-3.0-or-later +Group: Development/Tools +Source0: %{name}-%{version}.tar.gz + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +Requires: gtksourceview5 +Requires: libadwaita +Requires: cyrus-sasl-devel +Requires: openssl-devel + +%description +%{summary} + +%prep +%setup -q + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot} +cp -a * %{buildroot} +mkdir -p %{buildroot}/usr/share/applications +mkdir -p %{buildroot}/usr/share/pixmaps +cp -a ../../../../../data/images/io.miguelbaldi.KRust* %{buildroot}/usr/share/pixmaps/ +cp -a ../../../../../data/images/krust.png %{buildroot}/usr/share/pixmaps/ +cp -a ../../../../../data/images/krust.svg %{buildroot}/usr/share/pixmaps/ +cp -a ../../../../../*.desktop %{buildroot}/usr/share/applications/ + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root,-) +%{_bindir}/* +%{_datadir}/applications/%{name}.desktop +%{_datadir}/pixmaps/%{name}.svg +%{_datadir}/pixmaps/%{name}.png +%{_datadir}/pixmaps/io.miguelbaldi.KRust.png +%{_datadir}/pixmaps/io.miguelbaldi.KRust.svg +%{_datadir}/pixmaps/io.miguelbaldi.KRust-symbolic.svg +%{_datadir}/pixmaps/io.miguelbaldi.KRust-symbolic.png diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Cargo.lock b/Cargo.lock index 0afa03c..f7245e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -923,7 +923,7 @@ dependencies = [ [[package]] name = "krust" -version = "0.0.1" +version = "0.0.0" dependencies = [ "anyhow", "chrono", diff --git a/Cargo.toml b/Cargo.toml index abcdaa8..99f4b8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,15 @@ [package] name = "krust" -rust-version = "1.77" -version = "0.0.1" +rust-version = "1.78" +publish = false +version = "0.0.0" edition = "2021" resolver = "2" authors = ["Miguel A. Baldi Hörlle "] description = "Kafka desktop client" repository = "https://github.com/miguelbaldi/krust" -license-file = "LICENSE.md" +license-file = "COPYING" +license = "GPL-3.0-or-later" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -63,3 +65,83 @@ auto_link_exclude_list = [ "libstdc++.so*", "libm.so*", ] + +[package.metadata.rpm] +package = "krust" + +[package.metadata.rpm.cargo] +buildflags = ["--release"] + +[package.metadata.rpm.targets] +krust = { path = "/usr/bin/krust" } + +[package.metadata.generate-rpm] + +assets = [ + { source = "target/release/krust", dest = "/usr/bin/krust", mode = "755" }, + { source = "krust.desktop", dest = "/usr/share/applications/krust.desktop", mode = "644" }, + { source = "data/images/krust.png", dest = "/usr/share/pixmaps/", mode = "644" }, + { source = "data/images/krust.svg", dest = "/usr/share/pixmaps/", mode = "644" }, + { source = "data/images/io.miguelbaldi.KRust.png", dest = "/usr/share/pixmaps/", mode = "644" }, + { source = "data/images/io.miguelbaldi.KRust.svg", dest = "/usr/share/icons/hicolor/scalable/apps/", mode = "644" }, + { source = "data/images/io.miguelbaldi.KRust-symbolic.png", dest = "/usr/share/icons/hicolor/symbolic/apps/", mode = "644" }, + { source = "data/images/io.miguelbaldi.KRust-symbolic.svg", dest = "/usr/share/icons/hicolor/symbolic/apps/", mode = "644" }, +] + +[package.metadata.generate-rpm.requires] +gtksourceview5 = "*" +libadwaita = "*" +cyrus-sasl-devel = "*" +openssl-devel = "*" + +[package.metadata.deb] +maintainer = "Miguel A. Baldi Hörlle " +copyright = "2024, Miguel A. Baldi Hörlle " +license-file = ["COPYING"] +extended-description = """\ +A simple Apache Kafka GUI client \ +useful for developers as well adminstrators.""" +depends = "$auto" +section = "Utility;Development;IDE;" +assets = [ + [ + "target/release/krust", + "usr/bin/", + "755", + ], + [ + "krust.desktop", + "usr/share/applications/", + "644", + ], + [ + "data/images/krust.png", + "usr/share/pixmaps/", + "644", + ], + [ + "data/images/krust.svg", + "usr/share/pixmaps/", + "644", + ], + [ + "data/images/io.miguelbaldi.KRust.png", + "usr/share/pixmaps/", + "644", + ], + [ + "data/images/io.miguelbaldi.KRust.svg", + "usr/share/icons/hicolor/scalable/apps/", + "644", + ], + [ + "data/images/io.miguelbaldi.KRust-symbolic.png", + "usr/share/icons/hicolor/symbolic/apps/", + "644", + ], + [ + "data/images/io.miguelbaldi.KRust-symbolic.svg", + "usr/share/icons/hicolor/symbolic/apps/", + "644", + ], +] diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index e7141ce..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Miguel A. Baldi Hörlle - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f7e926c --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# KRust + +`KRust` is a simple Apache Kafka GUI client useful for developers as well adminstrators, +built using GTK and [Relm4]. + + +The topics messages are visualized using tabs, which enables quick +navigation throughout multiple topics. + +`KRust` is in the early stages of development. Manipulating important topics with it +risks data loss. + +## Platform support + +Development is currently focused on Linux, but bug reports for other platforms +are welcome. + +The application is known to run successfully on Microsoft Windows 10/11. Other platforms are +untested, but if you can get the system dependencies to build, `KRust` should work. + +## Hacking + +`KRust` is a Rust project that utilizes [GTK 4][install-gtk], +[GtkSourceView][install-gtksourceview], and [libadwaita][install-libadwaita]. + +1. First, [install Rust and Cargo][install-rust]. + +2. Install system dependencies. + + #### Arch Linux + + ```sh + $ pacman -Syu gtk4 libadwaita gtksourceview5 libsasl openssl + ``` + + #### Fedora + + ``` + $ dnf install -y gtk4 libadwaita-devel cyrus-sasl-devel openssl-devel + ``` + + #### Ubuntu + + ```sh + $ apt install libsasl2-2 libgtksourceview-5-0 libadwaita-1-0 libssl3t64 + ``` + +3. Build and run the application. + + ```sh + $ cargo run + ``` + +## License + +`KRust` is licensed under the GPLv3 license (see [COPYING](COPYING) or [GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt)). + +[install-rust]: https://rustup.rs/ +[install-gtk]: https://www.gtk.org/docs/installations/ +[install-gtksourceview]: https://wiki.gnome.org/Projects/GtkSourceView +[install-libadwaita]: https://gnome.pages.gitlab.gnome.org/libadwaita/ +[Relm4]: https://aaronerhardt.github.io/relm4-book/book/ diff --git a/build-scripts/create_windows_installer.sh b/build-scripts/create_windows_installer.sh new file mode 100755 index 0000000..811cb16 --- /dev/null +++ b/build-scripts/create_windows_installer.sh @@ -0,0 +1,17 @@ +# Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +# this source code is governed by the GPL-3.0 license that can be +# found in the COPYING file. + +docker rm setup +docker container create --name setup amake/innosetup setup.iss +docker cp ./package setup:/work/ +docker cp data/images/krust.ico setup:/work/krust.ico +export MY_VERSION=$(git describe) +sed -i "s/MY_VERSION/$MY_VERSION/g" setup.iss +docker cp setup.iss setup:/work/ +iconv -f utf8 -t iso8859-1 COPYING > LICENSE +docker cp LICENSE setup:/work/LICENSE +docker start -i -a setup +docker cp setup:/work/Output/. . +docker rm setup +zip -r package.zip package diff --git a/build-scripts/linux-rpm-prepare-and-build.sh b/build-scripts/linux-rpm-prepare-and-build.sh new file mode 100755 index 0000000..0d80877 --- /dev/null +++ b/build-scripts/linux-rpm-prepare-and-build.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +# this source code is governed by the GPL-3.0 license that can be +# found in the COPYING file. + +set -euo pipefail + +#dnf install -y strace rpm-build + +# cargo install cargo-rpm && cargo rpm build +cargo install cargo-generate-rpm +cargo build --release +cargo generate-rpm --set-metadata="version = '$(git describe)'" +cargo appimage diff --git a/win-prepare-and-build.sh b/build-scripts/win-prepare-and-build.sh similarity index 92% rename from win-prepare-and-build.sh rename to build-scripts/win-prepare-and-build.sh index b2764ca..1c784ba 100755 --- a/win-prepare-and-build.sh +++ b/build-scripts/win-prepare-and-build.sh @@ -1,4 +1,8 @@ #!/bin/bash +# Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +# this source code is governed by the GPL-3.0 license that can be +# found in the COPYING file. + set -euo pipefail dnf -y install mingw64-openssl-static mingw64-gcc-c++ zstd cyrus-sasl-devel perl @@ -44,4 +48,5 @@ export CHRONO_TZ_TIMEZONE_FILTER="(GMT|UTC|Brazil/.*)" git config --global --add safe.directory /mnt git config --global --list git describe +. ~/.cargo/env && rustup target add x86_64-pc-windows-gnu build && package diff --git a/build.rs b/build.rs index 2328699..4c2b062 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use anyhow::Result; use std::{env, path::Path, process::Command}; use vergen::EmitBuilder; @@ -56,17 +60,13 @@ pub fn compile_resources>(source_dirs: &[P], gresource: &str, tar } } -fn main() -> Result<()>{ +fn main() -> Result<()> { compile_resources( &["data"], "data/resources.gresource.xml", "resources.gresource", ); - compile_resources( - &["data"], - "data/icons.gresource.xml", - "icons.gresource", - ); + compile_resources(&["data"], "data/icons.gresource.xml", "icons.gresource"); EmitBuilder::builder() .all_build() @@ -74,5 +74,10 @@ fn main() -> Result<()>{ .all_sysinfo() .fail_on_error() .emit()?; + let version: String = std::env::var("VERGEN_GIT_DESCRIBE") + .unwrap_or("0.0.1-dev".to_string()) + .clone(); + println!("cargo:rustc-env=CARGO_PKG_VERSION={}", version); + println!("cargo:rerun-if-env-changed=VERGEN_GIT_DESCRIBE"); Ok(()) } diff --git a/create_windows_installer.sh b/create_windows_installer.sh deleted file mode 100755 index 6e36b80..0000000 --- a/create_windows_installer.sh +++ /dev/null @@ -1,11 +0,0 @@ -docker rm setup -docker container create --name setup amake/innosetup setup.iss -docker cp ./package setup:/work/ -docker cp data/images/krust.ico setup:/work/krust.ico -docker cp setup.iss setup:/work/ -iconv -f utf8 -t iso8859-1 LICENSE.md > LICENSE-win.md -docker cp LICENSE-win.md setup:/work/LICENSE.md -docker start -i -a setup -docker cp setup:/work/Output/. . -docker rm setup -zip -r package.zip package diff --git a/data/images/io.miguelbaldi.KRust-symbolic.png b/data/images/io.miguelbaldi.KRust-symbolic.png new file mode 100644 index 0000000000000000000000000000000000000000..16bc40898cc41662a500c32c986cd836df0f98e3 GIT binary patch literal 28919 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 literal 0 HcmV?d00001 diff --git a/data/images/io.miguelbaldi.KRust.png b/data/images/io.miguelbaldi.KRust.png new file mode 100644 index 0000000000000000000000000000000000000000..8bbc408e7cd6a881a7550b7a65ddda3387fc34f7 GIT binary patch literal 29397 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 Kk_Ar;eEuJC=+J2Z literal 0 HcmV?d00001 diff --git a/data/images/krust.png b/data/images/krust.png new file mode 100644 index 0000000000000000000000000000000000000000..97925dcfa14c09550b8f56f7dcd2ee978d28e150 GIT binary patch literal 6552 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 KMNUMnLSTY8ro;;X literal 0 HcmV?d00001 diff --git a/data/images/krust.svg b/data/images/krust.svg new file mode 100644 index 0000000..8e43fb0 --- /dev/null +++ b/data/images/krust.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docker-compose.kafka.yml b/docker-compose.kafka.yml index 16a67c7..b1d6813 100644 --- a/docker-compose.kafka.yml +++ b/docker-compose.kafka.yml @@ -1,3 +1,7 @@ +# Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +# this source code is governed by the GPL-3.0 license that can be +# found in the COPYING file. + services: zookeeper: image: confluentinc/cp-zookeeper:7.4.4 diff --git a/docker-compose.windows.yml b/docker-compose.windows.yml index 3a24a8c..41f27fb 100644 --- a/docker-compose.windows.yml +++ b/docker-compose.windows.yml @@ -1,3 +1,7 @@ +# Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +# this source code is governed by the GPL-3.0 license that can be +# found in the COPYING file. + services: krust-cross-win: # image id: c191618ca6ff @@ -5,5 +9,5 @@ services: #image: gtk4-cross-rust-4.14.3-1.5.0 volumes: - .:/mnt:z - command: bash -c "./win-prepare-and-build.sh" + command: bash -c "./build-scripts/win-prepare-and-build.sh" diff --git a/docker-compose.yml b/docker-compose.yml index 2864173..760e86e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,12 @@ +# Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +# this source code is governed by the GPL-3.0 license that can be +# found in the COPYING file. + version: "3" services: gtk4-rs: image: ghcr.io/miguelbaldi/relm4-docker:latest-appimage volumes: - .:/mnt:z - command: sh -c "cargo appimage" + command: bash -c "./build-scripts/linux-rpm-prepare-and-build.sh" diff --git a/krust.desktop b/krust.desktop new file mode 100644 index 0000000..3896863 --- /dev/null +++ b/krust.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Name=KRust +StartupWMClass=io.miguelbaldi.KRust +Name[pt_BR]=KRust +Comment=KRust Kafka Client +Comment[pt_BR]=KRust cliente de Kafka +Icon=io.miguelbaldi.KRust +Exec=krust +Categories=Utility;Development;IDE; +Terminal=false diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..744175d --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.78" diff --git a/setup.iss b/setup.iss index 0d5855e..8a5860f 100644 --- a/setup.iss +++ b/setup.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "KRust" -#define MyAppVersion "0.0.1" +#define MyAppVersion "MY_VERSION" #define MyAppPublisher "Miguel A. Baldi Hörlle" #define MyAppURL "https://github.com/miguelbaldi/krust" #define MyAppExeName "krust.exe" @@ -22,7 +22,7 @@ AppUpdatesURL={#MyAppURL} DefaultDirName={autopf}\{#MyAppName} DefaultGroupName={#MyAppName} AllowNoIcons=yes -LicenseFile=LICENSE.md +LicenseFile=LICENSE ; Remove the following line to run in administrative install mode (install for all users.) PrivilegesRequired=lowest OutputBaseFilename=krust-setup @@ -49,4 +49,3 @@ Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilen [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent - diff --git a/src/backend/kafka.rs b/src/backend/kafka.rs index 507665b..bdcd3b1 100644 --- a/src/backend/kafka.rs +++ b/src/backend/kafka.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use futures::future; use rdkafka::admin::{AdminClient, AdminOptions, NewTopic, TopicReplication}; use rdkafka::client::{ClientContext, DefaultClientContext}; diff --git a/src/backend/mod.rs b/src/backend/mod.rs index f40c8b6..e4219e7 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + pub(crate) mod repository; pub(crate) mod kafka; pub(crate) mod worker; diff --git a/src/backend/repository.rs b/src/backend/repository.rs index 5757073..074ce75 100644 --- a/src/backend/repository.rs +++ b/src/backend/repository.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::fmt; use std::path::PathBuf; use std::string::ToString; diff --git a/src/backend/settings.rs b/src/backend/settings.rs index bc26a55..e6aa7ae 100644 --- a/src/backend/settings.rs +++ b/src/backend/settings.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use serde::{Deserialize, Serialize}; use std::fs::File; use std::path::PathBuf; diff --git a/src/backend/worker.rs b/src/backend/worker.rs index 4bb5040..3ee16b8 100644 --- a/src/backend/worker.rs +++ b/src/backend/worker.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use chrono::Utc; use tokio::select; use tracing::*; diff --git a/src/component/app.rs b/src/component/app.rs index 0efcc37..afe97d1 100644 --- a/src/component/app.rs +++ b/src/component/app.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + //! Application entrypoint. use std::{collections::HashMap, time::Duration}; diff --git a/src/component/cache_manager_dialog.rs b/src/component/cache_manager_dialog.rs index b551136..23a3576 100644 --- a/src/component/cache_manager_dialog.rs +++ b/src/component/cache_manager_dialog.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use adw::prelude::*; use fs_extra::dir::get_size; use gtk::{glib::SignalHandlerId, ColumnViewColumn}; diff --git a/src/component/connection_list.rs b/src/component/connection_list.rs index 1c05687..dc96421 100644 --- a/src/component/connection_list.rs +++ b/src/component/connection_list.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use adw::{prelude::*, AlertDialog}; use relm4::{ factory::{DynamicIndex, FactoryComponent}, diff --git a/src/component/connection_page.rs b/src/component/connection_page.rs index fa316ce..83956dd 100644 --- a/src/component/connection_page.rs +++ b/src/component/connection_page.rs @@ -1,4 +1,8 @@ #![allow(deprecated)] +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::borrow::Borrow; use adw::prelude::*; diff --git a/src/component/messages/lists.rs b/src/component/messages/lists.rs index 06c9fdc..8e2c895 100644 --- a/src/component/messages/lists.rs +++ b/src/component/messages/lists.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use crate::backend::repository::{KrustHeader, KrustMessage}; use chrono::prelude::*; use chrono_tz::America; diff --git a/src/component/messages/message_viewer.rs b/src/component/messages/message_viewer.rs index 5671a97..e31bd0c 100644 --- a/src/component/messages/message_viewer.rs +++ b/src/component/messages/message_viewer.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use gtk::prelude::*; use relm4::{typed_view::column::TypedColumnView, *}; use sourceview::prelude::*; diff --git a/src/component/messages/messages_cache_settings_dialog.rs b/src/component/messages/messages_cache_settings_dialog.rs index 1e90dd3..dde3cfd 100644 --- a/src/component/messages/messages_cache_settings_dialog.rs +++ b/src/component/messages/messages_cache_settings_dialog.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use core::f64; use std::str::FromStr; diff --git a/src/component/messages/messages_page.rs b/src/component/messages/messages_page.rs index 4f0acc9..fed0967 100644 --- a/src/component/messages/messages_page.rs +++ b/src/component/messages/messages_page.rs @@ -1,4 +1,8 @@ #![allow(deprecated)] +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + // See: https://gitlab.gnome.org/GNOME/gtk/-/issues/5644 use crate::{ diff --git a/src/component/messages/messages_send_dialog.rs b/src/component/messages/messages_send_dialog.rs index a5cbad7..4101c34 100644 --- a/src/component/messages/messages_send_dialog.rs +++ b/src/component/messages/messages_send_dialog.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::cell::RefCell; use adw::prelude::*; diff --git a/src/component/messages/messages_tab.rs b/src/component/messages/messages_tab.rs index 293de5d..72e711b 100644 --- a/src/component/messages/messages_tab.rs +++ b/src/component/messages/messages_tab.rs @@ -1,4 +1,8 @@ #![allow(deprecated)] +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::borrow::Borrow; use std::str::FromStr; diff --git a/src/component/messages/mod.rs b/src/component/messages/mod.rs index b1e1eba..a542ae4 100644 --- a/src/component/messages/mod.rs +++ b/src/component/messages/mod.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + mod lists; pub(crate) mod message_viewer; pub(crate) mod messages_cache_settings_dialog; diff --git a/src/component/mod.rs b/src/component/mod.rs index 7b17f39..0e38503 100644 --- a/src/component/mod.rs +++ b/src/component/mod.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + //! Relm4 components. use crate::backend::repository::KrustConnection; diff --git a/src/component/settings_dialog.rs b/src/component/settings_dialog.rs index aa0ceb2..7aa7a64 100644 --- a/src/component/settings_dialog.rs +++ b/src/component/settings_dialog.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::path::PathBuf; use adw::prelude::*; diff --git a/src/component/status_bar.rs b/src/component/status_bar.rs index 0154fa0..bc1c579 100644 --- a/src/component/status_bar.rs +++ b/src/component/status_bar.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + //! Alert dialog for displaying arbitrary errors. //! //! Inspired by [`relm4_components::alert`], but allows sending the dialog text as part of the diff --git a/src/component/task_manager.rs b/src/component/task_manager.rs index a7d011e..c97becb 100644 --- a/src/component/task_manager.rs +++ b/src/component/task_manager.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::borrow::Borrow; use std::cell::RefCell; use std::time::Duration; diff --git a/src/component/topics/create_dialog.rs b/src/component/topics/create_dialog.rs index 2ffd5a7..4e1bc27 100644 --- a/src/component/topics/create_dialog.rs +++ b/src/component/topics/create_dialog.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use crate::backend::{ kafka::{CreateTopicRequest, KafkaBackend}, repository::KrustConnection, diff --git a/src/component/topics/mod.rs b/src/component/topics/mod.rs index fe009a2..aacdee4 100644 --- a/src/component/topics/mod.rs +++ b/src/component/topics/mod.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + pub(crate) mod create_dialog; pub(crate) mod topics_page; pub(crate) mod topics_tab; diff --git a/src/component/topics/topics_page.rs b/src/component/topics/topics_page.rs index 3e6ba51..478ea3e 100644 --- a/src/component/topics/topics_page.rs +++ b/src/component/topics/topics_page.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use crate::{ backend::repository::{KrustConnection, KrustTopic}, component::{ diff --git a/src/component/topics/topics_tab.rs b/src/component/topics/topics_tab.rs index d642a48..4eb6d1f 100644 --- a/src/component/topics/topics_tab.rs +++ b/src/component/topics/topics_tab.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::{cell::RefCell, cmp::Ordering, collections::HashMap}; use crate::backend::repository::KrustTopicCache; diff --git a/src/config.rs b/src/config.rs index e1938a2..9a692b4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use directories::ProjectDirs; use rdkafka::error::KafkaError; use ron::de::SpannedError; diff --git a/src/lib.rs b/src/lib.rs index 46b6c3d..5e819f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ -//! Small, general purpose file manager built using GTK. -//! -//! Generally, each top-level module corresponds to a different Relm4 component. - #![warn(clippy::dbg_macro)] +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] #![warn(clippy::todo)] diff --git a/src/main.rs b/src/main.rs index e9e15a6..21f3a6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,8 @@ #![windows_subsystem = "windows"] +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use std::env; use gtk::gdk; diff --git a/src/modals/about.rs b/src/modals/about.rs index 59115ba..aeb5b04 100644 --- a/src/modals/about.rs +++ b/src/modals/about.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use fs_extra::dir::get_size; use gtk::prelude::GtkWindowExt; use humansize::{format_size, DECIMAL}; @@ -22,7 +26,7 @@ impl SimpleComponent for AboutDialog { //.application_icon("/org/miguelbaldi/krust/logo.png") .application_icon(APP_ID) // Insert your license of choice here - .license_type(gtk::License::MitX11) + .license_type(gtk::License::Gpl30) // Insert your website here .website("https://github.com/miguelbaldi/krust") // Insert your Issues page diff --git a/src/modals/mod.rs b/src/modals/mod.rs index f22c255..f9c9cdc 100644 --- a/src/modals/mod.rs +++ b/src/modals/mod.rs @@ -1,2 +1,6 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + pub(crate) mod about; pub(crate) mod utils; diff --git a/src/modals/utils.rs b/src/modals/utils.rs index 8c35e16..a70e561 100644 --- a/src/modals/utils.rs +++ b/src/modals/utils.rs @@ -1,3 +1,7 @@ +// Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +// this source code is governed by the GPL-3.0 license that can be +// found in the COPYING file. + use adw::prelude::*; pub(crate) fn show_error_alert(parent: &impl IsA, message: String) { diff --git a/src/styles.less b/src/styles.less index 3656bb0..64cc12e 100644 --- a/src/styles.less +++ b/src/styles.less @@ -1,4 +1,9 @@ /* +* Copyright (c) 2024, Miguel A. Baldi Hörlle . All rights reserved. Use of +* this source code is governed by the GPL-3.0 license that can be +* found in the COPYING file. +*/ +/* Logo/Theme colors: Red Orange 4: #FF3F34 Pickled Bluewood 2: #314459