diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 245a0f98..2fbd0b37 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -224,10 +224,11 @@ if "idedata" in COMMAND_LINE_TARGETS: Import("projenv") except: # pylint: disable=bare-except projenv = env - click.echo( - "\n%s\n" - % json.dumps(projenv.DumpIDEData(env)) # pylint: disable=undefined-variable - ) + data = projenv.DumpIDEData(env) + # dump to file for the further reading by project.helpers.load_project_ide_data + with open(projenv.subst(os.path.join("$BUILD_DIR", "idedata.json")), "w") as fp: + json.dump(data, fp) + click.echo("\n%s\n" % json.dumps(data)) # pylint: disable=undefined-variable env.Exit(0) if "sizedata" in COMMAND_LINE_TARGETS: diff --git a/platformio/project/config.py b/platformio/project/config.py index 6c5aa7b1..dd75f701 100644 --- a/platformio/project/config.py +++ b/platformio/project/config.py @@ -384,7 +384,7 @@ class ProjectConfigDirsMixin(object): if result is None: return None - project_dir = os.getcwd() + project_dir = os.path.dirname(self.path) # patterns if "$PROJECT_HASH" in result: diff --git a/platformio/project/helpers.py b/platformio/project/helpers.py index ec8af4a2..7519e34a 100644 --- a/platformio/project/helpers.py +++ b/platformio/project/helpers.py @@ -135,17 +135,29 @@ def compute_project_checksum(config): return checksum.hexdigest() -def load_project_ide_data(project_dir, env_or_envs): +def load_project_ide_data(project_dir, env_or_envs, cache=False): + assert env_or_envs + env_names = env_or_envs + if not isinstance(env_names, list): + env_names = [env_names] + + result = _load_cached_project_ide_data(project_dir, env_names) if cache else {} + missed_env_names = set(env_names) - set(result.keys()) + if missed_env_names: + result.update(_load_project_ide_data(project_dir, missed_env_names)) + + if not isinstance(env_or_envs, list) and env_or_envs in result: + return result[env_or_envs] + return result or None + + +def _load_project_ide_data(project_dir, env_names): # pylint: disable=import-outside-toplevel from platformio.commands.run.command import cli as cmd_run - assert env_or_envs - envs = env_or_envs - if not isinstance(envs, list): - envs = [envs] args = ["--project-dir", project_dir, "--target", "idedata"] - for env in envs: - args.extend(["-e", env]) + for name in env_names: + args.extend(["-e", name]) result = CliRunner().invoke(cmd_run, args) if result.exit_code != 0 and not isinstance( result.exception, exception.ReturnErrorCode @@ -153,14 +165,17 @@ def load_project_ide_data(project_dir, env_or_envs): raise result.exception if '"includes":' not in result.output: raise exception.PlatformioException(result.output) + return _load_cached_project_ide_data(project_dir, env_names) - data = {} - for line in result.output.split("\n"): - line = line.strip() - if line.startswith('{"') and line.endswith("}") and "env_name" in line: - _data = json.loads(line) - if "env_name" in _data: - data[_data["env_name"]] = _data - if not isinstance(env_or_envs, list) and env_or_envs in data: - return data[env_or_envs] - return data or None + +def _load_cached_project_ide_data(project_dir, env_names): + build_dir = ProjectConfig.get_instance( + join(project_dir, "platformio.ini") + ).get_optional_dir("build") + result = {} + for name in env_names: + if not os.path.isfile(os.path.join(build_dir, name, "idedata.json")): + continue + with open(os.path.join(build_dir, name, "idedata.json")) as fp: + result[name] = json.load(fp) + return result