Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F393783
mod.rs
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
mod.rs
View Options
use
jj_lib
::{
config
::
StackedConfig
,
git
::{
self
,
GitFetch
,
GitFetchError
,
GitFetchPrepareError
,
GitImportError
,
GitRemoteManagementError
,
RemoteCallbacks
,
},
op_heads_store
::
OpHeadsStoreError
,
op_store
::
OpStoreError
,
repo
::{
ReadonlyRepo
,
Repo
,
RepoLoaderError
,
StoreFactories
},
settings
::{
GitSettings
,
UserSettings
},
str_util
::
StringPattern
,
workspace
::{
DefaultWorkspaceLoaderFactory
,
Workspace
,
WorkspaceInitError
,
WorkspaceLoadError
,
WorkspaceLoaderFactory
,
default_working_copy_factories
,
},
};
use
std
::{
collections
::
HashMap
,
path
::{
Path
,
PathBuf
},
sync
::
Arc
,
};
use
thiserror
::
Error
;
pub
mod
transaction
;
#[derive(Error, Debug)]
#[non_exhaustive]
pub
enum
CodeStateError
{
#[error(
"Failed to clone repository at {0}: {1}"
)]
CloneError
(
PathBuf
,
CodeCloneError
),
#[error(
"Repository already exists: {0}"
)]
RepositoryExists
(
PathBuf
),
}
#[derive(Error, Debug)]
#[non_exhaustive]
pub
enum
CodeCloneError
{
#[error(
"Failed to initialize workspace: {0}"
)]
WorkspaceInit
(
#[from]
WorkspaceInitError
),
#[error(
"Failed to add remote: {0}"
)]
RemoteAddError
(
#[from]
GitRemoteManagementError
),
#[error(
"Failed to store operation: {0}"
)]
WorkspaceOperationStoreError
(
#[from]
OpStoreError
),
#[error(
"Failed to store heads: {0}"
)]
WorkspaceOperationHeadsStoreError
(
#[from]
OpHeadsStoreError
),
#[error(
"Failed to load workspace: {0}"
)]
WorkspaceLoadError
(
#[from]
WorkspaceLoadError
),
#[error(
"Failed to load repository: {0}"
)]
RepositoryLoadError
(
#[from]
RepoLoaderError
),
#[error(
"Failed to fetch repository: {0}"
)]
FetchPrepareError
(
#[from]
GitFetchPrepareError
),
#[error(
"Failed to fetch repository: {0}"
)]
FetchError
(
#[from]
GitFetchError
),
#[error(
"Failed to import refs: {0}"
)]
ImportReferencesError
(
#[from]
GitImportError
),
}
pub
struct
CodeState
{
repository_path
:
PathBuf
,
repositories
:
HashMap
<
String
,
PathBuf
>
,
user_settings
:
UserSettings
,
}
impl
CodeState
{
pub
fn
new
(
repository_path
:
PathBuf
)
->
Self
{
Self
{
repository_path
,
repositories
:
HashMap
::
new
(),
user_settings
:
UserSettings
::
from_config
(
StackedConfig
::
with_defaults
())
.
expect
(
"Failed to load user settings"
),
}
}
pub
fn
get_repository_directory
(
&
self
)
->
&
Path
{
&
self
.
repository_path
}
pub
fn
add_repository_from_path
(
&
mut
self
,
path
:
PathBuf
,
)
->
Result
<
(
Workspace
,
Arc
<
ReadonlyRepo
>
),
CodeStateError
>
{
let
name
=
path
.
file_name
()
.
expect
(
"Failed to get file name"
)
.
to_string_lossy
()
.
to_string
();
let
workspace
=
Workspace
::
init_internal_git
(
&
self
.
user_settings
,
&
path
).
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
WorkspaceInit
(
err
))
})
?
;
self
.
repositories
.
insert
(
name
,
path
);
Ok
(
workspace
)
}
/// Adds a repository from a URL.
/// The repository will be cloned to the repository path
pub
fn
add_repository_from_url
(
&
mut
self
,
name
:
&
str
,
url
:
&
str
,
)
->
Result
<
(
Workspace
,
Arc
<
ReadonlyRepo
>
),
CodeStateError
>
{
let
path
=
std
::
path
::
absolute
(
self
.
repository_path
.
join
(
name
)).
unwrap
();
if
path
.
exists
()
{
return
Err
(
CodeStateError
::
RepositoryExists
(
path
));
}
// Create the repository path if it doesn't exist and the path/.jj
// directory if it doesn't exist
std
::
fs
::
create_dir_all
(
&
path
).
expect
(
"Failed to create repository path"
);
let
(
_workspace
,
repository
)
=
Workspace
::
init_internal_git
(
&
self
.
user_settings
,
&
path
)
.
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
WorkspaceInit
(
err
))
})
?
;
let
remote_name
=
"upstream"
;
git
::
add_remote
(
repository
.
store
(),
remote_name
,
url
).
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
RemoteAddError
(
err
))
})
?
;
let
loader
=
DefaultWorkspaceLoaderFactory
.
create
(
&
path
).
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
WorkspaceLoadError
(
err
))
})
?
;
let
workspace
=
loader
.
load
(
&
self
.
user_settings
,
&
StoreFactories
::
default
(),
&
default_working_copy_factories
(),
)
.
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
WorkspaceLoadError
(
err
))
})
?
;
let
op
=
workspace
.
repo_loader
()
.
load_operation
(
repository
.
op_id
())
.
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
WorkspaceOperationStoreError
(
err
),
)
})
?
;
let
repository
=
workspace
.
repo_loader
().
load_at
(
&
op
).
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
RepositoryLoadError
(
err
))
})
?
;
let
mut
transaction
=
repository
.
start_transaction
();
let
mutable_repository
=
transaction
.
repo_mut
();
let
git_settings
=
GitSettings
{
auto_local_bookmark
:
true
,
abandon_unreachable_commits
:
true
,
..
Default
::
default
()
};
let
mut
git_fetch
=
GitFetch
::
new
(
mutable_repository
,
&
git_settings
).
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
FetchPrepareError
(
err
))
})
?
;
git_fetch
.
fetch
(
remote_name
,
&
[
StringPattern
::
everything
()],
RemoteCallbacks
::
default
(),
None
,
)
.
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
FetchError
(
err
))
})
?
;
git_fetch
.
get_default_branch
(
remote_name
,
RemoteCallbacks
::
default
())
.
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
FetchError
(
err
))
})
?
;
git_fetch
.
import_refs
().
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
ImportReferencesError
(
err
))
})
?
;
transaction
.
commit
(
"Initial commit"
).
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
clone
(),
CodeCloneError
::
WorkspaceOperationHeadsStoreError
(
err
),
)
})
?
;
Ok
((
workspace
,
repository
))
}
pub
fn
remove_repository
(
&
mut
self
,
name
:
&
str
)
{
self
.
repositories
.
remove
(
name
);
}
pub
fn
get_repository
(
&
self
,
name
:
&
str
)
->
Result
<
PathBuf
,
CodeStateError
>
{
let
path
=
self
.
repositories
.
get
(
name
);
match
path
{
Some
(
path
)
=>
Ok
(
path
.
clone
()),
None
=>
Err
(
CodeStateError
::
RepositoryExists
(
self
.
repository_path
.
join
(
name
),
)),
}
}
pub
fn
load_repository
(
&
self
,
path
:
&
Path
,
)
->
Result
<
(
Workspace
,
Arc
<
ReadonlyRepo
>
),
CodeStateError
>
{
let
workspace
=
Workspace
::
load
(
&
self
.
user_settings
,
path
,
&
StoreFactories
::
default
(),
&
default_working_copy_factories
(),
)
.
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
to_path_buf
(),
CodeCloneError
::
WorkspaceLoadError
(
err
))
})
?
;
let
repository
=
workspace
.
repo_loader
().
load_at_head
().
map_err
(
|
err
|
{
CodeStateError
::
CloneError
(
path
.
to_path_buf
(),
CodeCloneError
::
RepositoryLoadError
(
err
))
})
?
;
Ok
((
workspace
,
repository
))
}
pub
fn
discover_repositories
(
&
mut
self
)
{
if
!
self
.
repository_path
.
exists
()
{
std
::
fs
::
create_dir_all
(
&
self
.
repository_path
)
.
expect
(
"Failed to create repository path"
);
}
// Look for repositories in the repository path
// and add them to the repositories map
let
paths
=
std
::
fs
::
read_dir
(
&
self
.
repository_path
).
expect
(
"Failed to read repository path"
);
for
entry
in
paths
{
let
entry
=
entry
.
expect
(
"Failed to read entry"
);
let
path
=
entry
.
path
();
if
path
.
is_dir
()
{
let
name
=
path
.
file_name
()
.
expect
(
"Failed to get file name"
)
.
to_string_lossy
()
.
to_string
();
self
.
repositories
.
insert
(
name
,
path
);
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-asm
Expires
Sun, Apr 20, 11:22 PM (1 d, 23 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
48337
Default Alt Text
mod.rs (8 KB)
Attached To
Mode
rJJ jjorge
Attached
Detach File
Event Timeline
Log In to Comment