Improved the Peace::Model::Release generate_build.

This commit is contained in:
sergiotarxz 2022-03-29 01:03:02 +02:00
parent a2cf90ca29
commit cd17423eb5
9 changed files with 196 additions and 53 deletions

View File

@ -20,6 +20,7 @@ my $build = Module::Build->new(
'Test::Pod::Coverage' => 0,
'JSON' => 0,
'YAML' => 0,
'Capture::Tiny' => 0,
},
install_path => {
'templates' => "$HOME/.local/share/peace/template",

View File

@ -44,6 +44,9 @@
<li>
<a href="lib/Peace/Test/Mock/Model/Application.pm.html">Peace::Test::Mock::Model::Application</a>
</li>
<li>
<a href="lib/Peace/Test/Mock/Model/Build.pm.html">Peace::Test::Mock::Model::Build</a>
</li>
<li>
<a href="lib/Peace/Test/Mock/Model/Developer.pm.html">Peace::Test::Mock::Model::Developer</a>
</li>

View File

@ -22,6 +22,7 @@
</li>
<li><a href="#METHODS">METHODS</a>
<ul>
<li><a href="#generate_build">generate_build</a></li>
<li><a href="#uuid">uuid</a></li>
<li><a href="#date_creation">date_creation</a></li>
<li><a href="#application">application</a></li>
@ -68,6 +69,16 @@
<p>Peace::Model::Release implements the following methods:</p>
<h2 id="generate_build">generate_build</h2>
<p>my $result = $release-&gt;generate_build( arch =&gt; $arch );</p>
<p>my ($success, $output) = @result{&#39;success&#39;, &#39;output&#39;};</p>
<p>Generates a build for a given arch of the release and returns the success status, any false value failed, any true value succeded and the output which combines stdout and stderr from the ran commands and some application specific data about whats being done.</p>
<p>The output log is thought to be human consumed, not automatically parsed.</p>
<h2 id="uuid">uuid</h2>
<pre><code>my $uuid = $release-&gt;uuid;

View File

@ -33,7 +33,7 @@
<h1 id="DESCRIPTION">DESCRIPTION</h1>
<p>Peace::Test::Mock::Model::Application aims to reduce repeated code which doesn&#39;t bring new things to tests by avoiding to add long lines in order to create a <a href="../../../Model/Application.pm.html">Peace::Model::Application</a> object on a unrelated test by providing a stub one already created object.</p>
<p>Peace::Test::Mock::Model::Application aims to reduce repeated code which doesn&#39;t bring new things to tests by avoiding to add long lines in order to create a <a href="../../../Model/Application.pm.html">Peace::Model::Application</a> object on a unrelated tests by providing a stub already created object.</p>
<h1 id="INSTANCE-METHODS">INSTANCE METHODS</h1>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Peace::Test::Mock::Model::Build - Mock object for Peace::Model::Build.</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<link href="mailto:Alpine@build-edge-aarch64.nonet" rev="made" />
</head>
<body>
<ul id="index">
<li><a href="#NAME">NAME</a></li>
<li><a href="#SYNOPSIS">SYNOPSIS</a></li>
<li><a href="#DESCRIPTION">DESCRIPTION</a></li>
<li><a href="#INSTANCE-METHODS">INSTANCE METHODS</a>
<ul>
<li><a href="#new">new</a></li>
</ul>
</li>
<li><a href="#SEE-ALSO">SEE ALSO</a></li>
</ul>
<h1 id="NAME">NAME</h1>
<p>Peace::Test::Mock::Model::Build - Mock object for Peace::Model::Build.</p>
<h1 id="SYNOPSIS">SYNOPSIS</h1>
<pre><code>my $build = Peace::Test::Mock::Model::Build-&gt;new;</code></pre>
<h1 id="DESCRIPTION">DESCRIPTION</h1>
<p>Peace::Test::Mock::Model::Build aims to reduce repeated code which doesn&#39;t bring new things to tests by avoiding to add long lines in order to create a <a href="../../../Model/Build.pm.html">Peace::Model::Build</a> object on a unrelated tests by providing a stub already created object.</p>
<h1 id="INSTANCE-METHODS">INSTANCE METHODS</h1>
<p>Peace::Test::Mock::Model::Build provides the following instance methods:</p>
<h2 id="new">new</h2>
<pre><code>my $build = Peace::Test::Mock::Model::Build-&gt;new;</code></pre>
<p>Instances a <a href="../../../Model/Build.pm.html">Peace::Model::Build</a> mock object.</p>
<h1 id="SEE-ALSO">SEE ALSO</h1>
<p><a href="../../../Model/Build.pm.html">Peace::Model::Build</a></p>
</body>
</html>

View File

@ -66,7 +66,7 @@ use Peace::DAO::Release;
{
my $validator = validation_for( params =>
{ { type => InstanceOf ['Peace::Model::Release'], optional => 1 } } );
[ { type => InstanceOf ['Peace::Model::Release'], optional => 1 } ] );
sub release {
my $self = shift;

View File

@ -11,6 +11,9 @@ use Path::Tiny;
use File::pushd;
use YAML;
use JSON;
use Capture::Tiny qw/tee_merged/;
use File::Spec;
use List::AllUtils qw/any/;
{
my $validator = validation_for(
@ -46,53 +49,77 @@ use JSON;
arch => { type => Str },
}
);
sub generate_build {
my $self = shift;
my %params = $validator->(@_);
my $application = $self->application;
my $flatpak_builder_file = $application->flatpak_builder_file;
my $arch = $params{arch};
my $dir = Path::Tiny->tempdir;
my $clone_dir = Path::Tiny->tempdir;
my $output_dir = Path::Tiny->new($ENV{HOME})->child('.peace-apps');
local $ENV{HOME} = $dir;
say $dir;
system 'git', 'clone', $application->git_repo, $clone_dir;
my $current_dir = pushd $clone_dir;
my $flatpak_data = $self->_parse_flatpak_builder_file;
my $app_id = $flatpak_data->{"app-id"};
my $sdk = $flatpak_data->{sdk};
my $runtime = $flatpak_data->{runtime};
system 'flatpak', '--user', 'list';
system 'flatpak', '--user', 'remote-add', '--if-not-exists', 'remote', $application->flatpak_repo;
say $sdk;
system 'flatpak', '--user', 'install', '--arch', $arch, '-y', "$sdk";
say $runtime;
system 'flatpak', '--user', 'install', '--arch', $arch, '-y', "$runtime";
system 'flatpak-builder', '--arch', $arch, '--install', '--user', 'build', $application->flatpak_builder_file, $app_id;
$output_dir = $output_dir->child($self->uuid);
$output_dir->mkpath;
system 'flatpak', 'build-bundle', '--arch', $arch, $dir->child('.local/share/flatpak/repo/'), $output_dir->child($arch), $app_id;
sub generate_build {
my $self = shift;
my %params = $validator->(@_);
my $arch = $params{arch};
my $application = $self->application;
say "Building @{[$application->name]} for $arch...";
my ( $merged_output, $exit ) = tee_merged {
my $flatpak_builder_file = $application->flatpak_builder_file;
say
"$flatpak_builder_file directory portions should not be .., . or empty string", return 1
if any { $_ eq '..' or $_ eq '.' or $_ eq '' }
File::Spec->splitdir($flatpak_builder_file);
my $dir = Path::Tiny->tempdir;
my $clone_dir = Path::Tiny->tempdir;
my $output_dir =
Path::Tiny->new( $ENV{HOME} )->child('.peace-apps');
local $ENV{HOME} = $dir;
say "TEMP_HOME: $dir";
system 'git', 'clone', $application->git_repo, $clone_dir and return 1;
say "CLONE_DIR: $clone_dir";
my $current_dir = pushd $clone_dir;
my $flatpak_data = $self->_parse_flatpak_builder_file;
my $app_id = $flatpak_data->{"app-id"};
say "APP_ID: $app_id";
my $sdk = $flatpak_data->{sdk};
say "SDK: $sdk";
my $runtime = $flatpak_data->{runtime};
say "RUNTIME: $runtime";
system 'flatpak', '--user', 'list' and return 1;
system 'flatpak', '--user', 'remote-add', '--if-not-exists',
'remote', $application->flatpak_repo and return 1;
say $sdk;
system 'flatpak', '--user', 'install', '--arch', $arch, '-y',
"$sdk" and return 1;
say $runtime;
system 'flatpak', '--user', 'install', '--arch', $arch, '-y',
"$runtime" and return 1;
system 'flatpak-builder', '--arch', $arch, '--install', '--user',
'build', $application->flatpak_builder_file, $app_id and return 1;
$output_dir = $output_dir->child( $self->uuid );
$output_dir->mkpath;
return system 'flatpak', 'build-bundle', '--arch', $arch,
$dir->child('.local/share/flatpak/repo/'),
$output_dir->child($arch), $app_id;
};
my $success = 1;
if ($exit) {
say "BUILD FAILED:\n$merged_output";
$success = 0;
}
return {
output => $merged_output,
success => $success,
};
}
}
sub _parse_flatpak_builder_file {
my $self = shift;
my $application = $self->application;
my $self = shift;
my $application = $self->application;
my $flatpak_builder_file = $application->flatpak_builder_file;
my $path = Path::Tiny->new($flatpak_builder_file);
my $payload = $path->slurp_utf8;
my $path = Path::Tiny->new($flatpak_builder_file);
my $payload = $path->slurp_utf8;
my $structure;
eval {
$structure = decode_json($payload);
};
if (!defined $structure) {
eval {
($structure) = Load($payload);
};
eval { $structure = decode_json($payload); };
if ( !defined $structure ) {
eval { ($structure) = Load($payload); };
}
if (!defined $structure) {
if ( !defined $structure ) {
die "Unable to parse flatpak builder file.";
}
return $structure;
@ -138,6 +165,7 @@ sub _dbh {
{ type => InstanceOf ['Peace::Model::Application'], optional => 1 }
]
);
sub application {
my $self = shift;
if (@_) {
@ -158,12 +186,14 @@ sub _dbh {
{
my $validator = validation_for(
params => [
{
type => Str, optional => 1,
}
]
params => [
{
type => Str,
optional => 1,
}
]
);
sub tag {
my $self = shift;
if (@_) {
@ -175,11 +205,8 @@ sub _dbh {
}
{
my $validator = validation_for(
params => [
{ type => Str, optional => 1 },
]
);
my $validator =
validation_for( params => [ { type => Str, optional => 1 }, ] );
sub name {
my $self = shift;
@ -192,6 +219,7 @@ sub _dbh {
}
1;
=encoding utf8
=head1 NAME
@ -231,6 +259,21 @@ methods:
Peace::Model::Release implements the following methods:
=head2 generate_build
my $result = $release->generate_build( arch => $arch );
my ($success, $output) = @result{'success', 'output'};
Generates a build for a given arch of the release and
returns the success status, any false value failed,
any true value succeded and the output which combines
stdout and stderr from the ran commands and some
application specific data about whats being done.
The output log is thought to be human consumed, not
automatically parsed.
=head2 uuid
my $uuid = $release->uuid;

View File

@ -3,7 +3,7 @@ use v5.30.0;
use strict;
use warnings;
use Test::Most tests => 5;
use Test::Most tests => 6;
use Test::MockModule;
use Peace::Model::Application;
@ -139,3 +139,28 @@ BEGIN {
## THEN
is $release->application, $release_application, 'Uuid is undef.';
}
{
my $developer = Peace::Test::Mock::Model::Developer->new;
my $application = Peace::Model::Application->new(
name => 'OpenMG',
description => 'Stub',
url => 'https://gitea.sergiotarxz.freemyip.com/sergiotarxz/mangareader',
developer => $developer,
price => '99',
git_repo =>
'https://gitea.sergiotarxz.freemyip.com/sergiotarxz/mangareader',
flatpak_builder_file => '../me.sergiotarxz.openmg.json',
flatpak_repo => 'https://nightly.gnome.org/gnome-nightly.flatpakrepo',
verified => 1,
);
my $uuid = 'random-uuid';
my $release = Peace::Model::Release->new(
uuid => $uuid,
application => $application,
tag => 'main',
name => 'test',
);
my $result = $release->generate_build( arch => 'x86_64' );
ok !$result->{success}, 'Build ends fail if flatpak_builder_file contains a .. component to avoid a directory escape vulnerability..';
}

View File

@ -5,6 +5,8 @@ use v5.30.0;
use strict;
use warnings;
use Test::Most tests => 1;
use Peace::Test::Mock::Model::Developer;
use Peace::Model::Application;
use Peace::Model::Release;
@ -30,5 +32,6 @@ use Peace::Model::Release;
tag => 'main',
name => 'test',
);
$release->generate_build( arch => 'x86_64' );
my $result = $release->generate_build( arch => 'x86_64' );
ok $result->{success}, 'Build ends successfully.';
}