Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Allow zip sketches with embedded libraries
  • Loading branch information
facchinm authored and cmaglie committed Jan 11, 2018
commit b3dd26f46051b7cfb35f0142bda0fe258c87fb61
2 changes: 1 addition & 1 deletion container_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func (s *ContainerSetupHardwareToolsLibsSketchAndProps) Run(ctx *types.Context)
&ToolsLoader{},
&TargetBoardResolver{},
&AddBuildBoardPropertyIfMissing{},
&LibrariesLoader{},
&SketchLoader{},
&LibrariesLoader{},
&SetupBuildProperties{},
&LoadVIDPIDSpecificProperties{},
&SetCustomBuildProperties{},
Expand Down
4 changes: 4 additions & 0 deletions libraries_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ func (s *LibrariesLoader) Run(ctx *types.Context) error {

sortedLibrariesFolders = appendPathToLibrariesFolders(sortedLibrariesFolders, filepath.Join(platform.Folder, constants.FOLDER_LIBRARIES))

if ctx.SketchZipped {
sortedLibrariesFolders = appendPathToLibrariesFolders(sortedLibrariesFolders, filepath.Join(filepath.Dir(ctx.SketchLocation), constants.FOLDER_LIBRARIES))
}

librariesFolders := ctx.OtherLibrariesFolders
librariesFolders, err = utils.AbsolutizePaths(librariesFolders)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions resolve_library.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ func ResolveLibrary(ctx *types.Context, header string) *types.Library {

library = useAlreadyImportedLibraryWithSameNameIfExists(library, importedLibraries)

if ctx.SketchZipped {
// select embedded library, in any case
library = libraryContainedInSketchFolder(libraries, filepath.Dir(ctx.SketchLocation))
}

libraryResolutionResults[header] = types.LibraryResolutionResult{
Library: library,
NotUsedLibraries: filterOutLibraryFrom(libraries, library),
Expand Down Expand Up @@ -119,6 +124,15 @@ func useAlreadyImportedLibraryWithSameNameIfExists(library *types.Library, impor
return library
}

func libraryContainedInSketchFolder(libraries []*types.Library, sketchFolder string) *types.Library {
for _, lib := range libraries {
if strings.Contains(lib.Folder, sketchFolder) {
return lib
}
}
return libraries[0]
}

func filterOutLibraryFrom(libraries []*types.Library, libraryToRemove *types.Library) []*types.Library {
filteredOutLibraries := []*types.Library{}
for _, lib := range libraries {
Expand Down
29 changes: 29 additions & 0 deletions sketch_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
package builder

import (
"bufio"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"sort"
Expand Down Expand Up @@ -63,6 +65,17 @@ func (s *SketchLoader) Run(ctx *types.Context) error {
sketchLocation = filepath.Join(sketchLocation, mainSketchStat.Name()+".ino")
}

if mimeType(sketchLocation) == "application/zip" {
dir, _ := ioutil.TempDir("", "arduino_sketch_zip_temp")
sketchLocation, err = utils.ExtractZip(sketchLocation, dir)
if err != nil {
return nil
}
mainSketchFileName := filepath.Base(sketchLocation) + ".ino"
sketchLocation = filepath.Join(sketchLocation, mainSketchFileName)
ctx.SketchZipped = true
}

ctx.SketchLocation = sketchLocation

allSketchFilePaths, err := collectAllSketchFiles(filepath.Dir(sketchLocation))
Expand All @@ -87,6 +100,22 @@ func (s *SketchLoader) Run(ctx *types.Context) error {
return nil
}

func mimeType(fileName string) string {
fs, err := os.Open(fileName)

if err != nil {
return ""
}

defer fs.Close()

reader := bufio.NewReader(fs)

buf := make([]byte, 512)
reader.Read(buf)
return http.DetectContentType(buf)
}

func collectAllSketchFiles(from string) ([]string, error) {
filePaths := []string{}
// Source files in the root are compiled, non-recursively. This
Expand Down
3 changes: 3 additions & 0 deletions types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ type Context struct {
Verbose bool
DebugPreprocessor bool

// inoz handling
SketchZipped bool

// Contents of a custom build properties file (line by line)
CustomBuildProperties []string

Expand Down
70 changes: 70 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
package utils

import (
"archive/zip"
"crypto/md5"
"encoding/hex"
"io"
"io/ioutil"
"os"
"os/exec"
Expand Down Expand Up @@ -488,3 +490,71 @@ func ParseCppString(line string) (string, string, bool) {
i += width
}
}

func ExtractZip(filePath string, location string) (string, error) {
r, err := zip.OpenReader(filePath)
if err != nil {
return location, err
}

var dirList []string

for _, f := range r.File {
dirList = append(dirList, f.Name)
}

basedir := findBaseDir(dirList)

for _, f := range r.File {
fullname := filepath.Join(location, strings.Replace(f.Name, "", "", -1))
if f.FileInfo().IsDir() {
os.MkdirAll(fullname, f.FileInfo().Mode().Perm())
} else {
os.MkdirAll(filepath.Dir(fullname), 0755)
perms := f.FileInfo().Mode().Perm()
out, err := os.OpenFile(fullname, os.O_CREATE|os.O_RDWR, perms)
if err != nil {
return location, err
}
rc, err := f.Open()
if err != nil {
return location, err
}
_, err = io.CopyN(out, rc, f.FileInfo().Size())
if err != nil {
return location, err
}
rc.Close()
out.Close()

mtime := f.FileInfo().ModTime()
err = os.Chtimes(fullname, mtime, mtime)
if err != nil {
return location, err
}
}
}
return filepath.Join(location, basedir), nil
}

func findBaseDir(dirList []string) string {
baseDir := ""
// https://github.com/backdrop-ops/contrib/issues/55#issuecomment-73814500
dontdiff := []string{"pax_global_header"}
for index := range dirList {
if SliceContains(dontdiff, dirList[index]) {
continue
}
candidateBaseDir := dirList[index]
for i := index; i < len(dirList); i++ {
if !strings.Contains(dirList[i], candidateBaseDir) {
return baseDir
}
}
// avoid setting the candidate if it is the last file
if dirList[len(dirList)-1] != candidateBaseDir {
baseDir = candidateBaseDir
}
}
return baseDir
}