Skip to content

Commit 348017c

Browse files
committed
v0.1.0
0 parents  commit 348017c

31 files changed

+2627
-0
lines changed

.github/workflows/build.yml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Build
2+
on: [push, pull_request]
3+
jobs:
4+
#
5+
# Build binaries
6+
#
7+
build_linux:
8+
runs-on: ubuntu-18.04
9+
steps:
10+
- uses: actions/checkout@v2
11+
- name: Test
12+
run: make test
13+
- name: Build
14+
run: OUT=cronedit-linux make build
15+
- name: Store binary
16+
uses: actions/upload-artifact@v2
17+
with:
18+
name: cronedit-linux
19+
path: bin/cronedit-linux
20+
build_macos:
21+
runs-on: macos-10.15
22+
steps:
23+
- uses: actions/checkout@v2
24+
- name: Test
25+
run: make test
26+
- name: Build
27+
run: OUT=cronedit-macos make build
28+
- name: Store binary
29+
uses: actions/upload-artifact@v2
30+
with:
31+
name: cronedit-macos
32+
path: bin/cronedit-macos
33+
#
34+
# Prepare a release if current commit is tagged
35+
#
36+
create_release:
37+
runs-on: ubuntu-18.04
38+
if: startsWith(github.ref, 'refs/tags/v')
39+
needs: [build_linux, build_macos]
40+
steps:
41+
# Draft
42+
- name: Create release draft
43+
id: create_release
44+
uses: actions/create-release@v1
45+
env:
46+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47+
with:
48+
tag_name: ${{ github.ref }}
49+
release_name: Release ${{ github.ref }}
50+
draft: true
51+
# cronedit-linux
52+
- name: Download cronedit-linux
53+
uses: actions/download-artifact@v2
54+
with:
55+
name: cronedit-linux
56+
path: .
57+
- name: Upload cronedit-linux
58+
uses: actions/upload-release-asset@v1
59+
env:
60+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61+
with:
62+
upload_url: ${{ steps.create_release.outputs.upload_url }}
63+
asset_path: ./cronedit-linux
64+
asset_name: cronedit-linux
65+
asset_content_type: application/octet-stream
66+
# cronedit-macos
67+
- name: Download cronedit-macos
68+
uses: actions/download-artifact@v2
69+
with:
70+
name: cronedit-macos
71+
path: .
72+
- name: Upload cronedit-macos
73+
uses: actions/upload-release-asset@v1
74+
env:
75+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
with:
77+
upload_url: ${{ steps.create_release.outputs.upload_url }}
78+
asset_path: ./cronedit-macos
79+
asset_name: cronedit-macos
80+
asset_content_type: application/octet-stream

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bin
2+
.filesystem_test.tmp

DEVELOPMENT.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Development
2+
3+
Cronedit is written in C++/C and without external dependencies. Supported platforms are debian and MacOS.
4+
5+
## How to develop locally
6+
7+
Clone the repository:
8+
9+
```bash
10+
git clone [email protected]:codeclown/cronedit.git
11+
cd cronedit/
12+
```
13+
14+
Run tests:
15+
16+
```bash
17+
make test
18+
```
19+
20+
Build binaries (written into `bin/`):
21+
22+
```bash
23+
make build
24+
```
25+
26+
Run the build:
27+
28+
```bash
29+
./bin/cronedit lib/sample.txt
30+
```
31+
32+
## Release process
33+
34+
### CI builds
35+
36+
For each commit and pull request, GitHub Actions is used to automatically build binaries on:
37+
38+
- Ubuntu 18.04
39+
- MacOS 10.15 (Catalina)
40+
41+
The resulting binaries are uploaded as artifacts into the respective GitHub workflow.
42+
43+
See [`.github/workflows/build.yml`](.github/workflows/build.yml).
44+
45+
### Making a release
46+
47+
1. Bump the version in [`lib/version.h`](lib/version.h), e.g. `#define CRONEDIT_VERSION "0.1.1"`
48+
2. Add a git tag, e.g. `git tag v0.1.1`
49+
3. Push with tags `git push --tags`
50+
4. GitHub action detects the new tag and creates a draft release with attached binaries. Review and publish it here:
51+
https://github.com/codeclown/cronedit/releases

