Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Project generation feature #124

Merged
merged 11 commits into from
Apr 13, 2023
Merged
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
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ vals
venv
versioning
viewcode
Website
whitelist
whitespaces
workdir
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"project_name": "MyProject",
"fprime_branch_or_tag": "devel",
"install_venv": ["yes", "no"],
"venv_install_path": "{% if cookiecutter.install_venv == 'yes' %}./venv{% else %}None{% endif %}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""
This script is run as a cookiecutter hook after the project is generated.
"""

import subprocess

DEFAULT_BRANCH = "devel"

# Add F' as a submodule
subprocess.run(["git", "init"])
subprocess.run(
[
"git",
"submodule",
"add",
"-b",
DEFAULT_BRANCH,
"https://github.com/nasa/fprime.git",
]
)

# Checkout requested branch/tag
res = subprocess.run(
["git", "checkout", "{{cookiecutter.fprime_branch_or_tag}}"],
cwd="./fprime",
capture_output=True,
)
if res.returncode != 0:
print(
"[WARNING] Unable to checkout branch/tag: {{cookiecutter.fprime_branch_or_tag}}"
)
print(f"[WARNING] Reverted to default branch: {DEFAULT_BRANCH}")
else:
print(
"[INFO] F' submodule checked out to branch/tag: {{cookiecutter.fprime_branch_or_tag}}"
)

# Install venv if requested
if "{{cookiecutter.install_venv}}" == "yes":

Check warning

Code scanning / CodeQL

Constant in conditional expression or statement

Testing a constant will always give the same result.

Check warning

Code scanning / CodeQL

Comparison of constants

Comparison of constants; use 'True' or 'False' instead.
subprocess.run(["python", "-m", "venv", "{{cookiecutter.venv_install_path}}"])
subprocess.run(
[
"{{cookiecutter.venv_install_path}}/bin/pip",
"install",
"-r",
"fprime/requirements.txt",
]
)

print(
"""
################################################################

Congratulations! You have successfully created a new F' project.

A git repository has been initialized and F' has been added as a
submodule, you can now create your first commit.

Get started with your F' project:

-- Activate the virtual environment --
Linux/MacOS: source venv/bin/activate

-- Generate a new component --
fprime-util new --component

-- Generate a new deployment --
fprime-util new --deployment

################################################################
"""
)

if res.returncode != 0:
print(
"[WARNING] Unable to checkout branch/tag: {{cookiecutter.fprime_branch_or_tag}}"
)
print(f"[WARNING] Reverted to default branch: {DEFAULT_BRANCH}")
else:
print(
"[INFO] F' submodule checked out to branch/tag: {{cookiecutter.fprime_branch_or_tag}}"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
####
#
####
cmake_minimum_required(VERSION 3.13)
project({{cookiecutter.project_name}} C CXX)

###
# F' Core Setup
# This includes all of the F prime core components, and imports the make-system.
###
include("${CMAKE_CURRENT_LIST_DIR}/fprime/cmake/FPrime.cmake")
# NOTE: register custom targets between these two lines
include("${FPRIME_FRAMEWORK_PATH}/cmake/FPrime-Code.cmake")


# This includes project-wide objects
include("${CMAKE_CURRENT_LIST_DIR}/project.cmake")
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# {{cookiecutter.project_name}} F' project

This project was auto-generated by the F' utility tool.

F´ (F Prime) is a component-driven framework that enables rapid development and deployment of spaceflight and other embedded software applications.
**Please Visit the F´ Website:** https://nasa.github.io/fprime/.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# This CMake file is intended to register project-wide objects so they can be
# reused easily between deployments, but also by other projects.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[fprime]
project_root: .
framework_path: ./fprime
34 changes: 33 additions & 1 deletion src/fprime/fbuild/interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from pathlib import Path
import re
from contextlib import contextmanager
import shutil

from cookiecutter.main import cookiecutter
from cookiecutter.exceptions import OutputDirExistsException
Expand Down Expand Up @@ -496,6 +497,37 @@ def new_deployment(parsed_args):
f"{out_directory_error}. Use --overwrite to overwrite (will not delete non-generated files).",
file=sys.stderr,
)
sys.exit(1)
return 1
print(f"New deployment successfully created: {gen_path}")
return 0


def new_project(parsed_args):
"""Creates a new F' project"""

# Check if Git is installed and available - needed for cloning F' as submodule
if not shutil.which("git"):
print(
"[ERROR] Git is not installed or in PATH. Please install Git and try again.",
file=sys.stderr,
)
return 1

source = (
os.path.dirname(__file__)
+ "/../cookiecutter_templates/cookiecutter-fprime-project"
)
try:
gen_path = cookiecutter(
source,
overwrite_if_exists=parsed_args.overwrite,
output_dir=parsed_args.path,
)
except OutputDirExistsException as out_directory_error:
print(
f"{out_directory_error}. Use --overwrite to overwrite (will not delete non-generated files).",
file=sys.stderr,
)
return 1
print(f"[INFO] New project successfully created: {gen_path}")
return 0
8 changes: 8 additions & 0 deletions src/fprime/util/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def skip_build_loading(parsed):
should manually be added here by the developer."""
if parsed.command == "new" and parsed.deployment:
return True
if parsed.command == "new" and parsed.project:
return True
return False


Expand Down Expand Up @@ -131,6 +133,12 @@ def add_special_parsers(
action="store_true",
help="Tells the new command to generate a deployment",
)
new_exclusive.add_argument(
"--project",
default=False,
action="store_true",
help="Tells the new command to generate a deployment",
)

# Code formatting with clang-format
format_parser = subparsers.add_parser(
Expand Down
9 changes: 8 additions & 1 deletion src/fprime/util/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
from typing import List, Dict

from fprime.fbuild.builder import Build, InvalidBuildCacheException
from fprime.fbuild.interaction import new_component, new_port, new_deployment
from fprime.fbuild.interaction import (
new_component,
new_port,
new_deployment,
new_project,
)

from fprime.util.code_formatter import ClangFormatter

Expand Down Expand Up @@ -128,6 +133,8 @@ def run_new(
return new_port(build.deployment, build)
if parsed.deployment:
return new_deployment(parsed)
if parsed.project:
return new_project(parsed)
raise NotImplementedError(
"`fprime-util new` target is missing or not implemented. See usage (--help)."
)
Expand Down
9 changes: 7 additions & 2 deletions src/fprime/util/help_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,14 @@
updated to use FPP models. Please check back later.

Usage:
-- New Project --
Generate a new F' project. This will create a Git repository and add F' as a submodule, optionally creating a new
virtual environment. Defaults to current directory, but --path can be used to point to a different location.
Using --overwrite will overwrite only the files that are generated by the new project.
-- New Deployment --
The new deployment command is expected to be ran at the root of the project and will create a new deployment in
the current directory. Using --overwrite will overwrite only the files that are generated by the new deployment.
Generate a new F' deployment within a F' project. The new deployment command is expected to be ran at the root of
the project and will create a new deployment in the current directory. Using --overwrite will overwrite only the
files that are generated by the new deployment.
-- New Component --
WARNING: prototype code generating XML only. Not recommended for inexperienced users. Please check back later.
-- New Port --
Expand Down