Skip to content

Commit

Permalink
Change project to hexagonal
Browse files Browse the repository at this point in the history
  • Loading branch information
Theo-Hafsaoui committed Nov 4, 2024
1 parent 4014157 commit 8f60acc
Show file tree
Hide file tree
Showing 18 changed files with 958 additions and 714 deletions.
100 changes: 34 additions & 66 deletions assets/latex/template/template.tex
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
%-------------------------
% Resume in Latex
% Author : Jake Gutierrez
% Based off of: https://github.com/sb2nov/resume
% License : MIT
%------------------------

\documentclass[letterpaper,11pt]{article}

\usepackage{latexsym}
\usepackage[empty]{fullpage}
\usepackage{titlesec}
Expand All @@ -21,34 +16,13 @@
\usepackage{xcolor}
\usepackage[english]{babel}
\usepackage{tabularx}
\definecolor{Nblack}{HTML}{3b4252}
\definecolor{NBLACK}{HTML}{2e3440}
\definecolor{Nwhite}{HTML}{eceff4}
\definecolor{nwhite}{HTML}{e5e9f0}
\definecolor{Nblue}{HTML}{5e81ac}
\definecolor{Nurl}{HTML}{8fbcbb}
\definecolor{nblue}{HTML}{005A92}
\definecolor{nblue}{HTML}{005A92}
\input{glyphtounicode}


%----------FONT OPTIONS----------
% sans-serif
% \usepackage[sfdefault]{FiraSans}
% \usepackage[sfdefault]{roboto}
% \usepackage[sfdefault]{noto-sans}
% \usepackage[default]{sourcesanspro}

% serif
% \usepackage{CormorantGaramond}
% \usepackage{charter}


\pagestyle{fancy}
\fancyhf{} % clear all header and footer fields
\fancyhf{}
\fancyfoot{}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}

% Adjust margins
\addtolength{\oddsidemargin}{-0.5in}
\addtolength{\evensidemargin}{-0.5in}
Expand Down Expand Up @@ -120,43 +94,37 @@

\begin{document}