LICENSE.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright (c) 2020, Martti Laine
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright
9+
notice, this list of conditions and the following disclaimer in the
10+
documentation and/or other materials provided with the distribution.
11+
* Neither the name of the copyright holders nor the
12+
names of its contributors may be used to endorse or promote products
13+
derived from this software without specific prior written permission.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
DISCLAIMED. IN NO EVENT SHALL A COPYRIGHT HOLDER BE LIABLE FOR ANY
19+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
GXX ?= g++
2+
OUT ?= cronedit
3+
libs = lib/parser.cpp lib/exec.cpp lib/filesystem.cpp lib/state.cpp lib/render.cpp lib/terminal.cpp lib/stringify.cpp lib/args.cpp
4+
5+
build:
6+
mkdir -p bin && $(GXX) $(libs) lib/cronedit.cpp -o bin/$(OUT)
7+
8+
test:
9+
mkdir -p bin && $(GXX) $(libs) lib/args_test.cpp -o bin/args_test && ./bin/args_test
10+
mkdir -p bin && $(GXX) $(libs) lib/filesystem_test.cpp -o bin/filesystem_test && ./bin/filesystem_test
11+
mkdir -p bin && $(GXX) $(libs) lib/parser_test.cpp -o bin/parser_test && ./bin/parser_test
12+
mkdir -p bin && $(GXX) $(libs) lib/state_test.cpp -o bin/state_test && ./bin/state_test
13+
mkdir -p bin && $(GXX) $(libs) lib/stringify_test.cpp -o bin/stringify_test && ./bin/stringify_test
14+
mkdir -p bin && $(GXX) $(libs) lib/render_test.cpp -o bin/render_test && ./bin/render_test

README.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# cronedit
2+
3+
> an interactive command line editor for crontab
4+
5+
## This project is in BETA!
6+
7+
**Note that this is an early version of cronedit. Versions 0.X.X should be considered beta versions and probably not suited for use in critical production environments. Recommended for use only in testing environments.**
8+
9+
If you want to be extra safe, or just play around, copy crontab contents into a file and edit that file with cronedit:
10+
11+
```bash
12+
# copy crontab contents to .txt file
13+
crontab -l > foobar.txt
14+
# edit that file via cronedit
15+
./cronedit foobar.txt
16+
```
17+
18+
## Usage
19+
20+
```shell
21+
$ cronedit --help
22+
cronedit v0.1.0
23+
24+
Usage:
25+
./bin/cronedit
26+
./bin/cronedit <file>
27+
28+
Arguments:
29+
file If given, this file is read and written to
30+
instead of modifying crontab directly via
31+
the 'crontab' command
32+
33+
Options:
34+
-h, --help Show this help message
35+
-v, --version Show cronedit version
36+
37+
Information about backups:
38+
Upon saving changes, previous crontab version is backed up
39+
into folder '$HOME/.cronedit'.
40+
41+
Source:
42+
This program is open source and available at:
43+
https://github.com/codeclown/cronedit
44+
45+
```
46+
47+
## Development
48+
49+
See [DEVELOPMENT.md](DEVELOPMENT.md).
50+
51+
## License
52+
53+
Released under 3-clause BSD License, see [LICENSE.md](LICENSE.md).

