diff --git a/.gitignore b/.gitignore index fefc6ff..468395b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,7 @@ target_*/ .flatpak-builder/ app/ repo/ + +# Files configured by meson +podcasts-gtk/src/config.rs +podcasts-gtk/src/static_resource.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 93fd27d..82f6b02 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,9 +17,6 @@ flatpak: script: - flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH} - # https://gitlab.gnome.org/World/podcasts/issues/55 - # Force regeneration of gresources regardless of artifacts chage - - flatpak-builder --run app ${MANIFEST_PATH} glib-compile-resources --sourcedir=podcasts-gtk/resources/ podcasts-gtk/resources/resources.xml # Build the flatpak repo - flatpak-builder --run app ${MANIFEST_PATH} meson --prefix=/app ${CONFIGURE_ARGS} _build @@ -29,13 +26,10 @@ flatpak: - | xvfb-run -a -s "-screen 0 1024x768x24" \ flatpak-builder --run \ - --env=APP_ID="org.gnome.PodcastsDevel" \ - --env=LOCALEDIR="./podcasts-gtk/po" \ - --env=VERSION="0.0.0" \ - --env=CARGO_HOME="target/cargo-home" \ - --env=CARGO_TARGET_DIR="target_test/" \ + --env=CARGO_HOME="${CI_PROJECT_DIR}/target/cargo-home" \ + --env=CARGO_TARGET_DIR="${CI_PROJECT_DIR}/target/" \ app ${MANIFEST_PATH} \ - cargo test --color=always -j 1 -- --test-threads=1 + ninja -C _build test # Create a flatpak bundle - flatpak-builder --finish-only app ${MANIFEST_PATH} @@ -92,6 +86,10 @@ rustfmt: stage: "lint" script: - rustup component add rustfmt + # Create blank versions of our configured files + # so rustfmt does not yell about non-existent files or completely empty files + - echo -e "" >> podcasts-gtk/src/config.rs + - echo -e "" >> podcasts-gtk/src/static_resource.rs - rustc -Vv && cargo -Vv - cargo fmt --version - cargo fmt --all -- --color=always --check diff --git a/meson.build b/meson.build index 7fc5e17..140bad4 100644 --- a/meson.build +++ b/meson.build @@ -46,6 +46,7 @@ endif application_id = 'org.gnome.Podcasts@0@'.format(profile) i18n = import('i18n') +gnome = import('gnome') subdir('podcasts-gtk/po') podir = join_paths (meson.source_root (), 'podcasts-gtk', 'po') @@ -64,22 +65,22 @@ datadir = get_option('datadir') subdir('podcasts-gtk/resources') cargo_script = find_program('scripts/cargo.sh') +test_script = find_program('scripts/test.sh') -cargo_release = custom_target('cargo-build', - build_always_stale: true, - output: ['gnome-podcasts'], - install: true, - install_dir: podcasts_bindir, - console: true, - command: [cargo_script, - '@CURRENT_SOURCE_DIR@', - '@OUTPUT@', - podcasts_localedir, - application_id, - podcasts_version + version_suffix, - profile - ]) +subdir('podcasts-data/src') +subdir('podcasts-downloader/src') +subdir('podcasts-gtk/src') -run_target('release', command: ['scripts/release.sh', - meson.project_name() + '-' + podcasts_version - ]) +meson.add_dist_script( + 'scripts/dist-vendor.sh', + meson.source_root(), + join_paths(meson.build_root(), 'meson-dist', meson.project_name() + '-' + podcasts_version) +) + +test( + 'cargo-test', + test_script, + args: meson.build_root(), + workdir: meson.source_root(), + timeout: 3000 +) diff --git a/org.gnome.Podcasts.json b/org.gnome.Podcasts.json index 9c57b70..3093fc9 100644 --- a/org.gnome.Podcasts.json +++ b/org.gnome.Podcasts.json @@ -62,6 +62,7 @@ }, { "name" : "gnome-podcasts", + "builddir" : "true", "buildsystem" : "meson", "sources" : [ { diff --git a/org.gnome.PodcastsDevel.json b/org.gnome.PodcastsDevel.json index c169b57..5e25ab7 100644 --- a/org.gnome.PodcastsDevel.json +++ b/org.gnome.PodcastsDevel.json @@ -63,6 +63,7 @@ { "name" : "gnome-podcasts", "buildsystem" : "meson", + "builddir" : "true", "config-opts" : [ "-Dprofile=development" ], "sources" : [ { diff --git a/podcasts-data/src/meson.build b/podcasts-data/src/meson.build new file mode 100644 index 0000000..fc33b47 --- /dev/null +++ b/podcasts-data/src/meson.build @@ -0,0 +1,19 @@ +data_sources = files( + 'models/episode.rs', + 'models/mod.rs', + 'models/new_episode.rs', + 'models/new_show.rs', + 'models/new_source.rs', + 'models/show.rs', + 'models/source.rs', + 'database.rs', + 'dbqueries.rs', + 'errors.rs', + 'feed.rs', + 'lib.rs', + 'opml.rs', + 'parser.rs', + 'pipeline.rs', + 'schema.rs', + 'utils.rs', +) diff --git a/podcasts-downloader/src/meson.build b/podcasts-downloader/src/meson.build new file mode 100644 index 0000000..120d95a --- /dev/null +++ b/podcasts-downloader/src/meson.build @@ -0,0 +1,5 @@ +downloader_sources = files( + 'downloader.rs', + 'errors.rs', + 'lib.rs' +) diff --git a/podcasts-gtk/Cargo.toml b/podcasts-gtk/Cargo.toml index 787930b..1ec78f0 100644 --- a/podcasts-gtk/Cargo.toml +++ b/podcasts-gtk/Cargo.toml @@ -1,6 +1,5 @@ [package] authors = ["Jordan Petridis "] -build = "build.rs" name = "podcasts-gtk" version = "0.1.0" diff --git a/podcasts-gtk/build.rs b/podcasts-gtk/build.rs deleted file mode 100644 index c8279e6..0000000 --- a/podcasts-gtk/build.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::process::Command; - -fn main() { - // Rerun the build script when files in the resources folder are changed. - println!("cargo:rerun-if-changed=resources"); - println!("cargo:rerun-if-changed=resources/*"); - - let out = Command::new("glib-compile-resources") - .args(&["--generate", "resources.xml"]) - .current_dir("resources") - .status() - .expect("failed to generate resources"); - assert!(out.success()); -} diff --git a/podcasts-gtk/resources/meson.build b/podcasts-gtk/resources/meson.build index ee91f08..c46bd00 100644 --- a/podcasts-gtk/resources/meson.build +++ b/podcasts-gtk/resources/meson.build @@ -58,4 +58,11 @@ configure_file( install_dir: join_paths(datadir,'dbus-1', 'services') ) +podcasts_resources = gnome.compile_resources( + 'resources', + 'resources.xml', + gresource_bundle: true, + source_dir: meson.current_build_dir() +) + meson.add_install_script('../../scripts/compile-gschema.py') diff --git a/podcasts-gtk/src/app.rs b/podcasts-gtk/src/app.rs index df556a8..0e82949 100644 --- a/podcasts-gtk/src/app.rs +++ b/podcasts-gtk/src/app.rs @@ -46,23 +46,9 @@ use std::env; use std::rc::Rc; use std::sync::Arc; +use crate::config::{APP_ID, LOCALEDIR}; use crate::i18n::i18n; -#[rustfmt::skip] -lazy_static! { - pub static ref APP_ID: &'static str = { - option_env!("APP_ID").unwrap_or("org.gnome.Podcasts") - }; - - pub static ref VERSION: &'static str = { - option_env!("VERSION").unwrap_or("0.0.1") - }; - - pub static ref LOCALEDIR: &'static str = { - option_env!("LOCALEDIR").unwrap_or("./podcasts-gtk/po") - }; -} - /// Creates an action named `name` in the action map `T with the handler `F` fn action(thing: &T, name: &str, action: F) where @@ -428,10 +414,10 @@ impl App { pub(crate) fn run() { // Set up the textdomain for gettext setlocale(LocaleCategory::LcAll, ""); - bindtextdomain("gnome-podcasts", *LOCALEDIR); + bindtextdomain("gnome-podcasts", LOCALEDIR); textdomain("gnome-podcasts"); - let application = gtk::Application::new(*APP_ID, gio::ApplicationFlags::empty()) + let application = gtk::Application::new(APP_ID, gio::ApplicationFlags::empty()) .expect("Application initialization failed..."); application.set_resource_base_path("/org/gnome/Podcasts"); @@ -462,7 +448,7 @@ impl App { // Weird magic I copy-pasted that sets the Application Name in the Shell. glib::set_application_name(&i18n("Podcasts")); glib::set_prgname(Some("gnome-podcasts")); - gtk::Window::set_default_icon_name(*APP_ID); + gtk::Window::set_default_icon_name(APP_ID); let args: Vec = env::args().collect(); ApplicationExtManual::run(&application, &args); } diff --git a/podcasts-gtk/src/config.rs.in b/podcasts-gtk/src/config.rs.in new file mode 100644 index 0000000..7de9911 --- /dev/null +++ b/podcasts-gtk/src/config.rs.in @@ -0,0 +1,23 @@ +/* config.rs.in + * + * Copyright 2019 Christopher Davis + * + * 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +pub static APP_ID: &'static str = @APP_ID@; +pub static VERSION: &'static str = @VERSION@; +pub static LOCALEDIR: &'static str = @LOCALEDIR@; diff --git a/podcasts-gtk/src/main.rs b/podcasts-gtk/src/main.rs index ee9db90..0a720dd 100644 --- a/podcasts-gtk/src/main.rs +++ b/podcasts-gtk/src/main.rs @@ -109,6 +109,7 @@ mod stacks; mod widgets; mod app; +mod config; mod headerbar; mod prefs; diff --git a/podcasts-gtk/src/meson.build b/podcasts-gtk/src/meson.build new file mode 100644 index 0000000..4c02888 --- /dev/null +++ b/podcasts-gtk/src/meson.build @@ -0,0 +1,77 @@ +global_conf = configuration_data() +global_conf.set_quoted('APP_ID', application_id) +global_conf.set_quoted('VERSION', podcasts_version + version_suffix) +global_conf.set_quoted('LOCALEDIR', podcasts_localedir) +config_rs = configure_file( + input: 'config.rs.in', + output: 'config.rs', + configuration: global_conf +) + +run_command( + 'cp', + config_rs, + meson.current_source_dir(), + check: true +) + +# include_bytes! only takes a string literal +resource_conf = configuration_data() +resource_conf.set_quoted('RESOURCEFILE', podcasts_resources.full_path()) +resource_rs = configure_file( + input: 'static_resource.rs.in', + output: 'static_resource.rs', + configuration: resource_conf +) + +run_command( + 'cp', + resource_rs, + meson.current_source_dir(), + check: true +) + +podcasts_sources = files( + 'stacks/content.rs', + 'stacks/home.rs', + 'stacks/mod.rs', + 'stacks/populated.rs', + 'stacks/show.rs', + 'widgets/aboutdialog.rs', + 'widgets/appnotif.rs', + 'widgets/base_view.rs', + 'widgets/empty.rs', + 'widgets/home_view.rs', + 'widgets/mod.rs', + 'widgets/player.rs', + 'widgets/show.rs', + 'widgets/show_menu.rs', + 'widgets/shows_view.rs', + 'app.rs', + 'headerbar.rs', + 'i18n.rs', + 'main.rs', + 'manager.rs', + 'prefs.rs', + 'settings.rs', + 'utils.rs' +) + +cargo_release = custom_target('cargo-build', + build_by_default: true, + input: [ + data_sources, + downloader_sources, + podcasts_sources, + ], + output: ['gnome-podcasts'], + install: true, + install_dir: podcasts_bindir, + console: true, + depends: podcasts_resources, + command: [cargo_script, + '@SOURCE_ROOT@', + '@OUTPUT@', + meson.build_root(), + profile + ]) diff --git a/podcasts-gtk/src/static_resource.rs b/podcasts-gtk/src/static_resource.rs.in similarity index 94% rename from podcasts-gtk/src/static_resource.rs rename to podcasts-gtk/src/static_resource.rs.in index c7fad23..a6c303e 100644 --- a/podcasts-gtk/src/static_resource.rs +++ b/podcasts-gtk/src/static_resource.rs.in @@ -23,7 +23,7 @@ use glib::Bytes; pub(crate) fn init() -> Result<(), Error> { // load the gresource binary at build time and include/link it into the final // binary. - let res_bytes = include_bytes!("../resources/resources.gresource"); + let res_bytes = include_bytes!(@RESOURCEFILE@); // Create Resource it will live as long the value lives. let gbytes = Bytes::from_static(res_bytes.as_ref()); diff --git a/podcasts-gtk/src/widgets/aboutdialog.rs b/podcasts-gtk/src/widgets/aboutdialog.rs index f29ce06..1e35841 100644 --- a/podcasts-gtk/src/widgets/aboutdialog.rs +++ b/podcasts-gtk/src/widgets/aboutdialog.rs @@ -17,7 +17,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -use crate::app::{APP_ID, VERSION}; +use crate::config::{APP_ID, VERSION}; use gtk; use gtk::prelude::*; @@ -47,12 +47,12 @@ pub(crate) fn about_dialog(window: >k::ApplicationWindow) { ]; let dialog = gtk::AboutDialog::new(); - dialog.set_logo_icon_name(*APP_ID); + dialog.set_logo_icon_name(APP_ID); dialog.set_comments(i18n("Podcast Client for the GNOME Desktop.").as_str()); dialog.set_copyright("© 2017, 2018 Jordan Petridis"); dialog.set_license_type(gtk::License::Gpl30); dialog.set_modal(true); - dialog.set_version(*VERSION); + dialog.set_version(VERSION); dialog.set_program_name(&i18n("Podcasts")); dialog.set_website("https://wiki.gnome.org/Apps/Podcasts"); dialog.set_website_label(i18n("Learn more about GNOME Podcasts").as_str()); diff --git a/podcasts-gtk/src/widgets/empty.rs b/podcasts-gtk/src/widgets/empty.rs index 5087078..66633b3 100644 --- a/podcasts-gtk/src/widgets/empty.rs +++ b/podcasts-gtk/src/widgets/empty.rs @@ -17,7 +17,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -use crate::app::APP_ID; +use crate::config::APP_ID; use gtk::{self, prelude::*}; use std::ops::Deref; @@ -37,7 +37,7 @@ impl Default for EmptyView { let view: gtk::Box = builder.get_object("empty_view").unwrap(); let image: gtk::Image = builder.get_object("image").unwrap(); image.set_from_icon_name( - format!("{}-symbolic", *APP_ID).as_str(), + format!("{}-symbolic", APP_ID).as_str(), gtk::IconSize::__Unknown(256), ); EmptyView(view) diff --git a/scripts/cargo.sh b/scripts/cargo.sh index bbe335a..ad47db3 100755 --- a/scripts/cargo.sh +++ b/scripts/cargo.sh @@ -2,11 +2,10 @@ set -ex -export CARGO_HOME=$1/target/cargo-home -export LOCALEDIR="$3" -export APP_ID="$4" -export VERSION="$5" -export PROFILE="$6" +export OUTPUT="$2" +export CARGO_TARGET_DIR="$3"/target +export CARGO_HOME="$CARGO_TARGET_DIR"/cargo-home +export PROFILE="$4" TARGET=debug ARGS=() @@ -22,4 +21,5 @@ if test -d vendor; then ARGS+=('--frozen') fi -cargo build ${ARGS[@]} -p podcasts-gtk && cp $1/target/${TARGET}/podcasts-gtk $2 +cargo build ${ARGS[@]} --manifest-path="$1"/Cargo.toml -p podcasts-gtk && +cp "$CARGO_TARGET_DIR"/${TARGET}/podcasts-gtk "$OUTPUT" diff --git a/scripts/dist-vendor.sh b/scripts/dist-vendor.sh new file mode 100755 index 0000000..e28f21d --- /dev/null +++ b/scripts/dist-vendor.sh @@ -0,0 +1,9 @@ +#!/bin/sh +export SOURCE_ROOT="$1" +export DIST="$2" + +cd "$SOURCE_ROOT" +mkdir "$DIST"/.cargo +cargo vendor | sed 's/^directory = ".*"/directory = "vendor"/g' > $DIST/.cargo/config +# Move vendor into dist tarball directory +mv vendor "$DIST" diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index c1a7d69..0000000 --- a/scripts/release.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -VERSION=$1 -DEST=${MESON_BUILD_ROOT} -DIST=$DEST/dist/$VERSION - - -cd "${MESON_SOURCE_ROOT}" -mkdir -p $DIST - -# copying files -cp -rf podcasts-data $DIST -cp -rf podcasts-gtk $DIST -cp -rf podcasts-downloader $DIST -cp Cargo.toml $DIST -cp Cargo.lock $DIST -cp meson.build $DIST -cp meson_options.txt $DIST -cp podcasts.doap $DIST -cp LICENSE $DIST -cp README.md $DIST -cp -rf screenshots $DIST -cp -rf scripts $DIST - -#cargo vendor -mkdir $DIST/.cargo -cargo vendor | sed 's/^directory = ".*"/directory = "vendor"/g' > $DIST/.cargo/config -cp -rf vendor $DIST/ - -# packaging -cd $DEST/dist -tar -cJvf $VERSION.tar.xz $VERSION diff --git a/scripts/test.sh b/scripts/test.sh index 5d4a9bd..35ed241 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,40 +1,9 @@ #! /usr/bin/sh set -o errexit -set -o nounset set -o pipefail -export MANIFEST_PATH="org.gnome.PodcastsDevel.json" -export FLATPAK_MODULE="gnome-podcasts" -export CONFIGURE_ARGS="-Dprofile=development" -# export DBUS_ID="org.gnome.PodcastsDevel" -# export BUNDLE="org.gnome.Podcasts.Devel.flatpak" -# export RUNTIME_REPO="https://sdk.gnome.org/gnome-nightly.flatpakrepo" +export CARGO_TARGET_DIR="$1/target/" +export CARGO_HOME="$CARGO_TARGET_DIR/cargo-home" -flatpak-builder --stop-at=${FLATPAK_MODULE} --force-clean app ${MANIFEST_PATH} -# https://gitlab.gnome.org/World/podcasts/issues/55 -# Force regeneration of gresources regardless of artifacts chage -flatpak-builder --run app ${MANIFEST_PATH} glib-compile-resources --sourcedir=podcasts-gtk/resources/ podcasts-gtk/resources/resources.xml - -# Build the flatpak repo -flatpak-builder --run app ${MANIFEST_PATH} meson --prefix=/app ${CONFIGURE_ARGS} build -flatpak-builder --run \ - --env=CARGO_HOME="target/cargo-home" \ - --env=CARGO_TARGET_DIR="target_test/" \ - --env=RUSTFLAGS="" \ - app ${MANIFEST_PATH} \ - ninja -C build - -# Run the tests -xvfb-run -a -s "-screen 0 1024x768x24" \ - flatpak-builder --run \ - --env=CARGO_HOME="target/cargo-home" \ - --env=CARGO_TARGET_DIR="target_test/" \ - --env=RUSTFLAGS="" \ - app ${MANIFEST_PATH} \ - cargo test -j 1 -- --test-threads=1 --nocapture - -# Create a flatpak bundle -# flatpak-builder --finish-only app ${MANIFEST_PATH} -# flatpak build-export repo app -# flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${DBUS_ID} +cargo test -j 1 -- --test-threads=1 --nocapture