Skip to content

Commit b868549

Browse files
committed
Initial
0 parents  commit b868549

18 files changed

+638
-0
lines changed

.prettierrc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"bracketSpacing": false,
3+
"printWidth": 80,
4+
"semi": false,
5+
"singleQuote": true,
6+
"proseWrap": "always"
7+
}

.travis.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
language: cpp
2+
3+
notifications:
4+
email: false
5+
6+
matrix:
7+
include:
8+
- os: linux
9+
dist: trusty
10+
addons:
11+
apt:
12+
sources:
13+
- ubuntu-toolchain-r-test
14+
- llvm-toolchain-trusty-7
15+
packages:
16+
- g++-8
17+
- clang-7
18+
- os: osx
19+
osx_image: xcode10.2
20+
- os: windows
21+
22+
git:
23+
submodules: false
24+
25+
before_install:
26+
- git submodule update --init
27+
28+
script:
29+
- .cppsm/travis-ci || ./test

LICENSE.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Copyright © 2019 Vesa Karvonen
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7+
the Software, and to permit persons to whom the Software is furnished to do so,
8+
subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# [](#contents) [C++ submodule manager command-line interface](#) [![Build Status](https://travis-ci.org/cppsm/cppsm-cli.svg?branch=master)](https://travis-ci.org/cppsm/cppsm-cli)
2+
3+
Poor man's submodule management, build scripts, and CI integration for simple,
4+
"conventional" C++ libraries, executable tests, and executable programs on top
5+
of
6+
7+
- [CMake](https://cmake.org/),
8+
- [git](https://git-scm.com/), and
9+
- [Travis CI](https://travis-ci.org/).
10+
11+
The idea is to minimize boilerplate by relying on simple conventions over
12+
excessive configuration. See also the
13+
[C++ submodule manager boilerplate](https://github.com/cppsm/cppsm-boilerplate)
14+
project.
15+
16+
## <a id="contents"></a> [](#contents) [Contents](#contents)
17+
18+
- [Synopsis](#synopsis)
19+
- [Project structure](#project-structure)
20+
21+
## <a id="synopsis"></a> [](#contents) [Synopsis](#synopsis)
22+
23+
Create a new project:
24+
25+
```bash
26+
mkdir PROJECT && cd "$_"
27+
git init
28+
cppsm init
29+
```
30+
31+
Try the hello world example (after `init`):
32+
33+
```bash
34+
cppsm hello
35+
cppsm test
36+
.build*/internals/hello
37+
```
38+
39+
Start hacking:
40+
41+
```bash
42+
emacs internals/program/hello.cpp &
43+
cppsm test-watch
44+
```
45+
46+
Clone an existing project:
47+
48+
```bash
49+
git clone URI
50+
git submodule update --init # NOTE: non-recursive
51+
```
52+
53+
Add a required library:
54+
55+
```bash
56+
cppsm add requires URL/NAME.git BRANCH
57+
```
58+
59+
Remove a previously required library:
60+
61+
```bash
62+
cppsm remove requires/NAME/BRANCH
63+
```
64+
65+
Update all required libraries:
66+
67+
```bash
68+
cppsm update-all
69+
```
70+
71+
## <a id="project-structure"></a> [](#contents) [Project structure](#project-structure)
72+
73+
At the root of a project there are three directories as follows:
74+
75+
- The `equipment` directory may contain any number of _project submodules_ that
76+
the project internally depends upon.
77+
- The `internals` directory may contain one or more _target directories_ that
78+
are internal to the project.
79+
- The `provides` directory may contain one or more _target directories_ that are
80+
provided for dependant projects.
81+
- The `requires` directory may contain any number of _project submodules_ that
82+
the provided targets depend upon.
83+
84+
In other words, both `internals` and `provides` may contain one or more target
85+
directories. In case only a single `internal` or `provides` target directory is
86+
needed, there is no need to create a nested directory.
87+
88+
A single _target directory_ may simultaneously contain
89+
90+
- a library in the `include/${name}` and `library` directories,
91+
- an executable test in the `testing` directory, and
92+
- an executable program in the `program` directory.
93+
94+
Try the `cppsm hello` script. It generates a simple example project that has
95+
essentially the following structure:
96+
97+
CMakeLists.txt
98+
equipment/
99+
testing.cpp/
100+
v1/
101+
provides/
102+
CMakeLists.txt
103+
include/
104+
testing_v1/
105+
test_synopsis.hpp
106+
test.hpp
107+
library/
108+
test.cpp
109+
internals/
110+
CMakeLists.txt
111+
testing/
112+
message_test.cpp
113+
program/
114+
hello.cpp
115+
provides/
116+
CMakeLists.txt
117+
include/
118+
message_v1/
119+
hello.hpp
120+
library/
121+
hello.cpp
122+
123+
Note that the include directories are versioned as are CMake target names and
124+
C++ namespace names. This allows multiple major versions of a library to be used
125+
simultaneously.

bin/cppsm

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash -e
2+
3+
# shellcheck source=../commands/.settings
4+
. "${BASH_SOURCE%/*/*}/commands/.settings"
5+
6+
COMMAND="$1"
7+
shift
8+
9+
"$CPPSM/commands/$COMMAND" "$@"

commands/.settings

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash -e
2+
3+
export CPPSM="${BASH_SOURCE%/*/*}"
4+
5+
if [ -n "$TRAVIS_OS_NAME" ]; then
6+
set -x
7+
fi

commands/add

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash -e
2+
3+
# shellcheck source=.settings
4+
. "${BASH_SOURCE%/*}/.settings"
5+
6+
KIND="${1%/}"
7+
URL="$2"
8+
BRANCH="$3"
9+
10+
if [ "$#" -ne 3 ] || \
11+
[ ! -d .git ] || \
12+
{ [ "$KIND" != requires ] && [ "$KIND" != equipment ]; } ; then
13+
CMD="${0##*/}"
14+
cat << EOF
15+
Usage: $CMD [requires|equipment] url branch
16+
17+
Adds a new cppsm compatible submodule and recursively the submodules it requires
18+
to the project.
19+
20+
This command is idempotent and can be run to e.g. add new transitive
21+
dependencies after updating submodules.
22+
EOF
23+
exit 1
24+
fi
25+
26+
NAME="${URL##*/}"
27+
NAME="${NAME%.git}"
28+
29+
DESIRED="$KIND/$NAME/$BRANCH"
30+
31+
if [ -e "$DESIRED" ]; then
32+
EXISTING="$DESIRED"
33+
echo "$EXISTING already exists."
34+
elif [ -e "requires/$NAME/$BRANCH" ]; then
35+
EXISTING="requires/$NAME/$BRANCH"
36+
echo "$EXISTING already exists."
37+
else
38+
if [ -e "equipment/$NAME/$BRANCH" ]; then
39+
echo "Promoting equipment/$NAME/$BRANCH -> $DESIRED"
40+
"$CPPSM/commands/remove" "equipment/$NAME/$BRANCH"
41+
fi
42+
git submodule add -b "$BRANCH" "$URL" "$DESIRED"
43+
EXISTING="$DESIRED"
44+
fi
45+
46+
for SUBMODULE in $(git config \
47+
--file "$EXISTING/.gitmodules" \
48+
--name-only \
49+
--get-regexp '^submodule\.requires/.*\.path$'); do
50+
SUBMODULE_URL=$(git config --file "$EXISTING/.gitmodules" --get "${SUBMODULE%.path}.url")
51+
SUBMODULE_BRANCH=$(git config --file "$EXISTING/.gitmodules" --get "${SUBMODULE%.path}.branch")
52+
"$CPPSM/commands/add" "$KIND" "$SUBMODULE_URL" "$SUBMODULE_BRANCH"
53+
done

commands/build

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash -e
2+
3+
# shellcheck source=setup
4+
. "${BASH_SOURCE%/*}/setup"
5+
6+
sh -c "$BUILD_CMD"

commands/build-watch

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash -e
2+
3+
# shellcheck source=setup
4+
. "${BASH_SOURCE%/*}/setup"
5+
6+
sh -c "$BUILD_CMD" || true
7+
"${WATCH_CMD[@]}" | xargs -n1 -I{} sh -c "$BUILD_CMD"

commands/hello

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/bin/bash -e
2+
3+
# shellcheck source=.settings
4+
. "${BASH_SOURCE%/*}/.settings"
5+
6+
if [ "$#" -ne 0 ] || \
7+
[ ! -f CMakeLists.txt ] || \
8+
[ -e equipment ] || \
9+
[ -e internals ] || \
10+
[ -e provides ] || \
11+
[ -e requires ] ; then
12+
CMD="${0##*/}"
13+
cat << EOF
14+
Usage: $CMD
15+
16+
Creates an example "Hello, world!" program in a freshly initialized project
17+
directory.
18+
EOF
19+
exit 1
20+
fi
21+
22+
mkdir -p provides/include/message_v1
23+
24+
cat << EOF > provides/include/message_v1/hello.hpp
25+
#include <string>
26+
27+
namespace message_v1 {
28+
29+
std::string hello(const std::string &to);
30+
31+
}
32+
EOF
33+
34+
mkdir -p provides/library
35+
36+
cat << EOF > provides/library/hello.cpp
37+
#include "message_v1/hello.hpp"
38+
39+
std::string message_v1::hello(const std::string &to) {
40+
return "Hello, " + to + "!";
41+
}
42+
EOF
43+
44+
cat << EOF > provides/CMakeLists.txt
45+
add_conventional_library(message_v1)
46+
EOF
47+
48+
"$CPPSM/commands/add" equipment https://github.com/per-framework/testing.cpp.git v1
49+
50+
mkdir -p internals/testing
51+
52+
cat << EOF > internals/testing/message_test.cpp
53+
#include "message_v1/hello.hpp"
54+
55+
#include "testing_v1/test.hpp"
56+
57+
using namespace testing_v1;
58+
59+
auto hello_test = test([]() {
60+
verify("Hello, there!" == message_v1::hello("there"));
61+
});
62+
EOF
63+
64+
mkdir -p internals/program
65+
66+
cat << EOF > internals/program/hello.cpp
67+
#include "message_v1/hello.hpp"
68+
69+
#include <iostream>
70+
71+
int main() {
72+
std::cout << message_v1::hello("world") << std::endl;
73+
return 0;
74+
}
75+
EOF
76+
77+
cat << EOF > internals/CMakeLists.txt
78+
add_conventional_executable_test(message_test)
79+
target_link_libraries(message_test PRIVATE message_v1 testing_v1)
80+
81+
add_conventional_executable(hello)
82+
target_link_libraries(hello PRIVATE message_v1)
83+
EOF

commands/init

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash -e
2+
3+
# shellcheck source=.settings
4+
. "${BASH_SOURCE%/*}/.settings"
5+
6+
if [ "$#" -ne 0 ] || [ ! -d .git ] || [ ! -d .git ]; then
7+
CMD="${0##*/}"
8+
cat << EOF
9+
Usage: $CMD
10+
11+
Initializes a new C++ project with cppsm configuration files or updates an
12+
existing project to use the latest configuration files.
13+
14+
Run $CMD in the top-level directory of a fresh git project.
15+
EOF
16+
exit 1
17+
fi
18+
19+
if [ ! -d .cppsm ]; then
20+
git submodule add -b master https://github.com/cppsm/cppsm-boilerplate.git .cppsm
21+
fi
22+
23+
ln -fs .cppsm/.clang-format .clang-format
24+
ln -fs .cppsm/.gitignore .gitignore
25+
ln -fs .cppsm/.prettierrc .prettierrc
26+
27+
cat << EOF > CMakeLists.txt
28+
cmake_minimum_required(VERSION 3.9)
29+
include(.cppsm/c++17-no-rtti-no-exns.cmake)
30+
EOF
31+
32+
cp "$CPPSM/.travis.yml" .travis.yml
33+
34+
git add \
35+
.clang-format \
36+
.gitignore \
37+
.prettierrc \
38+
.travis.yml \
39+
CMakeLists.txt

0 commit comments

Comments
 (0)