Skip to content

Commit

Permalink
feat: an option to change current working directory before package start
Browse files Browse the repository at this point in the history
  • Loading branch information
maxirmx committed Aug 6, 2024
1 parent 2a7c228 commit 067e22b
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 28 deletions.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,13 @@ else(${IS_MSYS})
set(FS_MOUNT_POINT "/__tebako_memfs__")
endif(${IS_MSYS})

if(PACKAGE_NEEDS_CWD)
set(NEEDS_CWD true)
set(PACKAGE_CWD ${FS_MOUNT_POINT}/${PACKAGE_CWD})
else(PACKAGE_NEEDS_CWD)
set(NEEDS_CWD false)
set(PACKAGE_CWD "")
endif(PACKAGE_NEEDS_CWD)

message(STATUS "DATA_SRC_DIR: ${DATA_SRC_DIR}")
message(STATUS "DATA_PRE_DIR: ${DATA_PRE_DIR}")
Expand Down
11 changes: 9 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ tebako press \
[-R|--Ruby=<ruby-version>] \
[-o|--output=<packaged-file-name>] \
[-l|--log-level=<error|warn|debug|trace>] \
[-c|--cwd=<package current working directory>]
[-D|--devmode] \
[-t|--tebafile=<path-to-tebafile>]
----
Expand All @@ -633,10 +634,10 @@ the Tebako root folder (see details in the Tebako Root Folder Selection section)
this parameter defines Ruby version that will be packaged (optional, defaults to
`3.1.6`)

`<project-root>`::
`project-root`::
a folder at the host source file system where project files are located

`<entry-point>`::
`entry-point`::
an executable file (binary executable or script) that shall be started when
packaged file is called