\begin{center}
\textbf{\Huge \scshape \textcolor{nblue}{Anemon Vincent}} \\ \vspace{1pt}
\small +33 6 26 26 50 07 $|$ \href{mailto:anemon@pm.me}{\underline{anemon@pm.me}} \\
\href{https://linkedin.com/in/anemon/}{\underline{linkedin.com/in/anemon}} $|$
\href{https://github.com/anemon}{\underline{github.com/anemon}}
\end{center}

\begin{center}
\textbf{\Huge \scshape \textcolor{nblue}{Anemon Vincent}} \\ \vspace{1pt}
\small +33 6 26 26 50 07 $|$ \href{mailto:anemon@pm.me}{\underline{anemon@pm.me}} \\
\href{https://linkedin.com/in/anemon/}{\underline{linkedin.com/in/anemon}} $|$
\href{https://github.com/anemon}{\underline{github.com/anemon}}
\end{center}

%-----------EDUCATION-----------
\section{EDUCATION}
\resumeSubHeadingListStart
%EDUCATION_SECTIONS%
\resumeSubHeadingListEnd

%-----------EXPERIENCE-----------
\section{EXPERIENCE}
\resumeSubHeadingListStart
%EXPERIENCE_SECTIONS%
\resumeSubHeadingListEnd

%-----------PROJECTS-----------
\section{Projects}
\resumeSubHeadingListStart
%PROJECTS_SECTIONS%
\resumeSubHeadingListEnd

%-----------PROGRAMMING SKILLS-----------
\section{Technical Skills}
\begin{itemize}[leftmargin=0.15in, label={}]
%SKILL_SECTIONS%
\end{itemize}

%-------------------------------------------

%-----------EDUCATION-----------
\section{EDUCATION}
\resumeSubHeadingListStart
%EDUCATION_SECTIONS%
\resumeSubHeadingListEnd


%-----------EXPERIENCE-----------
\section{EXPERIENCE}
\resumeSubHeadingListStart
%EXPERIENCE_SECTIONS%
\resumeSubHeadingListEnd



%-----------PROJECTS-----------
\section{Projects}
\resumeSubHeadingListStart
%PROJECTS_SECTIONS%
\resumeSubHeadingListEnd



%
%-----------PROGRAMMING SKILLS-----------
\section{Technical Skills}
\begin{itemize}[leftmargin=0.15in, label={}]
%SKILL_SECTIONS%
\end{itemize}

%-------------------------------------------
\end{document}
64 changes: 5 additions & 59 deletions cmd/generate.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package cmd

import (
m_lang "anemon/internal/markup_languages"
"anemon/internal/walker"
"errors"
"anemon/internal/adapters/input"
"os"
"strings"

"github.com/spf13/cobra"
)

Expand All @@ -15,64 +11,14 @@ var generateCmd = &cobra.Command{
Short: "Generate a CV",
Long: `Generate a CV using the Markdown CV directory in the current work directory`,
RunE: func(cmd *cobra.Command, args []string) error{
dir, err := os.Getwd()
if err != nil{
return err
}
CV,err := getSectionMapFrom(dir)
if err != nil {
return err
}
err = createLatexCVFrom(dir,CV)
if err != nil {
return err
}
root, err := os.Getwd()
if err != nil{ return err }
err = input.GenerateCVFromMarkDownToLatex(root)
if err != nil { return err }
return nil
},
}

//Use a CV map created by `getSectionMapFrom` and write for each lang key a latex CV using the given information
func createLatexCVFrom(dir string, CV map[string]map[string]string )(error){
for lang := range CV{
err := m_lang.Init_output(lang+"-CV",dir)
if err != nil{
return err
}
for sec_name := range CV[lang]{
for _,paragraphe := range strings.Split(CV[lang][sec_name], "\n\n"){
if len(paragraphe)<=1 {
continue
}
sec, err := m_lang.Parse(paragraphe)
if err != nil {
return err
}
_,err = m_lang.ApplyToSection(sec,sec_name,dir+"/assets/latex/output/"+lang+"-CV.tex")
if err != nil {
return err
}
}
}
}
return nil
}

//TODO consider struct for this map of map
//Walk throught the CV directory and return a map of lang within each their is a map of section
func getSectionMapFrom(dir string)(map[string]map[string]string,error){
cv_path := dir+"/cv"
_, err := os.Stat(cv_path)
if err != nil{
if os.IsNotExist(err) { return nil, errors.New("No `cv` directory found at:"+cv_path) }
return nil,err
}
result, err := walker.WalkCV(cv_path)
if err != nil{
return nil,err
}
return result,nil
}

func init() {
rootCmd.AddCommand(generateCmd)
}
15 changes: 15 additions & 0 deletions internal/adapters/input/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package input

import (
"anemon/internal/adapters/output"
"anemon/internal/core"
)

//Use the implementation for markdown and latex to generate latex CV from a tree dir of mardown document
func GenerateCVFromMarkDownToLatex(root string)error{
var source core.Source = &MarkdownSource{}
var templateReader core.TemplateReader = &output.LatexReader{}
var templateProccesor core.TemplateProcessor = &output.LatexProccesor{}
service := &core.CVService{}
return service.GenerateTemplates(root,source,templateReader,templateProccesor)
}
154 changes: 154 additions & 0 deletions internal/adapters/input/input_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package input

import (
core "anemon/internal/core"
"os"
"path/filepath"
"reflect"
"testing"
)

var(
work_input = `
# Back-End Intern
## February 2024 -- August 2024
### TechCorp
#### Internship
- Assisted in developing and optimizing a key business process for expanding into new markets, collaborating with various teams to ensure compliance and smooth integration.
- Participated in the migration of core backend logic from a monolithic application to a microservice architecture, improving system performance and scalability.
- Enhanced system monitoring and reliability by implementing tracing mechanisms and performance objectives.
# Back-End Intern
## February 2024 -- August 2024
### TechCorp
#### Internship
- Assisted in developing and optimizing a key business process for expanding into new markets, collaborating with various teams to ensure compliance and smooth integration.
- Participated in the migration of core backend logic from a monolithic application to a microservice architecture, improving system performance and scalability.
- Enhanced system monitoring and reliability by implementing tracing mechanisms and performance objectives.`

skill_input =`
**Langage**
- Langage A, Langage B, Langage C, Langage D, Langage E, Langage F, Langage G/H
**Langage**
- Langage A, Langage B, Langage C, Langage D, Langage E, Langage F, Langage G/H`
invalid_skill_input =`
- Langage A, Langage B, Langage C, Langage D, Langage E, Langage F, Langage G/H
**Langag
- Langage A, Langage B, Langage C, Langage D, Langage E, Langage F, Langage G/H`



skill_paragraphe = core.Paragraphe{H1: "Langage", H2: "Langage A, Langage B, Langage C, Langage D, Langage E, Langage F, Langage G/H"}

work_paragraphe = core.Paragraphe{H1: "Back-End Intern", H2: "February 2024 -- August 2024",
H3: "TechCorp", H4: "Internship",Items: []string{
"Assisted in developing and optimizing a key business process for expanding into new markets, collaborating with various teams to ensure compliance and smooth integration.",
"Participated in the migration of core backend logic from a monolithic application to a microservice architecture, improving system performance and scalability.",
"Enhanced system monitoring and reliability by implementing tracing mechanisms and performance objectives."}}

invalid_input = "ajsdlhsaeld##dafdbhkbhkjsd##"
work_expected_result = []core.Paragraphe{work_paragraphe,work_paragraphe}
skill_expected_result = []core.Paragraphe{skill_paragraphe,skill_paragraphe}

paths = []struct {
relativePath string
content string
}{
{"cv/eng/education.md", work_input},
{"cv/eng/project.md", work_input},
{"cv/eng/work.md", work_input},
{"cv/eng/skill.md", skill_input},
{"cv/fr/education.md", work_input},
{"cv/fr/work.md", work_input},
{"cv/fr/skill.md", skill_input},
}

)

func TestParagraphe(t *testing.T) {

t.Run("Work Paragraphes should return a slice of valid Paragraphe", func (t *testing.T) {
got := getParagrapheFrom(work_input)
want := work_expected_result
if !reflect.DeepEqual(got[0], want[0]){
t.Fatalf("the first Paragraphe should be :\n%s\n got :%s",want,got)
}

if !reflect.DeepEqual(got[1], want[1]){
t.Fatalf("the first Paragraphe should be :\n%s\n got :%s",want,got)
}
})

t.Run("Invalid input should return nothing", func (t *testing.T) {
result := getParagrapheFrom(invalid_input)
if result != nil{
t.Fatalf("Invalid input should return nil got %v",result)
}
})

t.Run("Skill Paragraphe should be return from valid input", func (t *testing.T) {
got := getParagrapheFrom(skill_input)
want := skill_expected_result
if !reflect.DeepEqual(got,want){
t.Fatalf("the first Paragraphe should be :\n%s\n got :%s",want,got)
}
})

t.Run("Invalid skill Paragraphe should return nil", func (t *testing.T) {
got := getParagrapheFrom(invalid_skill_input)
if got != nil{
t.Fatalf("Invalid input should return nil got %v",got)
}
})
}

func TestSections(t *testing.T) {
rootDir := t.TempDir()
for _, p := range paths {
fullPath := filepath.Join(rootDir, p.relativePath)
if err := os.MkdirAll(filepath.Dir(fullPath), os.ModePerm); err != nil {
t.Fatalf("Failed to create directories: %v", err)
}
if err := os.WriteFile(fullPath, []byte(p.content), os.ModePerm); err != nil {
t.Fatalf("Failed to write file: %v", err)
}
}

t.Run("Should return a valid list of cv", func (t *testing.T) {
source := MarkdownSource{}
got,err := source.GetCVsFrom(rootDir)
if err!=nil{
t.Fatalf("Failed to getCV got %s",err)
}

lang_got := got[len(got)-1].Lang
l_want := "fr"
if lang_got != l_want{
t.Fatalf("Should have %s got %s",l_want,lang_got)
}

sec_got := len(got[len(got)-1].Sections)
s_want := 3
if sec_got != s_want{
t.Fatalf("Should have %d got %d",s_want,sec_got)
}

t_sec_got := got[len(got)-1].Sections[len(got[len(got)-1].Sections)-1].Title
t_s_want := "work"
if t_sec_got != t_s_want{
t.Fatalf("Should have %s got %s",t_s_want,t_sec_got)
}

p_t_sec_got := got[len(got)-1].Sections[len(got[len(got)-1].Sections)-1].Paragraphes
p_t_s_want := work_expected_result

if len(p_t_sec_got) != len(p_t_s_want){ t.Fatalf("Should have len %d got %d",len(p_t_s_want),len(p_t_sec_got)) }

if p_t_sec_got[len(p_t_sec_got)-1].H1 != p_t_s_want[len(p_t_s_want)-1].H1{
t.Fatalf("Should have title %s got %s",p_t_s_want[len(p_t_s_want)-1].H1,p_t_sec_got[len(p_t_sec_got)-1].H1)
}

})
}
Loading

0 comments on commit 8f60acc

Please sign in to comment.