Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions cli/module_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ func reloadModuleActionInner(
"try --local if you are testing on the same machine.",
)
}
if err := validateReloadableArchive(cmd, manifest.Build); err != nil {
if err := validateReloadableArchive(cmd, manifest.Build, manifest.FirstRun); err != nil {
return err
}

Expand Down Expand Up @@ -1475,8 +1475,9 @@ func reloadingDestination(cmd *cli.Command, manifest *ModuleManifest) string {
}

// validateReloadableArchive returns an error if there is a fatal issue (for now just file not found).
// It also logs warnings for likely problems.
func validateReloadableArchive(cmd *cli.Command, build *manifestBuildInfo) error {
// It also logs warnings for likely problems, such as a missing meta.json or a first_run script
// declared in the manifest but absent from the archive.
func validateReloadableArchive(cmd *cli.Command, build *manifestBuildInfo, firstRun string) error {
reader, err := os.Open(build.Path)
if err != nil {
return errors.Wrap(err, "error opening the build.path field in your meta.json")
Expand All @@ -1487,6 +1488,7 @@ func validateReloadableArchive(cmd *cli.Command, build *manifestBuildInfo) error
}
archive := tar.NewReader(decompressed)
metaFound := false
firstRunFound := false
for {
header, err := archive.Next()
if errors.Is(err, io.EOF) {
Expand All @@ -1495,14 +1497,26 @@ func validateReloadableArchive(cmd *cli.Command, build *manifestBuildInfo) error
if err != nil {
return errors.Wrapf(err, "reading tar at %s", build.Path)
}
if header.Name == "meta.json" {
name := filepath.Base(header.Name)
if name == "meta.json" {
metaFound = true
}
if firstRun != "" && name == filepath.Base(firstRun) {
firstRunFound = true
}
if metaFound && (firstRun == "" || firstRunFound) {
break
}
}
if !metaFound {
warningf(cmd.Root().ErrWriter, "archive at %s doesn't contain a meta.json, your module will probably fail to start", build.Path)
}
if firstRun != "" && !firstRunFound {
warningf(cmd.Root().ErrWriter,
"archive at %s doesn't contain the first_run script %q declared in meta.json; "+
"the script will not run on the target machine. Include it in your build artifact",
build.Path, firstRun)
}
return nil
}

Expand Down
8 changes: 7 additions & 1 deletion cli/module_generate/_templates/go/tmpl-Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ update:
test:
go test ./...

FIRST_RUN := $(shell jq -r '.first_run // empty' meta.json 2>/dev/null)
TAR_FILES := meta.json $(MODULE_BINARY)
ifneq ($(FIRST_RUN),)
TAR_FILES += $(FIRST_RUN)
endif

module.tar.gz: meta.json $(MODULE_BINARY)
ifneq ($(VIAM_TARGET_OS), windows)
strip $(MODULE_BINARY)
endif
tar czf $@ meta.json $(MODULE_BINARY)
tar czf $@ $(TAR_FILES)

module: test module.tar.gz

Expand Down
8 changes: 7 additions & 1 deletion cli/module_generate/_templates/python/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ if ! $PYTHON -m pip install pyinstaller -Uqq; then
fi

$PYTHON -m PyInstaller --onefile --hidden-import="googleapiclient" src/main.py
tar -czvf dist/archive.tar.gz meta.json ./dist/main

TAR_FILES="meta.json ./dist/main"
FIRST_RUN=$($PYTHON -c "import json; print(json.load(open('meta.json')).get('first_run', ''))" 2>/dev/null)
if [ -n "$FIRST_RUN" ] && [ -f "$FIRST_RUN" ]; then
TAR_FILES="$TAR_FILES $FIRST_RUN"
fi
tar -czvf dist/archive.tar.gz $TAR_FILES
16 changes: 16 additions & 0 deletions cli/module_generate/cpp-gen/src/viam/generator/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ install(
DESTINATION .
)

file(READ "${{CMAKE_CURRENT_SOURCE_DIR}}/meta.json" _META_JSON)
string(JSON _FIRST_RUN ERROR_VARIABLE _FR_ERR GET "${{_META_JSON}}" "first_run")
if(NOT _FR_ERR AND _FIRST_RUN AND EXISTS "${{CMAKE_CURRENT_SOURCE_DIR}}/${{_FIRST_RUN}}")
install(FILES "${{_FIRST_RUN}}" DESTINATION .)
endif()

install(TARGETS {0})

set(CPACK_PACKAGE_NAME "{0}")
Expand Down Expand Up @@ -415,6 +421,16 @@ class {0}Recipe(ConanFile):
# Sources are located in the same place as this recipe, copy them to the recipe
exports_sources = "CMakeLists.txt", "src/*", "main.cpp", "meta.json"

def export_sources(self):
import json, os
from conan.tools.files import copy
meta_path = os.path.join(self.recipe_folder, "meta.json")
if os.path.exists(meta_path):
with open(meta_path) as f:
first_run = json.load(f).get("first_run", "")
if first_run and os.path.exists(os.path.join(self.recipe_folder, first_run)):
copy(self, first_run, src=self.recipe_folder, dst=self.export_sources_folder)

def layout(self):
cmake_layout(self)

Expand Down
Loading