From 05857155064215848c31ccf809d42af7ec9804fd Mon Sep 17 00:00:00 2001
From: gyulaid <gyulaid@gyulai.cloud>
Date: Thu, 31 Mar 2022 22:45:04 +0200
Subject: [PATCH] Change detection via git

---
 alice-ci/setup.cfg          |  2 +-
 alice-ci/src/alice/cli.py   |  4 ++--
 alice-ci/src/alice/utils.py | 41 +++++++++++++++++++++++++++++++++----
 ci-examples/full.yaml       |  4 ++++
 4 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/alice-ci/setup.cfg b/alice-ci/setup.cfg
index 6e79421..d1e593d 100644
--- a/alice-ci/setup.cfg
+++ b/alice-ci/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = alice-ci
-version = 0.0.5
+version = 0.0.6
 author = Daniel Gyulai
 description = Alice CI framework
 long_description = file: README.md
diff --git a/alice-ci/src/alice/cli.py b/alice-ci/src/alice/cli.py
index 4c0140b..bd958c4 100644
--- a/alice-ci/src/alice/cli.py
+++ b/alice-ci/src/alice/cli.py
@@ -30,8 +30,8 @@ def parse_jobs(args):
         print("Begin pipeline steps...")
         for step in args.steps:
             if step in jobParser.jobs:
-                jobParser.execute_job(step)
-                print(f"[Step] {step}: SUCCESS")
+                status = jobParser.execute_job(step)
+                print(f"[Step] {step}: {status}")
             else:
                 print(f"Step {step} not found in {args.input}")
                 exit(1)
diff --git a/alice-ci/src/alice/utils.py b/alice-ci/src/alice/utils.py
index 7794f4a..914093c 100644
--- a/alice-ci/src/alice/utils.py
+++ b/alice-ci/src/alice/utils.py
@@ -1,3 +1,5 @@
+import os
+import subprocess
 import yaml
 
 from alice.exceptions import ConfigException
@@ -44,10 +46,41 @@ class ConfigParser:
                 print(f"[Alice] Parsed jobs: {', '.join(jobs.keys())}")
             return jobs
         else:
-            raise ConfigException("[Alice] No jobs defined in config")
+            raise ConfigException("No jobs defined in config")
+
+    def __is_changed(self, changes):
+        try:                
+            target = changes["branch"]
+            paths = []
+            for path in changes["paths"]:
+                paths.append(os.path.abspath(path))
+            print(paths)
+            # TODO: Error handling
+            command = ["git", "diff", "--name-only", target]
+            with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p:
+                p.wait()
+                for line in p.stdout:
+                    change_path = os.path.abspath(line.decode("UTF-8").strip())
+                    for path in paths:
+                        spec_path = os.path.abspath(path)
+                        if change_path.startswith(spec_path):
+                            print(f"Modified file: {change_path}")
+                            print(f"Path match: {path}")
+                            return True
+        except KeyError:
+            raise ConfigException(f"Invalid 'changes' config: {changes}")
+        return False
 
     def execute_job(self, job_name):
         if job_name in self.jobs:
-            # Pass the job_spec to a runner
-            runner = self.factory.get_runner(self.jobs[job_name]["type"])
-            runner.run(self.jobs[job_name])
+            job_spec = self.jobs[job_name]
+            should_run = True
+            if "changes" in job_spec:
+                should_run = self.__is_changed(job_spec["changes"])
+            if should_run:
+                runner = self.factory.get_runner(job_spec["type"])
+                runner.run(job_spec)
+                return "SUCCESS"
+            else:
+                print("SKIP, no change detected")
+
diff --git a/ci-examples/full.yaml b/ci-examples/full.yaml
index f321b0c..3d2dfee 100644
--- a/ci-examples/full.yaml
+++ b/ci-examples/full.yaml
@@ -18,6 +18,10 @@ runners:
 jobs:
   - name: env
     type: python
+    changes:
+      branch: origin/master
+      paths:
+        - "docs"
     env:
       - name: B
         value: E
-- 
GitLab