Skip to content

Commit 1eb2f04

Browse files
committed
first commit
0 parents  commit 1eb2f04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2420
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.coverprofile

README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<p align="center">
2+
<a href="https://c3pm.io/">
3+
<img alt="c3pm" src="https://dev.c3pm.io/assets/c3pm.png" width="546">
4+
</a>
5+
</p>
6+
7+
<p align="center">
8+
Your toolkit to dive into C++ easily
9+
</p>
10+
11+
---
12+
13+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
14+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
15+
**Table of Contents**
16+
17+
- [What is c3pm?](#what-is-c3pm)
18+
- [Installing c3pm](#installing-c3pm)
19+
- [Usage](#usage)
20+
- [Start your project](#start-your-project)
21+
- [Add a package](#add-a-package)
22+
- [Building your project](#building-your-project)
23+
- [Publishing your project](#publishing-your-project)
24+
- [Releases](#releases)
25+
- [Contributing](#contributing)
26+
- [Support](#support)
27+
- [Ask a question](#ask-a-question)
28+
- [Create a bug report](#create-a-bug-report)
29+
- [Submit a feature request](#submit-a-feature-request)
30+
31+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
32+
33+
## What is c3pm?
34+
35+
**c3pm** stands for C++ package manager.
36+
37+
c3pm abstracts your build system and eases the management of your dependencies.
38+
39+
It manages your CMake and compiles your project with **minimal configuration**.
40+
41+
Feel free to explore the available packages on our [platform](https://c3pm.io).
42+
43+
## Installing c3pm
44+
45+
TBD
46+
47+
## Usage
48+
49+
Once you installed c3pm, you can start using it.
50+
Here are some basic commands you will need.
51+
52+
### Start your project
53+
```shell
54+
$ ctpm init
55+
```
56+
57+
### Add a package
58+
```shell
59+
$ ctpm add <package>
60+
```
61+
62+
63+
### Building your project
64+
```shell
65+
$ ctpm build
66+
```
67+
68+
### Publishing your project
69+
70+
```shell
71+
$ ctpm publish
72+
```
73+
74+
<br />
75+
76+
You can find a more complete list of the available commands [here](https://github.com/gabrielcolson/c3pm/tree/master/specs/cli) !
77+
78+
## Releases
79+
80+
TBD
81+
82+
## Contributing
83+
84+
Contributions are welcomed!
85+
86+
Refer to our [contribution guidelines](https://github.com/gabrielcolson/c3pm/blob/master/CONTRIBUTING.md).
87+
88+
You also may need the documentation of the different stacks:
89+
[api](https://github.com/gabrielcolson/c3pm/blob/master/api/README.md) -
90+
[web](https://github.com/gabrielcolson/c3pm/blob/master/web/README.md) -
91+
[cli](https://github.com/gabrielcolson/c3pm/blob/master/cli/README.md)
92+
93+
## Support
94+
95+
### Ask a question
96+
97+
TBD
98+
99+
### Create a bug report
100+
101+
TBD
102+
103+
### Submit a feature request
104+
105+
TBD

api/api.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"io/ioutil"
9+
"mime/multipart"
10+
"net/http"
11+
"os"
12+
)
13+
14+
type API struct {
15+
Client *http.Client
16+
Token string
17+
}
18+
19+
func (c API) newRequest(method string, path string, body io.Reader) (*http.Request, error) {
20+
var host string
21+
if customEndpoint := os.Getenv("C3PM_API_ENDPOINT"); customEndpoint == "" {
22+
host = "https://c3pm.herokuapp.com/v1"
23+
} else {
24+
host = customEndpoint
25+
}
26+
url := host + path
27+
28+
req, err := http.NewRequest(method, url, body)
29+
if err != nil {
30+
return nil, err
31+
}
32+
if c.Token != "" {
33+
req.Header.Set("Authorization", c.Token)
34+
}
35+
return req, err
36+
}
37+
38+
func (c API) fetch(method string, path string, body io.Reader, data interface{}) error {
39+
req, err := c.newRequest(method, path, body)
40+
if err != nil {
41+
return fmt.Errorf("failed to create request: %w", err)
42+
}
43+
req.Header.Set("Content-Type", "application/json; charset=utf-8")
44+
45+
resp, err := c.Client.Do(req)
46+
if err != nil {
47+
return err
48+
}
49+
defer resp.Body.Close()
50+
51+
success := resp.StatusCode >= 200 && resp.StatusCode < 300
52+
if !success {
53+
return handleHttpError(resp)
54+
}
55+
56+
b, err := ioutil.ReadAll(resp.Body)
57+
if err != nil {
58+
return err
59+
}
60+
61+
err = json.Unmarshal(b, &data)
62+
if err != nil {
63+
return err
64+
}
65+
66+
return nil
67+
}
68+
69+
func (c API) send(method string, path string, buf io.Reader) error {
70+
body := new(bytes.Buffer)
71+
w := multipart.NewWriter(body)
72+
part, err := w.CreateFormFile("file", "package.tar")
73+
if err != nil {
74+
return err
75+
}
76+
contents, err := ioutil.ReadAll(buf)
77+
if err != nil {
78+
return err
79+
}
80+
_, err = part.Write(contents)
81+
if err != nil {
82+
return err
83+
}
84+
w.Close()
85+
req, err := c.newRequest(method, path, body)
86+
if err != nil {
87+
return fmt.Errorf("failed to create request: %w", err)
88+
}
89+
req.Header.Add("Content-Type", w.FormDataContentType())
90+
91+
resp, err := c.Client.Do(req)
92+
if err != nil {
93+
return err
94+
}
95+
defer resp.Body.Close()
96+
97+
success := resp.StatusCode >= 200 && resp.StatusCode < 300
98+
if !success {
99+
return handleHttpError(resp)
100+
}
101+
return nil
102+
}
103+
104+
func handleHttpError(resp *http.Response) error {
105+
body, err := ioutil.ReadAll(resp.Body)
106+
if err != nil {
107+
return err
108+
}
109+
110+
var message string
111+
var parsedBody struct {
112+
Error string `json:"error"`
113+
}
114+
err = json.Unmarshal(body, &parsedBody)
115+
if err != nil {
116+
message = string(body)
117+
} else {
118+
message = parsedBody.Error
119+
}
120+
121+
return fmt.Errorf("Client error: '%s' failed (%d): '%s'", resp.Request.URL, resp.StatusCode, message)
122+
}

api/auth.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"net/http"
7+
)
8+
9+
func (c *API) Login(login, password string) (string, error) {
10+
body, err := json.Marshal(struct {
11+
Login string `json:"login"`
12+
Password string `json:"password"`
13+
}{
14+
Login: login,
15+
Password: password,
16+
})
17+
if err != nil {
18+
return "", err
19+
}
20+
21+
var data = struct {
22+
ApiKey string `json:"apiKey"`
23+
}{}
24+
err = c.fetch(http.MethodPost, "/auth/login", bytes.NewReader(body), &data)
25+
return data.ApiKey, err
26+
}

api/upload.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package api
2+
3+
import (
4+
"archive/tar"
5+
"bytes"
6+
"fmt"
7+
"io/ioutil"
8+
"os"
9+
)
10+
11+
func buildTarFile(files []string) bytes.Buffer {
12+
var buf bytes.Buffer
13+
tw := tar.NewWriter(&buf)
14+
for _, fn := range files {
15+
st, err := os.Lstat(fn)
16+
if err != nil {
17+
fmt.Printf("error handling %s: %s. ignoring...\n", fn, err.Error())
18+
continue
19+
}
20+
if st.Mode()&os.ModeSymlink != 0 {
21+
target, err := os.Readlink(fn)
22+
if err != nil {
23+
fmt.Printf("error handling %s: %s. ignoring...\n", fn, err.Error())
24+
continue
25+
}
26+
hdr := &tar.Header{
27+
Name: fn,
28+
Linkname: target,
29+
Typeflag: tar.TypeSymlink,
30+
}
31+
if err := tw.WriteHeader(hdr); err != nil {
32+
fmt.Printf("error writing %s: %s. ignoringa...", fn, err.Error())
33+
continue
34+
}
35+
} else {
36+
contents, err := ioutil.ReadFile(fn)
37+
if err != nil {
38+
fmt.Printf("error reading %s: %s. ignoringaa...\n", fn, err.Error())
39+
continue
40+
}
41+
hdr := &tar.Header{
42+
Name: fn,
43+
Mode: 0600,
44+
Size: st.Size(),
45+
}
46+
if err := tw.WriteHeader(hdr); err != nil {
47+
fmt.Printf("error writing %s: %s. ignoringaaa...", fn, err.Error())
48+
continue
49+
}
50+
if _, err := tw.Write(contents); err != nil {
51+
fmt.Printf("error writing %s: %s. ignoringaaaa...", fn, err.Error())
52+
continue
53+
}
54+
}
55+
}
56+
tw.Close()
57+
return buf
58+
}
59+
60+
func (c API) Upload(files []string) error {
61+
buf := buildTarFile(files)
62+
return c.send("POST", "/auth/publish", &buf)
63+
}

api/upload_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package api

cmake/cmake.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package cmake
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
)
8+
9+
func executeCmakeCLI(args ...string) error {
10+
cmd := exec.Command("cmake", args...)
11+
cmd.Stdout = os.Stdout
12+
cmd.Stderr = os.Stderr
13+
err := cmd.Start()
14+
if err != nil {
15+
return fmt.Errorf("failed to start cmake: %w", err)
16+
}
17+
if err = cmd.Wait(); err != nil {
18+
return fmt.Errorf("cmake process failed: %w", err)
19+
}
20+
return nil
21+
}
22+
23+
func GenerateBuildFiles(sourceDir string, buildDir string, variables map[string]string) error {
24+
args := []string{
25+
"-S", sourceDir,
26+
"-B", buildDir,
27+
}
28+
for key, value := range variables {
29+
args = append(args, fmt.Sprintf("-D%s=%s", key, value))
30+
}
31+
return executeCmakeCLI(args...)
32+
}
33+
34+
func Build(buildDir string) error {
35+
return executeCmakeCLI("--build", buildDir, "--config", "Release")
36+
}
37+
38+
func Install(buildDir string) error {
39+
return executeCmakeCLI("--install", buildDir)
40+
}

0 commit comments

Comments
 (0)