lib/args.cpp

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <string>
2+
#include <vector>
3+
#include "args.h"
4+
5+
Args parse_args(int argc, char* argv[]) {
6+
Args args;
7+
args.show_usage = false;
8+
args.show_version = false;
9+
args.filename = "";
10+
11+
std::vector<std::string> filenames;
12+
13+
for (int i = 1; i < argc; i++) {
14+
std::string arg = argv[i];
15+
if (arg == "--help" || arg == "-h") {
16+
args.show_usage = true;
17+
return args;
18+
}
19+
if (arg == "--version" || arg == "-v") {
20+
args.show_version = true;
21+
return args;
22+
}
23+
filenames.push_back(arg);
24+
}
25+
26+
if (filenames.size() > 1) {
27+
args.show_usage = true;
28+
} else if (filenames.size() > 1) {
29+
args.show_usage = true;
30+
} else if (filenames.size() == 1) {
31+
args.filename = filenames[0];
32+
}
33+
34+
return args;
35+
36+
// bool show_usage = false;
37+
// if (argc >= 2) {
38+
// for (int i = 1; i < argc; i++) {
39+
// std::string arg = argv[i];
40+
// if (arg == "--help" || arg == "-h") {
41+
// show_usage = true;
42+
// break;
43+
// }
44+
// }
45+
// }
46+
// if (show_usage) {
47+
// print_usage(argv[0]);
48+
// exit(0);
49+
// } else if (argc > 2) {
50+
// print_usage(argv[0]);
51+
// exit(1);
52+
// }
53+
// std::string file_arg = "";
54+
// if (argc == 2) {
55+
// file_arg = argv[1];
56+
// }
57+
58+
// return args;
59+
}

lib/args.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef ARGS_H
2+
#define ARGS_H
3+
4+
struct Args {
5+
bool show_usage;
6+
bool show_version;
7+
std::string filename;
8+
};
9+
10+
Args parse_args(int argc, char* argv[]);
11+
12+
#endif

lib/args_test.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include <sstream>
2+
#include <iostream>
3+
#include <string>
4+
#include <assert.h>
5+
#include "args.h"
6+
7+
int main()
8+
{
9+
char *argv1[1] = { (char*)"./bin/cronedit" };
10+
Args args1 = parse_args(1, argv1);
11+
assert(args1.show_usage == false);
12+
assert(args1.show_version == false);
13+
assert(args1.filename == "");
14+
15+
char *argv2[2] = { (char*)"./bin/cronedit", (char*)"-h" };
16+
Args args2 = parse_args(2, argv2);
17+
assert(args2.show_usage == true);
18+
assert(args2.show_version == false);
19+
assert(args2.filename == "");
20+
21+
char *argv3[2] = { (char*)"./bin/cronedit", (char*)"--help" };
22+
Args args3 = parse_args(2, argv3);
23+
assert(args3.show_usage == true);
24+
assert(args3.show_version == false);
25+
assert(args3.filename == "");
26+
27+
char *argv4[2] = { (char*)"./bin/cronedit", (char*)"-v" };
28+
Args args4 = parse_args(2, argv4);
29+
assert(args4.show_usage == false);
30+
assert(args4.show_version == true);
31+
assert(args4.filename == "");
32+
33+
char *argv5[2] = { (char*)"./bin/cronedit", (char*)"--version" };
34+
Args args5 = parse_args(2, argv5);
35+
assert(args5.show_usage == false);
36+
assert(args5.show_version == true);
37+
assert(args5.filename == "");
38+
39+
char *argv6[2] = { (char*)"./bin/cronedit", (char*)"foobar" };
40+
Args args6 = parse_args(2, argv6);
41+
assert(args6.show_usage == false);
42+
assert(args6.show_version == false);
43+
assert(args6.filename == "foobar");
44+
45+
char *argv7[3] = { (char*)"./bin/cronedit", (char*)"foobar", (char*)"lorem" };
46+
Args args7 = parse_args(3, argv7);
47+
assert(args7.show_usage == true);
48+
assert(args7.show_version == false);
49+
assert(args7.filename == "");
50+
51+
std::cout << "PASS" << std::endl;
52+
}

0 commit comments

Comments
 (0)