prototype
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
carga
|
||||||
28
cmd/main.go
Normal file
28
cmd/main.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/build"
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/create"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
execute_action()
|
||||||
|
}
|
||||||
|
|
||||||
|
// парсит 1 os.Args и вызывает нужный метод
|
||||||
|
func execute_action() {
|
||||||
|
action := os.Args[1]
|
||||||
|
switch action {
|
||||||
|
case "создай":
|
||||||
|
create.CreateProject()
|
||||||
|
case "собери":
|
||||||
|
build.BuildProject()
|
||||||
|
case "установи":
|
||||||
|
fmt.Println("эмулирую установку модуля")
|
||||||
|
case "добавь_цель":
|
||||||
|
fmt.Println("Добавляю цель")
|
||||||
|
}
|
||||||
|
}
|
||||||
45
internal/build/build_project.go
Normal file
45
internal/build/build_project.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/global"
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/target"
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/target/darwin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildProject() {
|
||||||
|
project_config := parseProjectFile()
|
||||||
|
bt := getBuildTarget(project_config)
|
||||||
|
bt.CreateBuildProject(project_config)
|
||||||
|
log.Println("СТАРАЯ КАРГА ЗАВЕРШИЛА СБОРКУ УСПЕШНО!")
|
||||||
|
|
||||||
|
}
|
||||||
|
func parseProjectFile() global.ProjectFile {
|
||||||
|
working_dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("карга не смогла получить текущую рабочую директорию")
|
||||||
|
}
|
||||||
|
file, err := os.ReadFile(path.Join(working_dir, "карга.json"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("карга не смогла прочитать карга.json")
|
||||||
|
}
|
||||||
|
var pf global.ProjectFile
|
||||||
|
json.Unmarshal(file, &pf)
|
||||||
|
return pf
|
||||||
|
}
|
||||||
|
func getBuildTarget(bc global.ProjectFile) target.BaseTarget {
|
||||||
|
switch bc.Target {
|
||||||
|
case "darwin":
|
||||||
|
return darwin.DarwinBuildTarget{}
|
||||||
|
case "linux":
|
||||||
|
//пока тут нет linux specific приколов так шо пока пусть будет дарвин, лол
|
||||||
|
return darwin.DarwinBuildTarget{}
|
||||||
|
}
|
||||||
|
log.Fatalf("Неизвестная цель сборки %s", bc.Target)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
51
internal/create/create_project.go
Normal file
51
internal/create/create_project.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package create
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/global"
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateProject() {
|
||||||
|
//выдает абсолютный путь (по крайней мере на маке) типо
|
||||||
|
// /Users/greenhaze/Programming/rela/old_carga
|
||||||
|
current_dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("карга не смогла получить текущую директорию")
|
||||||
|
}
|
||||||
|
|
||||||
|
is_empty, err := utils.IsDirEmpty(current_dir)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("карга не смогла проверить является ли текущая директория пустой")
|
||||||
|
}
|
||||||
|
if !is_empty {
|
||||||
|
log.Fatalln("Текущая директория не пустая. Карга не может создать тут проект")
|
||||||
|
}
|
||||||
|
createProjectFile(current_dir)
|
||||||
|
os.Mkdir(path.Join(current_dir, "исх"), 0755)
|
||||||
|
}
|
||||||
|
func createProjectFile(dir string) {
|
||||||
|
// для примера я добавил базовые таргеты
|
||||||
|
base_file := global.ProjectFile{
|
||||||
|
ProjectName: filepath.Base(dir),
|
||||||
|
Target: runtime.GOOS,
|
||||||
|
Modules: make([]global.IncludeModule, 0),
|
||||||
|
}
|
||||||
|
file_str, err := json.Marshal(&base_file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Карга не смогла собрать базовый файл. Пните пожалуйста разработчика")
|
||||||
|
}
|
||||||
|
carga_project := filepath.Join(dir, "карга.json")
|
||||||
|
|
||||||
|
err = os.WriteFile(carga_project, file_str, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("карга не смогла записать карга.json в директорию")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
11
internal/global/project_file.go
Normal file
11
internal/global/project_file.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
type ProjectFile struct {
|
||||||
|
ProjectName string `json:"project_name"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
Modules []IncludeModule `json:"include_modules"`
|
||||||
|
}
|
||||||
|
type IncludeModule struct {
|
||||||
|
CFile string `json:"c_file"`
|
||||||
|
CHeader string `json:"c_header"`
|
||||||
|
}
|
||||||
7
internal/target/base_target.go
Normal file
7
internal/target/base_target.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package target
|
||||||
|
|
||||||
|
import "git.gulenok.ru/greenhaze/old_carga/internal/global"
|
||||||
|
|
||||||
|
type BaseTarget interface {
|
||||||
|
CreateBuildProject(config global.ProjectFile) bool
|
||||||
|
}
|
||||||
100
internal/target/darwin/darwin_target.go
Normal file
100
internal/target/darwin/darwin_target.go
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
package darwin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/global"
|
||||||
|
"git.gulenok.ru/greenhaze/old_carga/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DarwinBuildTarget struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d DarwinBuildTarget) CreateBuildProject(config global.ProjectFile) bool {
|
||||||
|
//создаем папку в которой будем проводить все наши изуверства
|
||||||
|
// поскольку я не знаю насколько ниндзя/make дружат с кириллицей, пока что пусть называется build
|
||||||
|
value, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("карга не смогла получить рабочую директорию")
|
||||||
|
}
|
||||||
|
os.Mkdir(path.Join(value, "build"), 0755)
|
||||||
|
//копируем тривиль исходники в build
|
||||||
|
utils.CopyDir("./исх", "./build/src")
|
||||||
|
|
||||||
|
os.Chdir("./build")
|
||||||
|
//качаем бинарник компилятора если оного нет и не забываем удалить забытые скрипты
|
||||||
|
if _, err := os.Stat("./трик"); os.IsNotExist(err) {
|
||||||
|
log.Println("АХТУНГ. Поскольку это дев билд а у меня адекватно не завелся компилятор, сейчас оно качает бинарь с релиза каждый раз")
|
||||||
|
|
||||||
|
cmd := exec.Command("wget", "https://gitflic.ru/project/alekseinedoria/trivil-0/release/c09308df-49c1-4297-8e1c-a41030933720/df79d7c6-fd81-420c-bb42-6f3115dbbc2c/download")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
cmd = exec.Command("tar", "-zxf", "download")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
//а вот это в свою очередь уже костыль потому что из релиза забыли убрать билд кеши
|
||||||
|
cmd = exec.Command("rm", "-rf", "./_си")
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//собираем Тривиль код в Си
|
||||||
|
cmd := exec.Command("./трик.exe", "-отл-сборка=истина", "-сборка=ложь", "src")
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Fatalf("сборка триком не удалась %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// внедряем Си
|
||||||
|
log.Println(config.Modules)
|
||||||
|
|
||||||
|
for _, v := range config.Modules {
|
||||||
|
err := utils.CopyFile(fmt.Sprintf("../си/%s", v.CFile), fmt.Sprintf("./_си/%s", v.CFile))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("карга не смогла скопировать Си файл %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//собираем Makefile
|
||||||
|
files, err := getCFilesInCurrentDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
out, err := renderMakefile(Vars{
|
||||||
|
|
||||||
|
FILES: files,
|
||||||
|
RUNTIME: "../runtime",
|
||||||
|
TARGET: "target",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = os.WriteFile("./_си/Makefile", []byte(out), 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Карга не смогла записать Makefile")
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Chdir("./_си")
|
||||||
|
// Собираем
|
||||||
|
cmd = exec.Command("make")
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Fatalf("сборка make не удалась %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* pushd . &&
|
||||||
|
* cd /home/dmitrys/devel/trivil-project/trivil-0/scripts/rel/_си && clang yunikod.c utf8.c stroki.c vyvod.c fnv.c komstroka.c platforma.c fayily.c str_str.c osh_soobshcheniya.c osnova.c klyuchevye_slova.c lekser.c asd.c asd_pokaz.c slovar__moduli.c slovar__sostoyanie.c slovar__opisaniyi.c imena.c slovar__tcel_tcel.c kontrol_.c semantika.c perevod_imen.c str_log.c imena_opisaniyi.c imena_tipov.c si.c ar.c gen.c parser.c slovar__importy.c kompilyator.c trik.c /home/dmitrys/devel/trivil-project/trivil-0/scripts/rel/runtime/rt_api.c /home/dmitrys/devel/trivil-project/trivil-0/scripts/rel/runtime/rt_sysapi.c /home/dmitrys/devel/trivil-project/trivil-0/scripts/rel/runtime/rt_syscrash_linux.c -lm -rdynamic -I/home/dmitrys/devel/trivil-project/trivil-0/scripts/rel/runtime -o ../трик.exe && popd
|
||||||
|
*/
|
||||||
69
internal/target/darwin/template.go
Normal file
69
internal/target/darwin/template.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package darwin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
const makefileTemplate = `# Автогенерируемый Makefile
|
||||||
|
FILES := {{.FILES}}
|
||||||
|
RUNTIME := {{.RUNTIME}}
|
||||||
|
TARGET := {{.TARGET}}
|
||||||
|
|
||||||
|
CC := clang
|
||||||
|
CFLAGS := -I$(RUNTIME) -o3
|
||||||
|
LDFLAGS := -lm -rdynamic
|
||||||
|
|
||||||
|
SRCS := $(FILES) \
|
||||||
|
$(RUNTIME)/rt_api.c \
|
||||||
|
$(RUNTIME)/rt_sysapi.c \
|
||||||
|
$(RUNTIME)/rt_syscrash_linux.c
|
||||||
|
|
||||||
|
OUT := ../$(TARGET).exe
|
||||||
|
|
||||||
|
.PHONY: darwin-build clean
|
||||||
|
|
||||||
|
darwin-build:
|
||||||
|
$(CC) $(SRCS) $(CFLAGS) $(LDFLAGS) -o $(OUT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OUT)
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
type Vars struct {
|
||||||
|
FILES string
|
||||||
|
RUNTIME string
|
||||||
|
TARGET string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCFilesInCurrentDir() (string, error) {
|
||||||
|
files, err := ioutil.ReadDir("./_си")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var cFiles []string
|
||||||
|
for _, f := range files {
|
||||||
|
if !f.IsDir() && filepath.Ext(f.Name()) == ".c" {
|
||||||
|
cFiles = append(cFiles, f.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(cFiles, " "), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderMakefile(vars Vars) (string, error) {
|
||||||
|
tmpl, err := template.New("makefile").Parse(makefileTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := tmpl.Execute(&buf, vars); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
55
internal/utils/fsutils.go
Normal file
55
internal/utils/fsutils.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CopyFile(src, dst string) error {
|
||||||
|
log.Printf("копирую %s в %s", src, dst)
|
||||||
|
sourceFile, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer sourceFile.Close()
|
||||||
|
|
||||||
|
// create destination folder if not exist
|
||||||
|
if err = os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
destinationFile, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer destinationFile.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(destinationFile, sourceFile)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyDir recursively copies a directory tree
|
||||||
|
func CopyDir(src string, dst string) error {
|
||||||
|
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct new path
|
||||||
|
relPath, err := filepath.Rel(src, path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
targetPath := filepath.Join(dst, relPath)
|
||||||
|
|
||||||
|
if info.IsDir() {
|
||||||
|
// create directory
|
||||||
|
return os.MkdirAll(targetPath, info.Mode())
|
||||||
|
} else {
|
||||||
|
// copy file
|
||||||
|
return CopyFile(path, targetPath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
20
internal/utils/is_dir_empty.go
Normal file
20
internal/utils/is_dir_empty.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IsDirEmpty(name string) (bool, error) {
|
||||||
|
f, err := os.Open(name)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.Readdirnames(1) // Or f.Readdir(1)
|
||||||
|
if err == io.EOF {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, err // Either not empty or error, suits both cases
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user