Skip to content

Commit 032fa05

Browse files
author
Roberto Sora
authored
Command sketch new do not join sketchbook path to sketch name if only sketchname is provided (#396)
* poc of required mod for behavior alignment * align current tests to new behaviour * align sketch new behaviour in sketch path parameter mangling adding proper testing * add test for subpath * add fix test for subpath * align sketch new behaviour in sketch path parameter mangling adding proper testing * add `.ino` suffix trim * move sketch new test in separate test_new.py file * add working_dir fixture to sandboxing sketch creation tests * add e2e test for .ino strip * apply test_sketch.py to sketch test module name for consistency * update test lib invoke to 1.3.0 in requirements.txt * force pytest temp directory to be created in current dir * create local tmpdir only for windows-2019 VM * add conditional step to test pipeline to overcome win VM behaviour in e2e pytests * skip failing sketch new e2e tests in GA Win VM until we find the issue root cause
1 parent cc5e3d6 commit 032fa05

File tree

7 files changed

+94
-21
lines changed

7 files changed

+94
-21
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ __pycache__
1111
venv
1212
.pytest_cache
1313
/dist
14+
/.pytest-tmp-dir
1415

1516
# gRPC client example folder
1617
/client_example/client_example

Diff for: cli/cli_test.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,6 @@ func TestUploadIntegration(t *testing.T) {
296296
require.NotZero(t, exitCode)
297297
}
298298

299-
func TestSketchCommandsIntegration(t *testing.T) {
300-
exitCode, d := executeWithArgs("sketch", "new", "Test")
301-
require.Zero(t, exitCode)
302-
require.Contains(t, string(d), "Sketch created")
303-
}
304-
305299
func TestCompileCommandsIntegration(t *testing.T) {
306300
// Set staging dir to a temporary dir
307301
tmp := tmpDirOrDie()
@@ -319,11 +313,11 @@ func TestCompileCommandsIntegration(t *testing.T) {
319313
require.Zero(t, exitCode)
320314

321315
// Create a test sketch
322-
exitCode, d := executeWithArgs("sketch", "new", "Test1")
316+
test1 := filepath.Join(currSketchbookDir, "Test1")
317+
exitCode, d := executeWithArgs("sketch", "new", test1)
323318
require.Zero(t, exitCode)
324319

325320
// Build sketch without FQBN
326-
test1 := filepath.Join(currSketchbookDir, "Test1")
327321
exitCode, d = executeWithArgs("compile", test1)
328322
require.NotZero(t, exitCode)
329323
require.Contains(t, string(d), "no FQBN provided")

Diff for: cli/sketch/new.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
package sketch
1919

2020
import (
21+
"io/ioutil"
2122
"os"
23+
"path/filepath"
24+
"strings"
2225

2326
"github.com/arduino/arduino-cli/cli/errorcodes"
2427
"github.com/arduino/arduino-cli/cli/feedback"
25-
"github.com/arduino/arduino-cli/cli/globals"
2628
"github.com/spf13/cobra"
2729
)
2830

@@ -47,17 +49,23 @@ void loop() {
4749
`)
4850

4951
func runNewCommand(cmd *cobra.Command, args []string) {
50-
sketchDir := globals.Config.SketchbookDir.Join(args[0])
51-
if err := sketchDir.MkdirAll(); err != nil {
52+
// Trim to avoid issues if user creates a sketch adding the .ino extesion to the name
53+
trimmedSketchName := strings.TrimSuffix(args[0], ".ino")
54+
sketchDir, err := filepath.Abs(trimmedSketchName)
55+
if err != nil {
56+
feedback.Errorf("Error creating sketch: %v", err)
57+
os.Exit(errorcodes.ErrGeneric)
58+
}
59+
if err := os.MkdirAll(sketchDir, os.FileMode(0755)); err != nil {
5260
feedback.Errorf("Could not create sketch directory: %v", err)
5361
os.Exit(errorcodes.ErrGeneric)
5462
}
55-
56-
sketchFile := sketchDir.Join(args[0] + ".ino")
57-
if err := sketchFile.WriteFile(emptySketch); err != nil {
63+
sketchName := filepath.Base(sketchDir)
64+
sketchFile := filepath.Join(sketchDir, sketchName+".ino")
65+
if err := ioutil.WriteFile(sketchFile, emptySketch, os.FileMode(0644)); err != nil {
5866
feedback.Errorf("Error creating sketch: %v", err)
5967
os.Exit(errorcodes.ErrGeneric)
6068
}
6169

62-
feedback.Print("Sketch created in: " + sketchDir.String())
70+
feedback.Print("Sketch created in: " + sketchDir)
6371
}

Diff for: test/conftest.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import os
1616

1717
import pytest
18-
from invoke import run
18+
from invoke.context import Context
1919

2020

2121
@pytest.fixture(scope="function")
@@ -38,7 +38,17 @@ def downloads_dir(tmpdir_factory):
3838

3939

4040
@pytest.fixture(scope="function")
41-
def run_command(data_dir, downloads_dir):
41+
def working_dir(tmpdir_factory):
42+
"""
43+
A tmp folder to work in
44+
will be created before running each test and deleted
45+
at the end, this way all the tests work in isolation.
46+
"""
47+
return str(tmpdir_factory.mktemp("ArduinoTestWork"))
48+
49+
50+
@pytest.fixture(scope="function")
51+
def run_command(data_dir, downloads_dir, working_dir):
4252
"""
4353
Provide a wrapper around invoke's `run` API so that every test
4454
will work in the same temporary folder.
@@ -55,6 +65,8 @@ def run_command(data_dir, downloads_dir):
5565

5666
def _run(cmd_string):
5767
cli_full_line = "{} {}".format(cli_path, cmd_string)
58-
return run(cli_full_line, echo=False, hide=True, warn=True, env=env)
68+
run_context = Context()
69+
with run_context.cd(working_dir):
70+
return run_context.run(cli_full_line, echo=False, hide=True, warn=True, env=env)
5971

6072
return _run

Diff for: test/requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ astroid==2.2.5
22
atomicwrites==1.3.0
33
attrs==19.1.0
44
importlib-metadata==0.18
5-
invoke==1.2.0
5+
invoke==1.3.0
66
isort==4.3.21
77
lazy-object-proxy==1.4.1
88
mccabe==0.6.1

Diff for: test/test_compile.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_compile_with_simple_sketch(run_command, data_dir):
4747
fqbn = "arduino:avr:uno"
4848

4949
# Create a test sketch
50-
result = run_command("sketch new {}".format(sketch_name))
50+
result = run_command("sketch new {}".format(sketch_path))
5151
assert result.ok
5252
assert "Sketch created in: {}".format(sketch_path) in result.stdout
5353

@@ -83,7 +83,7 @@ def test_compile_and_compile_combo(run_command, data_dir):
8383
# Create a test sketch
8484
sketch_name = "CompileAndUploadIntegrationTest"
8585
sketch_path = os.path.join(data_dir, sketch_name)
86-
result = run_command("sketch new CompileAndUploadIntegrationTest")
86+
result = run_command("sketch new {}".format(sketch_path))
8787
assert result.ok
8888
assert "Sketch created in: {}".format(sketch_path) in result.stdout
8989

Diff for: test/test_sketch.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# This file is part of arduino-cli.
2+
#
3+
# Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
4+
#
5+
# This software is released under the GNU General Public License version 3,
6+
# which covers the main part of arduino-cli.
7+
# The terms of this license can be found at:
8+
# https://www.gnu.org/licenses/gpl-3.0.en.html
9+
#
10+
# You can be released from the requirements of the above licenses by purchasing
11+
# a commercial license. Buying such a license is mandatory if you want to modify or
12+
# otherwise use the software for commercial activities involving the Arduino
13+
# software without disclosing the source code of your own applications. To purchase
14+
# a commercial license, send an email to [email protected].
15+
import os
16+
import platform
17+
18+
import pytest
19+
20+
from test.common import running_on_ci
21+
22+
23+
@pytest.mark.skipif(running_on_ci() and platform.system() == "Windows",
24+
reason="Test disabled on Github Actions Win VM until tmpdir inconsistent behavior bug is fixed")
25+
def test_sketch_new(run_command, working_dir):
26+
# Create a test sketch in current directory
27+
current_path = working_dir
28+
sketch_name = "SketchNewIntegrationTest"
29+
current_sketch_path = os.path.join(current_path, sketch_name)
30+
result = run_command("sketch new {}".format(sketch_name))
31+
assert result.ok
32+
assert "Sketch created in: {}".format(current_sketch_path) in result.stdout
33+
assert os.path.isfile(os.path.join(current_sketch_path, sketch_name + ".ino"))
34+
35+
# Create a test sketch in current directory but using an absolute path
36+
sketch_name = "SketchNewIntegrationTestAbsolute"
37+
current_sketch_path = os.path.join(current_path, sketch_name)
38+
result = run_command("sketch new {}".format(current_sketch_path))
39+
assert result.ok
40+
assert "Sketch created in: {}".format(current_sketch_path) in result.stdout
41+
assert os.path.isfile(os.path.join(current_sketch_path, sketch_name + ".ino"))
42+
43+
# Create a test sketch in current directory subpath but using an absolute path
44+
sketch_name = "SketchNewIntegrationTestSubpath"
45+
sketch_subpath = os.path.join("subpath", sketch_name)
46+
current_sketch_path = os.path.join(current_path, sketch_subpath)
47+
result = run_command("sketch new {}".format(sketch_subpath))
48+
assert result.ok
49+
assert "Sketch created in: {}".format(current_sketch_path) in result.stdout
50+
assert os.path.isfile(os.path.join(current_sketch_path, sketch_name + ".ino"))
51+
52+
# Create a test sketch in current directory using .ino extension
53+
sketch_name = "SketchNewIntegrationTestDotIno"
54+
current_sketch_path = os.path.join(current_path, sketch_name)
55+
result = run_command("sketch new {}".format(sketch_name + ".ino"))
56+
assert result.ok
57+
assert "Sketch created in: {}".format(current_sketch_path) in result.stdout
58+
assert os.path.isfile(os.path.join(current_sketch_path, sketch_name + ".ino"))

0 commit comments

Comments
 (0)