Expand All @@ -647,6 +648,12 @@ the output file name (optional, defaults to `<current folder>/<entry point base
logging level for the Tebako built-in memory filesystem driver
(optional, defaults to `error`)

`cwd`::
a folder within Tebako memfs where the packaged application will start. This folder should be specified relative to the memfs root.
If not provided, the application will start within the current folder of the host (i.e., at $PWD).
This option is required because it is not possible to change the directory to a memfs folder until the package is started, as opposed to any host folder
that can be set as the current directory before Tebako package invocation.

`tebafile`::
the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
Please refer to the separate section below for tebafile description.
Expand Down
4 changes: 3 additions & 1 deletion include/tebako/tebako-fs.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2021, [Ribose Inc](https://www.ribose.com).
* Copyright (c) 2021-2024, [Ribose Inc](https://www.ribose.com).
* All rights reserved.
* This file is a part of tebako
*
Expand Down Expand Up @@ -37,4 +37,6 @@ namespace tebako {
extern const char* fs_log_level;
extern const char* fs_mount_point;
extern const char* fs_entry_point;
extern bool needs_cwd;
extern const char* package_cwd;
}
7 changes: 7 additions & 0 deletions lib/tebako/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ def hash
print Digest::SHA256.hexdigest [File.read(File.join(source, "CMakeLists.txt")), Tebako::VERSION].join
end

CWD_DESCRIPTION = <<~DESC
Current working directory for packaged application. This directory shall be specified relative to root.
#{" " * 62}# If this parameter is not set, the application will start in the current directory of the host file system.
DESC

desc "press", "Press tebako image"
method_option :cwd, type: :string, aliases: "-c", required: false,
desc: CWD_DESCRIPTION
method_option :"entry-point", type: :string, aliases: ["-e", "--entry"], required: true,
desc: "Ruby application entry point"
method_option :"log-level", type: :string, aliases: "-l", required: false, enum: %w[error warn debug trace],
Expand Down
20 changes: 14 additions & 6 deletions lib/tebako/cli_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,20 +195,28 @@ def prefix
end

def press_announce
cwd_announce = options["cwd"].nil? ? "<Host current directory>" : options["cwd"]

Check warning on line 198 in lib/tebako/cli_helpers.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/cli_helpers.rb#L198

Added line #L198 was not covered by tests
@press_announce ||= <<~ANN
Running tebako press at #{prefix}
Ruby version: '#{extend_ruby_version[0]}'
Project root: '#{root}'
Application entry point: '#{options["entry-point"]}'
Package file name: '#{package}'
Loging level: '#{l_level}'
Ruby version: '#{extend_ruby_version[0]}'
Project root: '#{root}'
Application entry point: '#{options["entry-point"]}'
Package file name: '#{package}'
Loging level: '#{l_level}'
Package working directory: '#{cwd_announce}'
ANN
end

def press_options
cwd_option = if options["cwd"].nil?
"-DPACKAGE_NEEDS_CWD:BOOL=OFF"

Check warning on line 212 in lib/tebako/cli_helpers.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/cli_helpers.rb#L211-L212

Added lines #L211 - L212 were not covered by tests
else
"-DPACKAGE_NEEDS_CWD:BOOL=ON -DPACKAGE_CWD:STRING='#{options["cwd"]}'"

Check warning on line 214 in lib/tebako/cli_helpers.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/cli_helpers.rb#L214

Added line #L214 was not covered by tests
end
@press_options ||=
"-DROOT:STRING='#{root}' -DENTRANCE:STRING='#{options["entry-point"]}' " \
"-DPCKG:STRING='#{package}' -DLOG_LEVEL:STRING='#{options["log-level"]}' "
"-DPCKG:STRING='#{package}' -DLOG_LEVEL:STRING='#{options["log-level"]}' " \
"#{cwd_option}"
end

def relative?(path)
Expand Down
4 changes: 3 additions & 1 deletion resources/tebako-fs.cpp.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2021-2023 [Ribose Inc](https://www.ribose.com).
* Copyright (c) 2021-2024 [Ribose Inc](https://www.ribose.com).
* All rights reserved.
* This file is a part of tebako
*
Expand Down Expand Up @@ -33,5 +33,7 @@ namespace tebako {
const char * fs_log_level = "@LOG_LEVEL@";
const char * fs_mount_point = "@FS_MOUNT_POINT@";
const char * fs_entry_point = "@FS_ENTRY_POINT@";
bool needs_cwd = @NEEDS_CWD@;
const char * package_cwd = "@PACKAGE_CWD@";
INCBIN(fs, "@DATA_BIN_FILE@");
}
9 changes: 7 additions & 2 deletions src/tebako-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ extern "C" int tebako_main(int* argc, char*** argv) {

}

if (tebako::needs_cwd) {
if (tebako_chdir(tebako::package_cwd) != 0) {
printf("Failed to chdir to '%s' : %s\n", tebako::package_cwd, strerror(errno));
ret = -1;
}
}

if (ret != 0) {
try {
printf("Tebako initialization failed\n");
Expand All @@ -145,8 +152,6 @@ extern "C" int tebako_main(int* argc, char*** argv) {
// Nested error, no recovery :(
}
}

// tebako_chdir("/__tebako_memfs__/local");
}
return ret;
}
Expand Down
28 changes: 28 additions & 0 deletions tests-2/fixtures/launcher-cwd-error/launcher-cwd-error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

# Copyright (c) 2021-2023, [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

puts "Hello, you should never see this message!"
1 change: 1 addition & 0 deletions tests-2/fixtures/launcher-cwd/folder/file-1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is file-1 txt
35 changes: 35 additions & 0 deletions tests-2/fixtures/launcher-cwd/launcher-cwd.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

# Copyright (c) 2024, [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

Dir.chdir("folder")
current_directory = Dir.pwd
puts "Current working directory: #{current_directory}"

# List all files in the current working directory
files = Dir.entries(current_directory).select { |file| File.file?(file) }
puts "Files in the current directory:"
files.each { |file| puts file }
61 changes: 45 additions & 16 deletions tests-2/tebako-test.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Copyright (c) 2021-2024 [Ribose Inc](https://www.ribose.com).
Expand Down Expand Up @@ -115,10 +114,15 @@ def ruby_ver
ENV.fetch("RUBY_VER", "3.1.6")
end

# Run 'tebako press ...'
def press(tebako, name, package, prefix)
def press_cmd(tebako, name, package, prefix, cwd = nil)
cmd = "ruby #{tebako} press -D -R #{ruby_ver} -o #{package} -e #{name}.rb -r #{name} -p '#{prefix}'"
out, st = Open3.capture2e(cmd)
cmd += " -c #{cwd}" unless cwd.nil?
cmd
end

# Run 'tebako press ...'
def press(tebako, name, package, prefix, cwd = nil)
out, st = Open3.capture2e(press_cmd(tebako, name, package, prefix, cwd))
if st.exitstatus != 0
puts "\"cmd\" failed with status #{st.exitstatus}"
puts out
Expand All @@ -130,10 +134,10 @@ def press(tebako, name, package, prefix)
end

# A kind of standart creates names - tmp dir with fixture - press sequence
def with_fixture_press_and_env(name)
def with_fixture_press_and_env(name, cwd = nil)
package = "#{name}-package"
with_fixture name do
pkg_file = press(Tebako, name, package, Prefix)
pkg_file = press(Tebako, name, package, Prefix, cwd)
pristine_env pkg_file do |tempdirname|
yield "#{tempdirname}/#{pkg_file}"
end
Expand All @@ -157,7 +161,7 @@ def test_311_io_wait
# with_fixture_press_and_env name do |package|
# out, st = Open3.capture2(package)
# assert_equal 0, st.exitstatus
# assert_match(/Hello! excavate gem welcomes you to the magic world of ruby gems./, out)
# assert_match(/Hello! excavate gem welcomes you to the magic world of ruby gems\./, out)
# end
# end

Expand All @@ -167,7 +171,7 @@ def test_219_nokogiri
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! nokogiri gem welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! nokogiri gem welcomes you to the magic world of ruby gems\./, out)
end
end

Expand All @@ -177,7 +181,7 @@ def test_218_ffi_libarchive_binary
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! ffi-libarchive-binary gem welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! ffi-libarchive-binary gem welcomes you to the magic world of ruby gems\./, out)
end
end

Expand All @@ -187,7 +191,7 @@ def test_218_ffi_libarchive_binary
# with_fixture_press_and_env name do |package|
# out, st = Open3.capture2(package)
# assert_equal 0, st.exitstatus
# assert_equal out, "Hello! Psych welcomes you to the magic world of ruby gems.\n"
# assert_equal out, "Hello! Psych welcomes you to the magic world of ruby gems\.\n"
# check_libs(package.to_s)
# end
# end
Expand All @@ -199,7 +203,7 @@ def test_218_ffi_libarchive_binary
# with_fixture_press_and_env name do |package|
# out, st = Open3.capture2(package)
# assert_equal 0, st.exitstatus
# assert_match(/Hello! Byebug welcomes you to the magic world of ruby gems./, out)
# assert_match(/Hello! Byebug welcomes you to the magic world of ruby gems\./, out)
# end
# end

Expand All @@ -209,7 +213,7 @@ def test_215_expressir
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! Expressir gem welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! Expressir gem welcomes you to the magic world of ruby gems\./, out)
end
end

Expand All @@ -219,7 +223,7 @@ def test_214_sassc
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! SassC gem welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! SassC gem welcomes you to the magic world of ruby gems\./, out)
end
end

Expand All @@ -229,7 +233,7 @@ def test_213_libmspack
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! libmspack welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! libmspack welcomes you to the magic world of ruby gems\./, out)
end
end

Expand All @@ -239,7 +243,7 @@ def test_212_seven_zip
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! SevenZipRuby welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! SevenZipRuby welcomes you to the magic world of ruby gems\./, out)
end
end

Expand All @@ -250,7 +254,7 @@ def test_211_bundler
with_fixture_press_and_env name do |package|
out, st = Open3.capture2(package)
assert_equal 0, st.exitstatus
assert_match(/Hello! Bundler welcomes you to the magic world of ruby gems./, out)
assert_match(/Hello! Bundler welcomes you to the magic world of ruby gems\./, out)
end
end

Expand Down Expand Up @@ -286,6 +290,31 @@ def test_121_main
end
end

# Test:
# -- that tebako package does chdir to specified folder on startup (--cwd option)
def test_107_launcher_cwd
name = "launcher-cwd"
print "\n#{name} "
with_fixture_press_and_env name, "local" do |package|
out, st = Open3.capture2(package.to_s)
assert_equal 0, st.exitstatus
assert_match(/file-1\.txt/, out)
end
end

# Test:
# -- that tebako package attempt to chdir to non-existing folder (--cwd option) and fails
# -- short options without whitespaces
def test_106_launcher_cwd_error
name = "launcher-cwd-error"
print "\n#{name} "
with_fixture_press_and_env name, "non-existing" do |package|
out, st = Open3.capture2(package.to_s)
assert_equal 255, st.exitstatus
assert_match(/Failed to chdir to /, out)
end
end

# Test:
# -- that executable can write a file to the current working directory (io.c, file.c patching)
# -- short options without whitespaces
Expand Down

0 comments on commit 067e22b

Please sign in to comment.